% This script contains an example of use for the software refactor

% Create a Tetra queueing network with delay station 1 and 4 nodes

qn=QNfactory.newSPECASQN(10000);

clear scAlt;
clear mgAlt;

scAlt{qn.M} = [];
%scAlt{2} = [0.07704*2    0.07331*2    0.37879*0.5    0.39370*2    0.04129*2];
scAlt{2} = [0.07704*0.5    0.07331*2    0.37879*2    0.39370*2    0.04129*2; ...
				0.07704*2    0.07331*0.5    0.37879*2    0.39370*2    0.04129*2; ...
				0.07704*2    0.07331*2    0.37879*0.5    0.39370*2    0.04129*2; ...
				0.07704*2    0.07331*2    0.37879*2    0.39370*0.5    0.04129*2; ...
				0.07704*2    0.07331*2    0.37879*2    0.39370*2    0.04129*0.5]; 


mgAlt{qn.M,qn.M} = [];
%mgAlt{3,4} = [3.5674    3.1954    7.6904   13.7880    2.2577];


maxDup = [0; 10; 10; 10];
maxJobReassignments = 50;
				
CNS = Constraints([100 100 20 20 1000],0.8,[200 200 40 40 2000]);

availability = 0.95;




disp('EXPERIMENT: loading spot price traces...');
% load historical data for three eu-west machines
meu1 = Survival('price/eu-west-1.windows.m1.small.csv');
meu2 = Survival('price/eu-west-1.windows.m1.large.csv');
meu3 = Survival('price/eu-west-1.windows.m1.xlarge.csv');
meu4 = Survival('price/eu-west-1.windows.m2.xlarge.csv');
meu5 = Survival('price/eu-west-1.windows.m2.2xlarge.csv');
meu6 = Survival('price/eu-west-1.windows.m2.4xlarge.csv');

% set the on-demand-price for three eu-west machines
% use the on-demand price
odp = [inf inf inf inf inf inf];
%      0.0649 0.2588 0.5181 0.0672 0.2674 0.5350

recoverTimeHours = 810/3600;
desiredLifeHours = recoverTimeHours*(availability)/(1-availability);

disp('EXPERIMENT: calculating minimum bid prices...');
bid1 = meu1.calcMaxBidFromAvgLife(desiredLifeHours);
bid2 = meu2.calcMaxBidFromAvgLife(desiredLifeHours);
bid3 = meu3.calcMaxBidFromAvgLife(desiredLifeHours);
bid4 = meu4.calcMaxBidFromAvgLife(desiredLifeHours);
bid5 = meu5.calcMaxBidFromAvgLife(desiredLifeHours);
bid6 = meu6.calcMaxBidFromAvgLife(desiredLifeHours);	

disp('EXPERIMENT: calculating expected average prices...');
[~, price1] = meu1.calcAverageLife(bid1);
[~, price2] = meu2.calcAverageLife(bid2);
[~, price3] = meu3.calcAverageLife(bid3);
[~, price4] = meu4.calcAverageLife(bid4);
[~, price5] = meu5.calcAverageLife(bid5);
[~, price6] = meu6.calcAverageLife(bid6);
ttl = [desiredLifeHours desiredLifeHours desiredLifeHours ...
			desiredLifeHours desiredLifeHours desiredLifeHours];
price = [price1 price2 price3 price4 price5 price6];

% set rates and cpus
rate =  [1 2 2 3.25 3.25 3.25];
%rate = rate*ecuconv;
cpu =   [1 2 4 2    4    8];
%cpu = [1 1 1 1 1 1];
%rate = [1 4 8 6.5  13 26]; % ecu

rec = repmat(recoverTimeHours, 1, 6);

% finally create the resources
RES = Resources(rate, cpu, price, odp, ttl, rec);
					
seed = 1;
 
disp('STARTING OPT0');
%Optimization without software refactoring
[ d0, cost0, avgRT0, cdfRTindex0, cdfRTvalue0, evaluations0, time0 ] = ... 
		findOptimalAllocationFullLimit(qn, [], CNS, RES, maxDup, seed);

	
disp('STARTING OPT1');
% Optimization with software speedup refactoring only
[ d1, cost1, avgRT1, cdfRTindex1, cdfRTvalue1, evaluations1, time1, nrefactorings1 ] = ...
	refactor(qn, scAlt, mgAlt, maxDup, 0, CNS, RES, seed);

disp('STARTING OPT2');
% Optimization with software job reassignment refactoring only
[ d2, cost2, avgRT2, cdfRTindex2, cdfRTvalue2, evaluations2, time2, nrefactorings2 ] = ...
	refactor(qn, [], [], maxDup, maxJobReassignments, CNS, RES, seed);	
	
disp('STARTING OPT3');
% Optimization with full software refactoring
[ d3, cost3, avgRT3, cdfRTindex3, cdfRTvalue3, evaluations3, time3, nrefactorings3 ] = ...
	refactor(qn, scAlt, mgAlt, maxDup, maxJobReassignments, CNS, RES, seed);

d0
cost0
avgRT0
evaluations0
time0
d1
cost1
avgRT1
evaluations1
time1
d2
cost2
avgRT2
evaluations2
time2
d3
cost3
avgRT3
evaluations3
time3
