%>>>processAction
%
%This function processes an action 'actionToDo'changing the net state
%according to this action.
%>>>The inputs are:
%
% 1) actionToDo: It is a struct with the data needed to update the net state.
% We have 6 types of actions:
% -1(Add a new flow):
% struct('Action',1, 'newFlowProperties', flowProperties ,
% 'newFlowRoutingEntry',newFlowRoutingEntry )
% where newFlowProperties is a struct with the properties of the new
% flow and newFlowRoutingEntry is the new row of flowRoutingMatrix
% with the lightpath used.
%
% -2(Reroute an existing flow):
% struct('Action',2, 'flowSerialNumber', flowSerialNumber ,
% 'newFlowRoutingEntry',newFlowRoutingEntry )
% where flowSerialNumber is the serial number of the flow to
% reallocate and newFlowRoutingEntry is the new row of flowRoutingMatrix
% with the lightpath used.
%
% -3(Delete an existing flow):
% struct('Action',3, 'flowSerialNumberToDelete', flowSerialNumber)
% where flowSerialNumberToDelete is the serial number of the flow to
% delete from the net.
%
% -4(Create a new lightpath):
% struct('Action',4,'newLightpathRoutingEntry',newLightpathRoutingEntry,
% 'pairIngressEgress',[ingressNode egressNode],'occupiedTWCsPerNode',
% occupiedTWCsPerNode)
% where newLightpathRoutingEntry is the route of the new lightpath
% with the physical links and wavelengths used, pairIngressEgress is
% the pair source and destiation of the new lightpath,
% occupiedTWCsPerNode is a vector containing the number of converters
% occupied per node.
%
% -5(Reroute an existing lightpath):
% struct('Action',5,'lightpathSerialNumberToReroute',
% lightpathSerialNumberToReroute,'newLightpathRoutingEntry',
% newLightpathRoutingEntry, 'occupiedTWCsPerNode', occupiedTWCsPerNode)
% where lightpathSerialNumberToReroute is the serial number of the
% lightpath to reallocate, newLightpathRoutingEntry is the new route
% of the lightpath, occupiedTWCsPerNode is a vector containing the
% number of converters occupied per node.
%
% -6(Delete an existing lightpath):
% struct('Action',6,'lightpathSerialNumberToDelete',
% lightpathSerialNumberToDelete)
% where lightpathSerialNumberToDelete is the serial number of the
% lightpath to delete from the net.
%
% 2) netState: NetState Structure. More information about netState in
% section "Structure of netState variable" from Help.
%
% 3) phys: Phys Structure. More information about netState in section
% "Structure of phys variable" from Help.
%
%>>>The outputs are:
%
% 1) netState: NetState Structure updated according to the changes done by
% the action.
%
function [netState]=processAction(actionToDo, netState,phys,simTime)
switch actionToDo.Action
case 1 %New Flow
serialNumOfThisFlow = actionToDo.newFlowProperties.flowSerialNumber;
pairIngressEgress=actionToDo.newFlowProperties.pairIngressEgress;
flowAverageRate=actionToDo.newFlowProperties.flowAverageRate;
flowDuration=actionToDo.newFlowProperties.flowDuration;
netState.flowRoutingMatrix(end+1,:) = actionToDo.newFlowRoutingEntry;
netState.flowTable(end+1,:)=[serialNumOfThisFlow pairIngressEgress(1) pairIngressEgress(2) flowAverageRate simTime flowDuration -1];
case 2 %Reroute Flow
serialNumOfThisFlow = actionToDo.flowSerialNumber;
flowID=find(netState.flowTable(:,1) == serialNumOfThisFlow);
netState.flowRoutingMatrix(flowID,:)=actionToDo.newFlowRoutingEntry;
case 3 %Delete Flow
flowID=find(netState.flowTable(:,1)==actionToDo.flowSerialNumberToDelete);
netState.flowRoutingMatrix(flowID,:)=[];
netState.flowTable(flowID,:)=[];
case 4 %New Lightpath
if(isempty(netState.lightpathTable))
seialNumLightpath=1;
else
seialNumLightpath=netState.lightpathTable(end,1)+1;
end
netState.lightpathTable(end+1,:)=[seialNumLightpath actionToDo.pairIngressEgress];
netState.lightpathRoutingMatrix(end+1,:)=actionToDo.newLightpathRoutingEntry;
netState.flowRoutingMatrix=[netState.flowRoutingMatrix zeros(size(netState.flowRoutingMatrix,1),1)];
netState.numberOfOccupiedTxs(actionToDo.pairIngressEgress(1))= netState.numberOfOccupiedTxs(actionToDo.pairIngressEgress(1))+1;
netState.numberOfOccupiedRxs(actionToDo.pairIngressEgress(2))= netState.numberOfOccupiedRxs(actionToDo.pairIngressEgress(2))+1;
netState.numberOfOccupiedTWCs = netState.numberOfOccupiedTWCs + actionToDo.occupiedTWCsPerNode;
case 5 %Reroute Lightpath
lpID=find(netState.lightpathTable(:,1) == actionToDo.lightpathSerialNumberToReroute);
[sequenceOfNodeIDs , sequenceOfFiberIDs , sequenceOfWavelengthIDs] = lightpathPathComputation(lpID , netState, phys.linkTable);
netState.numberOfOccupiedTWCs = updateNumberOfTWCsState (netState , sequenceOfWavelengthIDs , sequenceOfNodeIDs , -1);
netState.lightpathRoutingMatrix(lpID,:) = actionToDo.newLightpathRoutingEntry;
netState.numberOfOccupiedTWCs = netState.numberOfOccupiedTWCs + actionToDo.occupiedTWCsPerNode;
case 6 %Delete Lightpath
lpID=find(netState.lightpathTable(:,1) == actionToDo.lightpathSerialNumberToDelete);
ingressNode=netState.lightpathTable(lpID,2);
egressNode=netState.lightpathTable(lpID,3);
[sequenceOfNodeIDs , sequenceOfFiberIDs , sequenceOfWavelengthIDs] = lightpathPathComputation(lpID , phys, netState);
netState.numberOfOccupiedTWCs = updateNumberOfTWCsState (netState , sequenceOfWavelengthIDs , sequenceOfNodeIDs , -1);
if(isempty(netState.flowRoutingMatrix)==0)
netState.flowRoutingMatrix(:,lpID)=[];
end
netState.lightpathTable(lpID,:)=[];
netState.lightpathRoutingMatrix(lpID,:) = [];
netState.numberOfOccupiedTxs(ingressNode)= netState.numberOfOccupiedTxs(ingressNode)-1;
netState.numberOfOccupiedRxs(egressNode)= netState.numberOfOccupiedRxs(egressNode)-1;
end
%updateNumberOfTWCsState is a function what updates the number of TWCs. If
%the input argument newLp is '1', the TWCs will be occupied. If the input
%argument newLp is '-1', the TWCs will be released.
function [numberOfOccupiedTWCs] = updateNumberOfTWCsState (netState , sequenceOfWavelengths , sequenceOfSPFNodeIDs , newLp)
numberOfOccupiedTWCs = netState.numberOfOccupiedTWCs;
if (length(sequenceOfWavelengths)>1)
for contLink=2:length(sequenceOfWavelengths)
wavelengthThisLink = sequenceOfWavelengths(contLink);
wavelengthPreviousLink = sequenceOfWavelengths(contLink-1);
if (wavelengthThisLink ~= wavelengthPreviousLink)
nodeId = sequenceOfSPFNodeIDs (contLink);
newNumberOfOccupiedTWCs (nodeId) = newNumberOfOccupiedTWCs (nodeId) + newLp;
if newNumberOfOcuppiedTWCs (nodeId) > phys.numberTWCPerNode (nodeId)
disp ('error');
pause;
end
end
end
end