1function nvars = refreshLocalVars(self)
2% NVARS = REFRESHLOCALVARS()
4R = self.getNumberOfClasses;
5nvars = zeros(self.getNumberOfNodes, 2*R+1);
6nodeparam = cell(self.getNumberOfNodes, 1);
7rtnodes = self.sn.rtnodes;
11% nodeToPlace = zeros(1, self.getNumberOfNodes);
12% nodeToTransition = zeros(1, self.getNumberOfNodes);
13% for ind=1:self.getNumberOfNodes
14% node = self.getNodeByIndex(ind);
18% nodeToPlace(ind) = length(isp);
21% nodeToTransition(ind) = length(ist);
26for ind=1:self.getNumberOfNodes
27 node = self.getNodeByIndex(ind);
30 nodeparam{ind} =
struct();
31 nodeparam{ind}.nitems = 0;
32 nodeparam{ind}.accost = node.accessProb;
33 for r=1:self.getNumberOfClasses
34 if length(node.popularity) >= r && isa(node.popularity{r},
'Distribution') && ~node.popularity{r}.isDisabled
35 nodeparam{ind}.nitems = max(nodeparam{ind}.nitems,node.popularity{r}.support(2));
38 % nvars holds the cache state width: cache contents plus, when a retrieval
39 % system
is configured, a per-item occupancy bitmap (one column per item);
40 % otherwise only the cache contents are stored.
41 if node.retrievalSystemCapacity > 0
42 retrievalBitmapWidth = nodeparam{ind}.nitems;
44 retrievalBitmapWidth = 0;
46 nvars(ind,2*R+1) = node.totalCacheCapacity + retrievalBitmapWidth;
47 nodeparam{ind}.itemcap = node.itemLevelCap;
48 nodeparam{ind}.totalCacheCapacity = node.totalCacheCapacity;
49 nodeparam{ind}.retrievalSystemCapacity = node.retrievalSystemCapacity;
50 nodeparam{ind}.pread = cell(1,self.getNumberOfClasses);
51 for r=1:self.getNumberOfClasses
52 if length(node.popularity) < r || ~isa(node.popularity{r},
'Distribution') || node.popularity{r}.isDisabled
53 nodeparam{ind}.pread{r} = NaN;
55 nodeparam{ind}.pread{r} = node.popularity{r}.evalPMF(1:nodeparam{ind}.nitems);
58 nodeparam{ind}.replacestrat = node.replacestrategy;
59 nodeparam{ind}.hitclass = zeros(1,self.getNumberOfClasses);
60 nodeparam{ind}.hitclass(1:length(node.server.hitClass)) = round(node.server.hitClass);
61 nodeparam{ind}.missclass = zeros(1,self.getNumberOfClasses);
62 nodeparam{ind}.missclass(1:length(node.server.missClass)) = round(node.server.missClass);
64 % retrieval-system
class matrix: pad to current class count and -1 outside known entries
65 K = self.getNumberOfClasses;
66 if isprop(node.server, 'retrievalClasses') && ~isempty(node.server.retrievalClasses)
67 rc = -ones(nodeparam{ind}.nitems, K);
68 rc(1:size(node.server.retrievalClasses,1), 1:min(size(node.server.retrievalClasses,2),K)) = ...
69 node.server.retrievalClasses(1:size(node.server.retrievalClasses,1), 1:min(size(node.server.retrievalClasses,2),K));
70 nodeparam{ind}.retrievalClasses = rc;
72 nodeparam{ind}.retrievalClasses = -ones(max(nodeparam{ind}.nitems,1), K);
74 nodeparam{ind}.retrievalClassIndices = node.retrievalClassIndices;
75 nodeparam{ind}.retrievalSystemQueueIndices = containers.Map(
'KeyType',
'int32',
'ValueType',
'any');
76 keysList = keys(node.retrievalSystemQueueIndices);
77 for kk = 1:numel(keysList)
78 nodeparam{ind}.retrievalSystemQueueIndices(keysList{kk}) = node.retrievalSystemQueueIndices(keysList{kk});
81 % Store actual hit/miss/latency from solver results (
if available)
82 if isprop(node.server,
'actualHitProb') && ~isempty(node.server.actualHitProb)
83 nodeparam{ind}.actualhitprob = full(node.server.actualHitProb);
84 nodeparam{ind}.actualmissprob = full(node.server.actualMissProb);
86 if isprop(node.server,
'actualDelayedHitProb') && ~isempty(node.server.actualDelayedHitProb)
87 nodeparam{ind}.actualdelayedhitprob = full(node.server.actualDelayedHitProb);
89 if isprop(node.server,
'actualResidT') && ~isempty(node.server.actualResidT)
90 nodeparam{ind}.actualresidt = full(node.server.actualResidT);
93 nodeparam{ind}.fanOut = node.output.tasksPerLink;
95 nodeparam{ind}.joinStrategy = node.input.joinStrategy;
96 nodeparam{ind}.fanIn = cell(1,self.getNumberOfClasses);
97 for r=1:self.getNumberOfClasses
98 nodeparam{ind}.fanIn{r} = node.input.joinRequired{r};
101 nodeparam{ind}.fileName = node.fileName;
102 nodeparam{ind}.filePath = node.filePath;
103 nodeparam{ind}.startTime = node.getStartTime;
104 nodeparam{ind}.loggerName = node.getLoggerName;
105 nodeparam{ind}.timestamp = node.getTimestamp;
106 nodeparam{ind}.jobID = node.getJobID;
107 nodeparam{ind}.jobClass = node.getJobClass;
108 nodeparam{ind}.timeSameClass = node.getTimeSameClass;
109 nodeparam{ind}.timeAnyClass = node.getTimeAnyClass;
111 for r=1:self.getNumberOfClasses
112 if ~iscell(node.arrivalProcess) || length(node.arrivalProcess) < r || isempty(node.arrivalProcess{r})
115 switch class(node.arrivalProcess{r})
117 nvars(ind,r) = nvars(ind,r) + 1;
118 case {
'Replayer',
'Trace'}
119 if isempty(nodeparam{ind})
120 nodeparam{ind} = cell(1,self.getNumberOfClasses);
122 if isempty(nodeparam{ind}{r})
123 nodeparam{ind}{r} =
struct();
125 nodeparam{ind}{r}.(node.arrivalProcess{r}.params{1}.paramName) = node.arrivalProcess{r}.params{1}.paramValue;
128 case {
'Queue',
'QueueingStation',
'Delay',
'DelayStation',
'Transition'}
129 for r=1:self.getNumberOfClasses
130 switch class(node.server.serviceProcess{r}{3})
132 nvars(ind,r) = nvars(ind,r) + 1;
133 case {
'Replayer',
'Trace'}
134 if isempty(nodeparam{ind})
135 nodeparam{ind} = cell(1,self.getNumberOfClasses);
137 if isempty(nodeparam{ind}{r})
138 nodeparam{ind}{r} =
struct();
140 nodeparam{ind}{r}.(node.server.serviceProcess{r}{3}.params{1}.paramName) = node.server.serviceProcess{r}{3}.params{1}.paramValue;
142 if ~isa(node,
'Delay') && ~isa(node,
'Transition') && ~isempty(node.setupTime) && ~isempty(node.setupTime{r})
143 if isempty(nodeparam{ind})
144 nodeparam{ind} = cell(1,self.getNumberOfClasses);
146 if isempty(nodeparam{ind}{r})
147 nodeparam{ind}{r} =
struct();
149 nodeparam{ind}{r}.setupTime = node.setupTime{r}.getProcess();
150 nodeparam{ind}{r}.delayoffTime = node.delayoffTime{r}.getProcess();
152 if (isa(node,
'Queue') || isa(node,
'QueueingStation'))
153 if isempty(nodeparam{ind}) && (~isempty(node.pollingType) || ~isempty(node.switchoverTime))
154 nodeparam{ind} = cell(1,self.getNumberOfClasses);
155 for s=1:self.getNumberOfClasses
156 nodeparam{ind}{s} =
struct();
159 if ~isempty(node.pollingType) && ~isempty(node.pollingType{r})
160 nodeparam{ind}{r}.pollingType = node.pollingType{r};
161 nodeparam{ind}{r}.pollingPar = node.pollingPar;
163 if ~isempty(node.switchoverTime) && ~isempty(node.switchoverTime{r})
164 if min(size(node.switchoverTime))==1
165 nodeparam{ind}{r}.switchoverTime = node.switchoverTime{r}.getProcess();
166 nodeparam{ind}{r}.switchoverProcId = ProcessType.toId(ProcessType.fromText(
class(node.switchoverTime{r})));
168 for t=1:length(node.switchoverTime)
169 nodeparam{ind}{r}.switchoverTime{t} = node.switchoverTime{r,t}.getProcess();
170 nodeparam{ind}{r}.switchoverProcId(t) = ProcessType.toId(ProcessType.fromText(
class(node.switchoverTime{r,t})));
176 % Pass-and-swap (PAS) queues carry a node-level
class
177 % compatibility/swap graph rather than per-
class parameters.
178 if (isa(node,'Queue') || isa(node,'QueueingStation')) && ...
179 SchedStrategy.toId(node.schedStrategy) == SchedStrategy.PAS
180 if isempty(nodeparam{ind})
181 nodeparam{ind} =
struct();
183 if isempty(node.swapGraph)
184 % Default to a complete compatibility graph (any
class may
185 % swap with any other; no self-loops) when none was set.
186 nodeparam{ind}.swapGraph = ones(R,R) - eye(R);
188 nodeparam{ind}.swapGraph = node.swapGraph;
190 % Total service rate function mu(c) of the ordered state vector c.
191 nodeparam{ind}.svcRateFun = node.svcRateFun;
196 switch sn.routing(ind,r)
197 case RoutingStrategy.KCHOICES
198 nodeparam{ind}{r}.k = node.output.outputStrategy{r}{3}{1};
199 nodeparam{ind}{r}.withMemory = node.output.outputStrategy{r}{3}{2};
200 if nodeparam{ind}{r}.withMemory
201 % Reserve a state slot per
class to record the last
202 % selected destination so sub_kchoices can replicate the
203 %
"Power-of-K with memory" semantics (Mitzenmacher 2002).
204 nvars(ind, R+r) = nvars(ind, R+r) + 1;
206 case RoutingStrategy.WRROBIN
207 nvars(ind,R+r) = nvars(ind,R+r) + 1;
208 % save indexes of outgoing links
209 if isempty(nodeparam) || isempty(nodeparam{ind}) % reinstantiate
if not a cache
210 nodeparam{ind}{r} =
struct();
212 nodeparam{ind}{r}.weights = zeros(1,self.sn.nnodes);
213 nodeparam{ind}{r}.outlinks = find(self.sn.connmatrix(ind,:));
214 for c=1:size(node.output.outputStrategy{1, r}{3},2)
216 weight = node.output.outputStrategy{1, r}{3}{c}{2};
217 nodeparam{ind}{r}.weights(destination.index) = weight;
219 % Build the WRR cycle by replicating each outlink by its weight.
220 % afterEventRouter walks
this list one position per DEP. With
221 % unit weights
this collapses to ordinary RR.
223 for ol = nodeparam{ind}{r}.outlinks
224 w = nodeparam{ind}{r}.weights(ol);
226 cycle = [cycle, repmat(ol, 1, max(1, round(w)))]; %#ok<AGROW>
228 cycle = [cycle, ol]; %#ok<AGROW>
231 nodeparam{ind}{r}.weighted_outlinks = cycle;
232 case RoutingStrategy.RROBIN
233 nvars(ind,R+r) = nvars(ind,R+r) + 1;
234 % save indexes of outgoing links
235 if isempty(nodeparam) || isempty(nodeparam{ind}) % reinstantiate
if not a cache
236 nodeparam{ind}{r} =
struct();
238 nodeparam{ind}{r}.outlinks = find(self.sn.connmatrix(ind,:));
243if ~isempty(self.sn) %&& isprop(self.sn,
'nvars')
244 self.sn.nvars = nvars;
245 self.sn.nodeparam = nodeparam;