2 % JLINE Conversion utilities
for JLINE format models
4 % JLINE provides
static methods to convert between LINE MATLAB models
5 % and JLINE Java/Kotlin models. This
class serves as the primary interface
6 %
for interoperability between the MATLAB and Java implementations of LINE.
8 % @brief JLINE format conversion and Java interoperability utilities
11 % - Convert LINE MATLAB models to JLINE Java models
12 % - Convert JLINE Java models back to LINE MATLAB format
13 % - Access JLINE solvers from MATLAB
14 % - Handle serialization between MATLAB and Java representations
18 % % Convert a LINE model to JLINE format
19 % jnetwork = JLINE.from_model(network);
20 % % Get a JLINE solver
21 % jssa = JLINE.get_solver(jnetwork,
'ssa');
25 jar_loc = which(
'jline.jar');
30 function model = from_line_layered_network(line_layered_network)
31 sn = line_layered_network.getStruct;
34 model = javaObject(
'jline.lang.layered.LayeredNetwork', line_layered_network.getName);
37 P = cell(1,sn.nhosts);
40 sn_mult_h = java.lang.Integer.MAX_VALUE;
42 sn_mult_h = sn.mult(h);
45 case SchedStrategy.REF
46 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.REF);
47 case SchedStrategy.INF
48 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.INF);
49 case SchedStrategy.FCFS
50 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.FCFS);
51 case SchedStrategy.LCFS
52 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LCFS);
53 case SchedStrategy.SIRO
54 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.SIRO);
55 case SchedStrategy.SJF
56 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.SJF);
57 case SchedStrategy.LJF
58 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LJF);
60 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.PS);
61 case SchedStrategy.DPS
62 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.DPS);
63 case SchedStrategy.GPS
64 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.GPS);
65 case SchedStrategy.SEPT
66 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.SEPT);
67 case SchedStrategy.LEPT
68 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LEPT);
69 case {SchedStrategy.HOL, SchedStrategy.FCFSPRIO}
70 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.FCFSPRIO);
71 case SchedStrategy.FORK
72 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.FORK);
73 case SchedStrategy.EXT
74 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.EXT);
75 case SchedStrategy.LCFSPR
76 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LCFSPR);
77 case SchedStrategy.LCFSPI
78 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LCFSPI);
79 case SchedStrategy.LCFSPRIO
80 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LCFSPRIO);
81 case SchedStrategy.LCFSPRPRIO
82 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LCFSPRPRIO);
83 case SchedStrategy.LCFSPIPRIO
84 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.LCFSPIPRIO);
85 case SchedStrategy.PSPRIO % todo
86 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.PSPRIO);
87 case SchedStrategy.DPSPRIO % todo
88 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.DPSPRIO);
89 case SchedStrategy.GPSPRIO % todo
90 P{h} = javaObject(
'jline.lang.layered.Processor', model, sn.names{h}, sn_mult_h, jline.lang.constant.SchedStrategy.GPSPRIO);
93 P{h}.setReplication(sn.repl(h));
98 T = cell(1,sn.ntasks);
101 if isinf(sn.mult(tidx))
102 sn_mult_tidx = java.lang.Integer.MAX_VALUE;
104 sn_mult_tidx = sn.mult(tidx);
106 % Check
if this is a CacheTask
108 % Get replacement strategy from ordinal
109 switch sn.replacestrat(tidx)
110 case ReplacementStrategy.RR
111 jReplacestrat = jline.lang.constant.ReplacementStrategy.RR;
112 case ReplacementStrategy.FIFO
113 jReplacestrat = jline.lang.constant.ReplacementStrategy.FIFO;
114 case ReplacementStrategy.SFIFO
115 jReplacestrat = jline.lang.constant.ReplacementStrategy.SFIFO;
116 case ReplacementStrategy.LRU
117 jReplacestrat = jline.lang.constant.ReplacementStrategy.LRU;
119 jReplacestrat = jline.lang.constant.ReplacementStrategy.FIFO;
121 T{t} = javaObject(
'jline.lang.layered.CacheTask', model, sn.names{tidx}, sn.nitems(tidx), sn.itemcap{tidx}, jReplacestrat, sn_mult_tidx);
122 elseif sn.isfunction(tidx)
123 % FunctionTask (has setupTime/delayOffTime)
124 jSchedStrategy = JLINE.to_jline_sched_strategy(sn.sched(tidx));
125 T{t} = javaObject(
'jline.lang.layered.FunctionTask', model, sn.names{tidx}, sn_mult_tidx, jSchedStrategy);
127 jSchedStrategy = JLINE.to_jline_sched_strategy(sn.sched(tidx));
128 T{t} = javaObject(
'jline.lang.layered.Task', model, sn.names{tidx}, sn_mult_tidx, jSchedStrategy);
130 T{t}.on(
P{sn.parent(tidx)});
132 T{t}.setReplication(sn.repl(tidx));
134 if ~isempty(sn.think{tidx}) && sn.think_type(tidx) ~= ProcessType.DISABLED
135 switch sn.think_type(tidx)
136 case ProcessType.IMMEDIATE
137 T{t}.setThinkTime(jline.lang.processes.Immediate);
139 T{t}.setThinkTime(jline.lang.processes.Exp(1/sn.think_mean(tidx)));
140 case ProcessType.ERLANG
141 T{t}.setThinkTime(jline.lang.processes.Erlang.fitMeanAndSCV(sn.think_mean(tidx), sn.think_scv(tidx)));
142 case ProcessType.HYPEREXP
143 if ~isempty(sn.think_params{tidx}) && length(sn.think_params{tidx}) >= 3
144 T{t}.setThinkTime(jline.lang.processes.HyperExp(sn.think_params{tidx}(1), sn.think_params{tidx}(2), sn.think_params{tidx}(3)));
146 T{t}.setThinkTime(jline.lang.processes.HyperExp.fitMeanAndSCV(sn.think_mean(tidx), sn.think_scv(tidx)));
148 case ProcessType.COXIAN
149 T{t}.setThinkTime(jline.lang.processes.Coxian.fitMeanAndSCV(sn.think_mean(tidx), sn.think_scv(tidx)));
151 T{t}.setThinkTime(jline.lang.processes.APH.fitMeanAndSCV(sn.think_mean(tidx), sn.think_scv(tidx)));
153 if ~isempty(sn.think_proc{tidx})
154 proc = sn.think_proc{tidx};
155 T{t}.setThinkTime(jline.lang.processes.PH(JLINE.from_line_matrix(proc{1}), JLINE.from_line_matrix(proc{2})));
157 T{t}.setThinkTime(jline.lang.processes.Exp(1/sn.think_mean(tidx)));
160 if ~isempty(sn.think_proc{tidx})
161 proc = sn.think_proc{tidx};
162 T{t}.setThinkTime(jline.lang.processes.MAP(JLINE.from_line_matrix(proc{1}), JLINE.from_line_matrix(proc{2})));
164 T{t}.setThinkTime(jline.lang.processes.Exp(1/sn.think_mean(tidx)));
167 line_error(mfilename,sprintf(
'JLINE conversion does not support the %s distribution for task think time yet.',
char(sn.think_type(tidx))));
171 if sn.isfunction(tidx) && ~isnan(sn.setuptime_mean(tidx)) && sn.setuptime_mean(tidx) > 1e-8
172 T{t}.setSetupTime(sn.setuptime_mean(tidx));
175 if sn.isfunction(tidx) && ~isnan(sn.delayofftime_mean(tidx)) && sn.delayofftime_mean(tidx) > 1e-8
176 T{t}.setDelayOffTime(sn.delayofftime_mean(tidx));
180 E = cell(1,sn.nentries);
183 % Check
if this is an ItemEntry (has nitems > 0)
184 if sn.nitems(eidx) > 0
185 % ItemEntry requires cardinality and popularity distribution
186 if ~isempty(sn.itemproc) && ~isempty(sn.itemproc{eidx})
187 jPopularity = JLINE.from_line_distribution(sn.itemproc{eidx});
189 % Default to uniform distribution
190 jPopularity = javaObject(
'jline.lang.processes.DiscreteSampler', jline.util.matrix.Matrix.uniformDistribution(sn.nitems(eidx)));
192 E{e} = javaObject(
'jline.lang.layered.ItemEntry', model, sn.names{eidx}, sn.nitems(eidx), jPopularity);
194 E{e} = javaObject(
'jline.lang.layered.Entry', model, sn.names{eidx});
196 E{e}.on(T{sn.parent(eidx)-sn.tshift});
200 A = cell(1,sn.nacts);
203 tidx = sn.parent(aidx);
204 onTask = tidx-sn.tshift;
205 % Convert host demand from primitives to Java distribution
206 switch sn.hostdem_type(aidx)
207 case ProcessType.IMMEDIATE
208 jHostDem = jline.lang.processes.Immediate;
209 case ProcessType.DISABLED
210 jHostDem = jline.lang.processes.Disabled;
212 jHostDem = javaObject(
'jline.lang.processes.Exp', 1/sn.hostdem_mean(aidx));
213 case ProcessType.ERLANG
214 jHostDem = jline.lang.processes.Erlang.fitMeanAndSCV(sn.hostdem_mean(aidx), sn.hostdem_scv(aidx));
215 case ProcessType.HYPEREXP
216 if ~isempty(sn.hostdem_params{aidx}) && length(sn.hostdem_params{aidx}) >= 3
217 jHostDem = javaObject(
'jline.lang.processes.HyperExp', sn.hostdem_params{aidx}(1), sn.hostdem_params{aidx}(2), sn.hostdem_params{aidx}(3));
219 jHostDem = jline.lang.processes.HyperExp.fitMeanAndSCV(sn.hostdem_mean(aidx), sn.hostdem_scv(aidx));
221 case ProcessType.COXIAN
222 jHostDem = jline.lang.processes.Coxian.fitMeanAndSCV(sn.hostdem_mean(aidx), sn.hostdem_scv(aidx));
224 jHostDem = jline.lang.processes.APH.fitMeanAndSCV(sn.hostdem_mean(aidx), sn.hostdem_scv(aidx));
226 if ~isempty(sn.hostdem_proc{aidx})
227 proc = sn.hostdem_proc{aidx};
228 jHostDem = javaObject(
'jline.lang.processes.PH', JLINE.from_line_matrix(proc{1}), JLINE.from_line_matrix(proc{2}));
230 jHostDem = javaObject(
'jline.lang.processes.Exp', 1/sn.hostdem_mean(aidx));
233 if ~isempty(sn.hostdem_proc{aidx})
234 proc = sn.hostdem_proc{aidx};
235 jHostDem = javaObject(
'jline.lang.processes.MAP', JLINE.from_line_matrix(proc{1}), JLINE.from_line_matrix(proc{2}));
237 jHostDem = javaObject(
'jline.lang.processes.Exp', 1/sn.hostdem_mean(aidx));
240 jHostDem = javaObject(
'jline.lang.processes.Det', sn.hostdem_mean(aidx));
242 line_error(mfilename,sprintf(
'JLINE conversion does not support the %s distribution for host demand yet.',
char(sn.hostdem_type(aidx))));
244 A{a} = javaObject(
'jline.lang.layered.Activity', model, sn.names{aidx}, jHostDem);
247 boundTo = find(sn.graph((sn.eshift+1):(sn.eshift+sn.nentries),aidx));
250 A{a}.boundTo(E{boundTo});
253 if sn.sched(tidx) ~= SchedStrategy.REF % ref tasks don
't reply
254 repliesTo = find(sn.replygraph(a,:)); % index of entry
255 if ~isempty(repliesTo)
256 if ~sn.isref(sn.parent(sn.eshift+repliesTo))
257 A{a}.repliesTo(E{repliesTo});
262 if ~isempty(sn.callpair)
263 cidxs = find(sn.callpair(:,1)==aidx);
264 calls = sn.callpair(:,2);
266 switch sn.calltype(c)
268 A{a}.synchCall(E{calls(c)-sn.eshift},sn.callproc_mean(c));
270 A{a}.asynchCall(E{calls(c)-sn.eshift},sn.callproc_mean(c));
279 if ~isempty(sn.think{h}) && sn.think_type(h) ~= ProcessType.DISABLED
280 switch sn.think_type(h)
281 case ProcessType.IMMEDIATE
282 P{h}.setThinkTime(jline.lang.processes.Immediate);
284 P{h}.setThinkTime(jline.lang.processes.Exp(1/sn.think_mean(h)));
285 case ProcessType.ERLANG
286 P{h}.setThinkTime(jline.lang.processes.Erlang.fitMeanAndSCV(sn.think_mean(h),sn.think_scv(h)));
287 case ProcessType.HYPEREXP
288 % For HyperExp, reconstruct from params
if available, otherwise use fitMeanAndSCV
289 if ~isempty(sn.think_params{h}) && length(sn.think_params{h}) >= 3
290 P{h}.setThinkTime(jline.lang.processes.HyperExp(sn.think_params{h}(1), sn.think_params{h}(2), sn.think_params{h}(3)));
292 P{h}.setThinkTime(jline.lang.processes.HyperExp.fitMeanAndSCV(sn.think_mean(h), sn.think_scv(h)));
294 case ProcessType.COXIAN
295 % For Coxian, use fitMeanAndSCV
296 P{h}.setThinkTime(jline.lang.processes.Coxian.fitMeanAndSCV(sn.think_mean(h), sn.think_scv(h)));
298 % For APH, reconstruct from params
if available
299 if ~isempty(sn.think_params{h})
300 P{h}.setThinkTime(jline.lang.processes.APH.fitMeanAndSCV(sn.think_mean(h), sn.think_scv(h)));
302 P{h}.setThinkTime(jline.lang.processes.Exp(1/sn.think_mean(h)));
305 line_error(mfilename,sprintf(
'JLINE conversion does not support the %s distribution yet.',
char(sn.think_type(h))));
310 %% Sequential precedences
312 aidx = sn.ashift + ai;
313 tidx = sn.parent(aidx);
315 for bidx=find(sn.graph(aidx,:))
316 if bidx > sn.ashift % ignore precedence between entries and activities
317 % Serial pattern (SEQ)
318 if full(sn.actpretype(aidx)) == ActivityPrecedenceType.PRE_SEQ && full(sn.actposttype(bidx)) == ActivityPrecedenceType.POST_SEQ
319 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.Serial(sn.names{aidx}, sn.names{bidx}));
325 %%%%%%%%%%%%%%%%%%%%%%%%%%% translated up to here
327 %% Loop precedences (POST_LOOP)
328 % Loop structure in sn.graph:
329 % - Entry activity (preAct) has edge to first loop body activity
330 % - Last loop body activity has back-edge to first loop body (weight = 1-1/counts)
331 % - Last loop body activity has edge to end activity (weight = 1/counts)
332 % - All loop body and end activities have POST_LOOP type
333 processedLoops = false(1, sn.nacts);
335 aidx = sn.ashift + ai;
336 tidx = sn.parent(aidx);
337 % Check
if this activity starts a loop (has a successor with POST_LOOP type)
338 % and hasn
't been processed as part of another loop
339 if processedLoops(ai)
343 successors = find(sn.graph(aidx,:));
344 for bidx = successors
345 if bidx > sn.ashift && full(sn.actposttype(bidx)) == ActivityPrecedenceType.POST_LOOP
346 % Skip if this loop body activity was already processed
347 if processedLoops(bidx - sn.ashift)
350 % Found start of a loop: aidx is the entry, bidx is first loop body activity
352 precActs = java.util.ArrayList();
354 % Follow the chain of POST_LOOP activities
357 precActs.add(sprintf("%s", sn.names{curIdx}));
358 processedLoops(curIdx - sn.ashift) = true;
360 % Find successors of current activity
361 curSuccessors = find(sn.graph(curIdx,:));
362 curSuccessors = curSuccessors(curSuccessors > sn.ashift);
364 % Check for loop termination: find the end activity
365 % End activity has weight = 1/counts (not the back-edge weight)
368 for succIdx = curSuccessors
369 if full(sn.actposttype(succIdx)) == ActivityPrecedenceType.POST_LOOP
370 if succIdx == loopStart
371 % This is the back-edge, skip it
374 weight = full(sn.graph(curIdx, succIdx));
375 if weight > 0 && weight < 1
376 % This is the end activity (weight = 1/counts)
379 % This is the next activity in the loop body (weight = 1.0)
386 % Found end activity - calculate counts and output
387 weight = full(sn.graph(curIdx, endIdx));
391 counts = 1; % Fallback to prevent division by zero
393 precActs.add(sprintf("%s", sn.names{endIdx}));
394 processedLoops(endIdx - sn.ashift) = true;
396 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.Loop(sn.names{aidx}, precActs, jline.util.matrix.Matrix(counts)));
399 % Continue to next activity in loop body
402 % No more successors - shouldn't happen in valid loop
406 break; % Only process one loop starting from
this activity
411 %% OrFork precedences (POST_OR)
415 aidx = sn.ashift + ai;
416 tidx = sn.parent(aidx);
419 for bidx=find(sn.graph(aidx,:))
420 if bidx > sn.ashift % ignore precedence between entries and activities
421 % Or pattern (POST_OR)
422 if full(sn.actposttype(bidx)) == ActivityPrecedenceType.POST_OR
423 if precMarker == 0 % start a new orjoin
424 precActs = java.util.ArrayList();
425 precMarker = aidx-sn.ashift;
426 precActs.add(sprintf(
"%s", sn.names{bidx}));
427 probs=full(sn.graph(aidx,bidx));
429 precActs.add(sprintf(
"%s", sn.names{bidx}));
430 probs(end+1)=full(sn.graph(aidx,bidx));
438 probsMatrix = jline.util.matrix.Matrix(1,length(probs));
439 for i=1:length(probs)
440 probsMatrix.set(0,i-1,probs(i));
442 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.OrFork(sn.names{precMarker+sn.ashift}, precActs, probsMatrix));
447 %% AndFork precedences (POST_AND)
451 aidx = sn.ashift + ai;
452 tidx = sn.parent(aidx);
454 for bidx=find(sn.graph(aidx,:))
455 if bidx > sn.ashift % ignore precedence between entries and activities
456 % Or pattern (POST_AND)
457 if full(sn.actposttype(bidx)) == ActivityPrecedenceType.POST_AND
459 postActs = java.util.ArrayList();
460 postActs.add(sprintf(
"%s", sn.names{bidx}));
462 postActs.add(sprintf(
"%s", sn.names{bidx}));
465 if precMarker == 0 % start a
new orjoin
466 precMarker = aidx-sn.ashift;
472 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.AndFork(sn.names{precMarker+sn.ashift}, postActs));
477 %% CacheAccess precedences (POST_CACHE)
481 aidx = sn.ashift + ai;
482 tidx = sn.parent(aidx);
484 for bidx=find(sn.graph(aidx,:))
485 if bidx > sn.ashift % ignore precedence between entries and activities
486 % CacheAccess pattern (POST_CACHE)
487 if full(sn.actposttype(bidx)) == ActivityPrecedenceType.POST_CACHE
489 postActs = java.util.ArrayList();
490 postActs.add(sprintf(
"%s", sn.names{bidx}));
492 postActs.add(sprintf(
"%s", sn.names{bidx}));
495 if precMarker == 0 % start a
new cache access
496 precMarker = aidx-sn.ashift;
502 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.CacheAccess(sn.names{precMarker+sn.ashift}, postActs));
508 %% OrJoin precedences (PRE_OR)
510 for bi = sn.nacts:-1:1
511 bidx = sn.ashift + bi;
512 tidx = sn.parent(bidx);
513 %
for all predecessors
514 for aidx=find(sn.graph(:,bidx))
'
515 if aidx > sn.ashift % ignore precedence between entries and activities
516 % OrJoin pattern (PRE_OR)
517 if full(sn.actpretype(aidx)) == ActivityPrecedenceType.PRE_OR
518 if precMarker == 0 % start a new orjoin
519 precActs = java.util.ArrayList();
520 precMarker = bidx-sn.ashift;
521 precActs.add(sprintf("%s", sn.names{aidx}));
523 precActs.add(sprintf("%s", sn.names{aidx}));
529 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.OrJoin(precActs, sn.names{precMarker+sn.ashift}));
534 %% AndJoin precedences (PRE_AND)
536 for bi = sn.nacts:-1:1
537 bidx = sn.ashift + bi;
538 tidx = sn.parent(bidx);
539 % for all predecessors
540 for aidx=find(sn.graph(:,bidx))'
541 if aidx > sn.ashift % ignore precedence between entries and activities
542 % OrJoin pattern (PRE_AND)
543 if full(sn.actpretype(aidx)) == ActivityPrecedenceType.PRE_AND
544 if precMarker == 0 % start a new orjoin
545 precActs = java.util.ArrayList();
546 precMarker = bidx-sn.ashift;
547 precActs.add(sprintf(
"%s", sn.names{aidx}));
549 precActs.add(sprintf(
"%s", sn.names{aidx}));
555 % Find quorum parameter from original precedence structure
556 postActName = sn.names{precMarker+sn.ashift};
557 localTaskIdx = tidx - sn.tshift;
559 for ap = 1:length(line_layered_network.tasks{localTaskIdx}.precedences)
560 precedence = line_layered_network.tasks{localTaskIdx}.precedences(ap);
561 if precedence.preType == ActivityPrecedenceType.PRE_AND
562 % Check
if this precedence contains our post activity
563 if any(strcmp(precedence.postActs, postActName))
564 quorum = precedence.preParams;
571 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.AndJoin(precActs, sn.names{precMarker+sn.ashift}));
573 T{tidx-sn.tshift}.addPrecedence(jline.lang.layered.ActivityPrecedence.AndJoin(precActs, sn.names{precMarker+sn.ashift}, quorum));
581 function jdist = from_line_distribution(line_dist)
582 if isa(line_dist,
'Exp')
583 jdist = javaObject('jline.lang.processes.Exp', line_dist.getParam(1).paramValue);
584 elseif isa(line_dist, "APH")
585 alpha = line_dist.getParam(1).paramValue;
586 T = line_dist.getParam(2).paramValue;
587 jline_alpha = java.util.ArrayList();
588 for i = 1:length(alpha)
589 jline_alpha.add(alpha(i));
591 jline_T = JLINE.from_line_matrix(T);
592 jdist = javaObject('jline.lang.processes.APH', jline_alpha, jline_T);
593 elseif isa(line_dist, 'Coxian')
594 jline_mu = java.util.ArrayList();
595 jline_phi = java.util.ArrayList();
596 if length(line_dist.params) == 3
597 jline_mu.add(line_dist.getParam(1).paramValue);
598 jline_mu.add(line_dist.getParam(2).paramValue);
599 jline_phi.add(line_dist.getParam(3).paramValue);
601 mu = line_dist.getParam(1).paramValue;
602 phi = line_dist.getParam(2).paramValue;
606 for i = 1:length(phi)
607 jline_phi.add(phi(i));
610 jdist = javaObject('jline.lang.processes.Coxian', jline_mu, jline_phi);
611 elseif isa(line_dist, 'Det')
612 jdist = javaObject('jline.lang.processes.Det', line_dist.getParam(1).paramValue);
613 elseif isa(line_dist, 'DiscreteSampler')
614 popularity_p = JLINE.from_line_matrix(line_dist.getParam(1).paramValue);
615 popularity_val = JLINE.from_line_matrix(line_dist.getParam(2).paramValue);
616 jdist = javaObject('jline.lang.processes.DiscreteSampler', popularity_p, popularity_val);
617 elseif isa(line_dist, 'Erlang')
618 jdist = javaObject('jline.lang.processes.Erlang', line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue);
619 elseif isa(line_dist, 'Gamma')
620 jdist = javaObject('jline.lang.processes.Gamma', line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue);
621 elseif isa(line_dist, "HyperExp")
622 jdist = javaObject('jline.lang.processes.HyperExp', line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue, line_dist.getParam(3).paramValue);
623 elseif isa(line_dist, 'Lognormal')
624 jdist = javaObject('jline.lang.processes.Lognormal', line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue);
625 elseif isa(line_dist, 'Pareto')
626 jdist = javaObject('jline.lang.processes.Pareto', line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue);
627 elseif isa(line_dist, 'MAP')
630 jdist = javaObject('jline.lang.processes.MAP', JLINE.from_line_matrix(D0), JLINE.from_line_matrix(D1));
631 elseif isa(line_dist, 'MMPP2')
632 lambda0 = line_dist.getParam(1).paramValue;
633 lambda1 = line_dist.getParam(2).paramValue;
634 sigma0 = line_dist.getParam(3).paramValue;
635 sigma1 = line_dist.getParam(4).paramValue;
636 jdist = javaObject('jline.lang.processes.MMPP2', lambda0, lambda1, sigma0, sigma1);
637 elseif isa(line_dist, 'PH')
638 alpha = line_dist.getParam(1).paramValue;
639 T = line_dist.getParam(2).paramValue;
640 jdist = javaObject('jline.lang.processes.PH', JLINE.from_line_matrix(alpha), JLINE.from_line_matrix(T));
641 elseif isa(line_dist, 'Uniform')
642 jdist = javaObject('jline.lang.processes.Uniform', line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue);
643 elseif isa(line_dist, 'Weibull')
644 jdist = javaObject('jline.lang.processes.Weibull', line_dist.getParam(1).paramValue, line_dist.getParam(2).paramValue);
645 elseif isa(line_dist, 'Zipf')
646 jdist = javaObject('jline.lang.processes.Zipf', line_dist.getParam(3).paramValue, line_dist.getParam(4).paramValue);
647 elseif isa(line_dist, 'Immediate')
648 jdist = javaObject('jline.lang.processes.Immediate');
649 elseif isempty(line_dist) || isa(line_dist, 'Disabled')
650 jdist = javaObject('jline.lang.processes.Disabled');
652 elseif isa(line_dist, 'Replayer')
653 jdist = javaObject('jline.lang.processes.Replayer', line_dist.params{1}.paramValue);
654 elseif isa(line_dist,
'Trace')
655 jdist = javaObject('jline.lang.processes.Trace', line_dist.params{1}.paramValue);
656 elseif isa(line_dist,
'Prior')
657 % Convert Prior: each alternative
is a distribution
658 dists = line_dist.getParam(1).paramValue;
659 probs = line_dist.getParam(2).paramValue;
660 jdists = java.util.ArrayList();
661 for k = 1:length(dists)
662 jdists.add(JLINE.from_line_distribution(dists{k}));
664 jdist = javaObject(
'jline.lang.processes.Prior', jdists, probs);
666 line_error(mfilename,
'Distribution not supported by JLINE.');
670 function matlab_dist = from_jline_distribution(jdist)
671 if isa(jdist,
'jline.lang.processes.Exp')
672 matlab_dist = Exp(jdist.getRate());
673 elseif isa(jdist, 'jline.lang.processes.Det')
674 matlab_dist = Det(jdist.getParam(1).getValue);
675 elseif isa(jdist, 'jline.lang.processes.Erlang')
676 matlab_dist = Erlang(jdist.getParam(1).getValue(),jdist.getNumberOfPhases());
677 elseif isa(jdist, 'jline.lang.processes.Gamma')
678 matlab_dist = Gamma(jdist.getParam(1).getValue,jdist.getParam(2).getValue);
679 elseif isa(jdist, 'jline.lang.processes.HyperExp')
680 matlab_dist = HyperExp(jdist.getParam(1).getValue, jdist.getParam(2).getValue, jdist.getParam(3).getValue);
681 elseif isa(jdist, 'jline.lang.processes.Lognormal')
682 matlab_dist = Lognormal(jdist.getParam(1).getValue,jdist.getParam(2).getValue);
683 elseif isa(jdist, 'jline.lang.processes.Pareto')
684 matlab_dist = Pareto(jdist.getParam(1).getValue,jdist.getParam(2).getValue);
685 elseif isa(jdist, 'jline.lang.processes.Uniform')
686 matlab_dist = Uniform(jdist.getParam(1).getValue,jdist.getParam(2).getValue);
687 elseif isa(jdist, 'jline.lang.processes.Weibull')
688 matlab_dist = Weibull(jdist.getParam(1).getValue,jdist.getParam(2).getValue);
689 elseif isa(jdist, 'jline.lang.processes.MAP')
690 D0 = JLINE.from_jline_matrix(jdist.D(0));
691 D1 = JLINE.from_jline_matrix(jdist.D(1));
692 matlab_dist = MAP({D0, D1});
693 elseif isa(jdist,
'jline.lang.processes.APH')
694 alpha = JLINE.from_jline_matrix(jdist.getInitProb());
695 T = JLINE.from_jline_matrix(jdist.getSubgenerator());
696 matlab_dist = APH(alpha(:)', T);
697 elseif isa(jdist, 'jline.lang.processes.PH')
698 alpha = JLINE.from_jline_matrix(jdist.getInitProb());
699 T = JLINE.from_jline_matrix(jdist.getSubgenerator());
700 matlab_dist = PH(alpha(:)', T);
701 elseif isa(jdist, 'jline.lang.processes.Coxian')
702 if jdist.getNumberOfPhases == 2
703 matlab_dist = Coxian([jdist.getParam(1).getValue.get(0), jdist.getParam(1).getValue.get(1)], [jdist.getParam(2).getValue.get(0),1]);
705 jmu = jdist.getParam(1).getValue;
706 jphi = jdist.getParam(2).getValue;
707 mu = zeros(1, jmu.size);
708 phi = zeros(1, jphi.size);
710 mu(i) = jmu.get(i-1);
713 phi(i) = jphi.get(i-1);
715 matlab_dist = Coxian(mu, phi);
717 elseif isa(jdist, 'jline.lang.processes.Zipf')
718 matlab_dist = Zipf(jdist.getParam(3).getValue, jdist.getParam(4).getValue);
719 elseif isa(jdist, 'jline.lang.processes.DiscreteSampler')
720 jpMat = jdist.getParam(1).getValue;
721 jxMat = jdist.getParam(2).getValue;
722 p = zeros(1, jpMat.length);
723 x = zeros(1, jxMat.length);
724 for i = 1:jpMat.length
725 p(i) = jpMat.get(i-1);
727 for i = 1:jxMat.length
728 x(i) = jxMat.get(i-1);
730 matlab_dist = DiscreteSampler(p, x);
731 elseif isa(jdist, 'jline.lang.processes.Immediate')
732 matlab_dist = Immediate();
733 elseif isa(jdist, 'jline.lang.processes.Disabled')
734 matlab_dist = Disabled();
735 elseif isa(jdist, 'jline.lang.processes.MMPP2')
736 matlab_dist = MMPP2(jdist.getParam(1).getValue, jdist.getParam(2).getValue, jdist.getParam(3).getValue, jdist.getParam(4).getValue);
737 elseif isa(jdist, 'jline.lang.processes.Prior')
738 % Convert Prior from JAR to MATLAB
739 jdists = jdist.getDistributions();
740 nalt = jdists.size();
741 dists = cell(1, nalt);
743 dists{k} = JLINE.from_jline_distribution(jdists.get(k-1));
745 probs = jdist.getProbabilities();
746 matlab_dist = Prior(dists, probs);
748 line_error(mfilename,
'Distribution not supported by JLINE.');
752 function set_csMatrix(line_node, jnode, jclasses)
753 nClasses = length(line_node.model.classes);
754 csMatrix = jnode.initClassSwitchMatrix();
757 csMatrix.set(jclasses{i}, jclasses{j}, line_node.server.csFun(i,j,0,0));
760 jnode.setClassSwitchingMatrix(csMatrix);
763 function set_service(line_node, jnode, job_classes)
764 if (isa(line_node,
'Sink') || isa(line_node,
'Router') || isa(line_node,
'Cache') || isa(line_node,
'Logger') || isa(line_node,
'ClassSwitch') || isa(line_node,
'Fork') || isa(line_node,
'Join') || isa(line_node,
'Place') || isa(line_node,
'Transition'))
768 for n = 1 : length(job_classes)
769 if (isa(line_node,
'Queue') || isa(line_node,
'Delay'))
770 matlab_dist = line_node.getService(job_classes{n});
771 elseif (isa(line_node,
'Source'))
772 matlab_dist = line_node.getArrivalProcess(job_classes{n});
774 line_error(mfilename,
'Node not supported by JLINE.');
776 service_dist = JLINE.from_line_distribution(matlab_dist);
778 if (isa(line_node,
'Queue') || isa(line_node,
'Delay'))
779 jnode.setService(jnode.getModel().getClasses().get(n-1), service_dist, line_node.schedStrategyPar(n));
780 elseif (isa(line_node,
'Source'))
781 jnode.setArrival(jnode.getModel().getClasses().get(n-1), service_dist);
786 function set_delayoff(line_node, jnode, job_classes)
787 % Transfer setup and delayoff times from MATLAB Queue to Java Queue
788 if ~isa(line_node, 'Queue')
792 % Check if setupTime property exists and
is not empty
793 if ~isprop(line_node, 'setupTime') || isempty(line_node.setupTime)
797 for n = 1 : length(job_classes)
798 c = job_classes{n}.index;
799 % Check
if both setupTime and delayoffTime are set
for this class
800 if c <= length(line_node.setupTime) && ~isempty(line_node.setupTime{1, c}) && ...
801 c <= length(line_node.delayoffTime) && ~isempty(line_node.delayoffTime{1, c})
802 % Convert MATLAB distributions to Java distributions
803 setup_dist = JLINE.from_line_distribution(line_node.setupTime{1, c});
804 delayoff_dist = JLINE.from_line_distribution(line_node.delayoffTime{1, c});
805 % Set delayoff on the Java Queue
806 jnode.setDelayOff(jnode.getModel().getClasses().get(n-1), setup_dist, delayoff_dist);
811 function set_line_service(jline_node, line_node, job_classes, line_classes)
812 if (isa(line_node,
'Sink')) || isa(line_node,
'ClassSwitch') || isa(line_node,
'Fork') || isa(line_node,
'Join') || isa(line_node,
'Place') || isa(line_node,
'Transition') || isa(line_node,
'Cache')
815 for n = 1:job_classes.size()
816 if (isa(line_node, 'Queue') || isa(line_node, 'Delay'))
817 jdist = jline_node.getServiceProcess(job_classes.get(n-1));
818 matlab_dist = JLINE.from_jline_distribution(jdist);
819 weight = jline_node.getSchedStrategyPar(job_classes.get(n-1));
820 line_node.setService(line_classes{n}, matlab_dist, weight);
821 elseif (isa(line_node,
'Source'))
822 jdist = jline_node.getArrivalProcess(job_classes.get(n-1));
823 matlab_dist = JLINE.from_jline_distribution(jdist);
824 line_node.setArrival(line_classes{n}, matlab_dist);
825 elseif (isa(line_node,
'Router'))
828 line_error(mfilename,'Node not supported by JLINE.');
833 function node_object = from_line_node(line_node, jnetwork, ~, forkNode, sn)
834 % Handle optional sn argument
838 if isa(line_node,
'Delay')
839 node_object = javaObject('jline.lang.
nodes.Delay', jnetwork, line_node.getName);
840 elseif isa(line_node, 'Queue')
841 switch line_node.schedStrategy
842 case SchedStrategy.INF
843 node_object = javaObject('jline.lang.
nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.INF);
844 case SchedStrategy.FCFS
845 node_object = javaObject('jline.lang.
nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FCFS);
846 case SchedStrategy.LCFS
847 node_object = javaObject('jline.lang.
nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LCFS);
848 case SchedStrategy.SIRO
849 node_object = javaObject('jline.lang.
nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.SIRO);
850 case SchedStrategy.SJF
851 node_object = javaObject('jline.lang.
nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.SJF);
852 case SchedStrategy.LJF
853 node_object = javaObject('jline.lang.
nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LJF);
854 case SchedStrategy.PS
855 node_object = javaObject('jline.lang.
nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.PS);
856 case SchedStrategy.DPS
857 node_object = javaObject('jline.lang.
nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.DPS);
858 case SchedStrategy.GPS
859 node_object = javaObject('jline.lang.
nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.GPS);
860 case SchedStrategy.SEPT
861 node_object = javaObject('jline.lang.
nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.SEPT);
862 case SchedStrategy.LEPT
863 node_object = javaObject('jline.lang.
nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LEPT);
864 case {SchedStrategy.HOL, SchedStrategy.FCFSPRIO}
865 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FCFSPRIO);
866 case SchedStrategy.FORK
867 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FORK);
868 case SchedStrategy.EXT
869 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.EXT);
870 case SchedStrategy.REF
871 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.REF);
872 case SchedStrategy.LCFSPR
873 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LCFSPR);
874 case SchedStrategy.LCFSPI
875 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LCFSPI);
876 case SchedStrategy.LCFSPRIO
877 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LCFSPRIO);
878 case SchedStrategy.LCFSPRPRIO
879 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LCFSPRPRIO);
880 case SchedStrategy.LCFSPIPRIO
881 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LCFSPIPRIO);
882 case SchedStrategy.FCFSPR
883 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FCFSPR);
884 case SchedStrategy.FCFSPI
885 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FCFSPI);
886 case SchedStrategy.FCFSPRPRIO
887 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FCFSPRPRIO);
888 case SchedStrategy.FCFSPIPRIO
889 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FCFSPIPRIO);
890 case SchedStrategy.PSPRIO
891 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.PSPRIO);
892 case SchedStrategy.DPSPRIO
893 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.DPSPRIO);
894 case SchedStrategy.GPSPRIO
895 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.GPSPRIO);
896 case SchedStrategy.POLLING
897 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.POLLING);
898 case SchedStrategy.SRPT
899 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.SRPT);
900 case SchedStrategy.SRPTPRIO
901 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.SRPTPRIO);
902 case SchedStrategy.PSJF
903 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.PSJF);
904 case SchedStrategy.FB
905 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.FB);
906 case SchedStrategy.LRPT
907 node_object = javaObject(
'jline.lang.nodes.Queue', jnetwork, line_node.getName, jline.lang.constant.SchedStrategy.LRPT);
909 nservers = line_node.getNumberOfServers;
911 node_object.setNumberOfServers(java.lang.Integer.MAX_VALUE);
913 node_object.setNumberOfServers(line_node.getNumberOfServers);
915 if ~isempty(line_node.lldScaling)
916 node_object.setLoadDependence(JLINE.from_line_matrix(line_node.lldScaling));
918 if ~isempty(line_node.lcdScaling)
920 line_error(mfilename, "Class-dependent models require sn struct for MATLAB-to-JAVA translation.");
922 node_object.setLimitedClassDependence(JLINE.handle_to_serializablefun(line_node.lcdScaling, sn));
924 % Transfer LJD (Limited Joint Dependence) scaling
925 if ~isempty(line_node.ljdScaling) && ~isempty(line_node.ljdCutoffs)
926 jScaling = JLINE.from_line_matrix(line_node.ljdScaling(:));
927 jCutoffs = JLINE.from_line_matrix(line_node.ljdCutoffs(:));
928 node_object.setLimitedJointDependence(jScaling, jCutoffs);
930 % NOTE: LJCD (Limited Joint Class Dependence)
is transferred in
931 % from_line_network after
classes are created
932 % Set queue capacity if finite
933 if ~isinf(line_node.cap)
934 node_object.setCapacity(line_node.cap);
936 elseif isa(line_node, 'Source')
937 node_object = javaObject('jline.lang.
nodes.Source', jnetwork, line_node.getName);
938 elseif isa(line_node, 'Sink')
939 node_object = javaObject('jline.lang.
nodes.Sink', jnetwork, line_node.getName);
940 elseif isa(line_node, 'Router')
941 node_object = javaObject('jline.lang.
nodes.Router', jnetwork, line_node.getName);
942 elseif isa(line_node, 'ClassSwitch')
943 node_object = javaObject('jline.lang.
nodes.ClassSwitch', jnetwork, line_node.getName);
944 elseif isa(line_node, 'Fork')
945 node_object = javaObject('jline.lang.
nodes.Fork', jnetwork, line_node.name);
946 node_object.setTasksPerLink(line_node.output.tasksPerLink);
947 elseif isa(line_node, 'Join')
948 node_object = javaObject('jline.lang.
nodes.Join', jnetwork, line_node.name, forkNode);
949 elseif isa(line_node, 'Logger')
950 node_object = javaObject('jline.lang.
nodes.Logger', jnetwork, line_node.name, [line_node.filePath,line_node.fileName]);
951 elseif isa(line_node, 'Cache')
952 nitems = line_node.items.nitems;
953 switch line_node.replacestrategy
954 case ReplacementStrategy.RR
955 repStrategy = jline.lang.constant.ReplacementStrategy.RR;
956 case ReplacementStrategy.FIFO
957 repStrategy = jline.lang.constant.ReplacementStrategy.FIFO;
958 case ReplacementStrategy.SFIFO
959 repStrategy = jline.lang.constant.ReplacementStrategy.SFIFO;
960 case ReplacementStrategy.LRU
961 repStrategy = jline.lang.constant.ReplacementStrategy.LRU;
963 if ~isempty(line_node.graph)
964 node_object = javaObject('jline.lang.
nodes.Cache', jnetwork, line_node.name, nitems, JLINE.from_line_matrix(line_node.itemLevelCap), repStrategy, JLINE.from_line_matrix(line_node.graph));
966 node_object = javaObject('jline.lang.
nodes.Cache', jnetwork, line_node.name, nitems, JLINE.from_line_matrix(line_node.itemLevelCap), repStrategy);
968 elseif isa(line_node, 'Place')
969 node_object = javaObject('jline.lang.
nodes.Place', jnetwork, line_node.getName);
970 elseif isa(line_node, 'Transition')
971 node_object = javaObject('jline.lang.
nodes.Transition', jnetwork, line_node.getName);
972 % Modes are added later in from_line_network after
classes are created
974 line_error(mfilename,'Node not supported by JLINE.');
978 function node_object = from_jline_node(jline_node, model, job_classes)
979 if isa(jline_node, 'jline.lang.
nodes.Delay')
980 node_object = Delay(model, jline_node.getName.toCharArray');
981 elseif isa(jline_node, 'jline.lang.
nodes.Queue')
982 schedStrategy = jline_node.getSchedStrategy;
983 switch schedStrategy.name().toCharArray'
985 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.INF);
987 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FCFS);
989 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LCFS);
991 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.SIRO);
993 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.SJF);
995 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LJF);
997 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.PS);
999 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.DPS);
1001 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.GPS);
1003 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.SEPT);
1005 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LEPT);
1006 case {
'HOL',
'FCFSPRIO'}
1007 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.FCFSPRIO);
1009 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FORK);
1011 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.EXT);
1013 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.REF);
1015 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.LCFSPR);
1017 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.SRPT);
1019 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.SRPTPRIO);
1021 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.PSJF);
1023 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.FB);
1025 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LRPT);
1027 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.PSPRIO);
1029 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.DPSPRIO);
1031 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.GPSPRIO);
1033 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LCFSPI);
1035 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.LCFSPRIO);
1037 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.LCFSPRPRIO);
1039 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.LCFSPIPRIO);
1041 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FCFSPR);
1043 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.FCFSPI);
1045 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.FCFSPRPRIO);
1047 node_object = Queue(model, jline_node.getName.toCharArray
', SchedStrategy.FCFSPIPRIO);
1049 node_object = Queue(model, jline_node.getName.toCharArray', SchedStrategy.POLLING);
1051 node_object.setNumberOfServers(jline_node.getNumberOfServers);
1052 cap = jline_node.getCap();
1053 if cap < intmax && cap > 0
1054 node_object.setCapacity(cap);
1056 if ~isempty(JLINE.from_jline_matrix(jline_node.getLimitedLoadDependence))
1057 node_object.setLoadDependence(JLINE.from_jline_matrix(jline_node.getLimitedLoadDependence));
1059 elseif isa(jline_node, 'jline.lang.
nodes.Source')
1060 node_object = Source(model, jline_node.getName.toCharArray');
1061 elseif isa(jline_node, 'jline.lang.
nodes.Sink')
1062 node_object = Sink(model, jline_node.getName.toCharArray');
1063 elseif isa(jline_node, 'jline.lang.
nodes.Router')
1064 node_object = Router(model, jline_node.getName.toCharArray');
1065 elseif isa(jline_node, 'jline.lang.
nodes.ClassSwitch')
1066 nClasses = job_classes.size;
1067 csMatrix = zeros(nClasses, nClasses);
1070 csMatrix(r,s) = jline_node.getServer.applyCsFun(r-1,s-1);
1073 node_object = ClassSwitch(model, jline_node.getName.toCharArray', csMatrix);
1074 elseif isa(jline_node, 'jline.lang.
nodes.Cache')
1075 numItems = jline_node.getNumberOfItems();
1076 itemLevelCap = JLINE.from_jline_matrix(jline_node.getItemLevelCap());
1077 replPolicy = jline_node.getReplacementStrategy();
1078 switch
char(replPolicy)
1080 rp = ReplacementStrategy.LRU;
1082 rp = ReplacementStrategy.FIFO;
1084 rp = ReplacementStrategy.RR;
1086 rp = ReplacementStrategy.LRU;
1088 node_object = Cache(model, jline_node.getName.toCharArray', numItems, itemLevelCap, rp);
1089 % hitClass, missClass, and popularity set later in jline_to_line
1090 elseif isa(jline_node, 'jline.lang.
nodes.Fork')
1091 node_object = Fork(model, jline_node.getName.toCharArray');
1092 tpl = jline_node.getOutput().tasksPerLink;
1094 node_object.setTasksPerLink(tpl);
1096 elseif isa(jline_node, 'jline.lang.
nodes.Join')
1097 node_object = Join(model, jline_node.getName.toCharArray');
1098 % joinOf
is set later in jline_to_line after all
nodes are created
1099 elseif isa(jline_node, 'jline.lang.
nodes.Place')
1100 node_object = Place(model, jline_node.getName.toCharArray');
1101 elseif isa(jline_node, 'jline.lang.
nodes.Transition')
1102 node_object = Transition(model, jline_node.getName.toCharArray');
1103 % Note: Mode configurations need to be set after
classes are created
1105 line_error(mfilename,'Node not supported by JLINE.');
1109 function node_class = from_line_class(line_class, jnetwork)
1111 if isa(line_class, 'ClosedSignal')
1112 % ClosedSignal -> jline.lang.ClosedSignal
1113 jSignalType = jline.lang.constant.SignalType.fromID(line_class.signalType);
1114 node_class = javaObject('jline.lang.ClosedSignal', jnetwork, line_class.getName, jSignalType, jnetwork.getNodeByName(line_class.refstat.getName), line_class.priority);
1115 elseif isa(line_class, 'Signal') || isa(line_class, 'OpenSignal')
1116 % Signal/OpenSignal -> jline.lang.Signal (includes CATASTROPHE type)
1117 jSignalType = jline.lang.constant.SignalType.fromID(line_class.signalType);
1118 node_class = javaObject('jline.lang.Signal', jnetwork, line_class.getName, jSignalType, line_class.priority);
1119 elseif isa(line_class, 'OpenClass')
1120 node_class = javaObject('jline.lang.OpenClass', jnetwork, line_class.getName, line_class.priority);
1121 elseif isa(line_class, 'SelfLoopingClass')
1122 node_class = javaObject('jline.lang.SelfLoopingClass', jnetwork, line_class.getName, line_class.population, jnetwork.getNodeByName(line_class.refstat.getName), line_class.priority);
1123 elseif isa(line_class, 'ClosedClass')
1124 node_class = javaObject('jline.lang.ClosedClass', jnetwork, line_class.getName, line_class.population, jnetwork.getNodeByName(line_class.refstat.getName), line_class.priority);
1126 line_error(mfilename,'Class type not supported by JLINE.');
1128 if line_class.isReferenceClass()
1129 node_class.setReferenceClass(true);
1133 function node_class = from_jline_class(jclass, model)
1134 if isa(jclass, 'jline.lang.OpenClass')
1135 node_class = OpenClass(model, jclass.getName.toCharArray', jclass.getPriority);
1136 elseif isa(jclass, 'jline.lang.SelfLoopingClass')
1137 node_class = SelfLoopingClass(model, jclass.getName.toCharArray', jclass.getNumberOfJobs, model.getNodeByName(jclass.getReferenceStation.getName), jclass.getPriority);
1138 elseif isa(jclass, 'jline.lang.ClosedClass')
1139 node_class = ClosedClass(model, jclass.getName.toCharArray', jclass.getNumberOfJobs, model.getNodeByName(jclass.getReferenceStation.getName), jclass.getPriority);
1141 line_error(mfilename,'Class type not supported by JLINE.');
1145 function from_line_links(model, jmodel)
1146 connections = model.getConnectionMatrix();
1147 [m, ~] = size(connections);
1148 jnodes = jmodel.getNodes();
1149 jclasses = jmodel.getClasses();
1150 njclasses = jclasses.size();
1151 line_nodes = model.getNodes;
1152 sn = model.getStruct;
1154 % Build mapping from MATLAB node index to Java node index
1155 % (accounting for skipped auto-added ClassSwitch
nodes)
1156 matlab2java_node_idx = zeros(1, length(line_nodes));
1158 for i = 1:length(line_nodes)
1159 if isa(line_nodes{i},
'ClassSwitch') && line_nodes{i}.autoAdded
1160 matlab2java_node_idx(i) = -1; % Mark as skipped
1162 matlab2java_node_idx(i) = jidx;
1168 % [ ] Update to consider different weights/routing
for classes
1169 if isempty(sn.rtorig)
1170 useLinkMethod = false; % this model did not call link()
1172 jrt_matrix = jmodel.initRoutingMatrix();
1173 useLinkMethod = true;
1176 % For models with auto-added ClassSwitch
nodes, use sn.rtorig directly
1177 % to set up routing with proper class switching
1179 for i = 1:length(line_nodes)
1180 if isa(line_nodes{i},
'ClassSwitch') && line_nodes{i}.autoAdded
1186 if useLinkMethod && hasAutoCS
1187 % Use sn.rtorig directly - it contains the full routing with class switching
1188 % sn.rtorig already excludes auto-added ClassSwitch
nodes (it's based on nstations)
1189 % So we iterate over the rtorig matrix dimensions directly
1192 if ~isempty(sn.rtorig{r,s})
1193 Prs = sn.rtorig{r,s};
1194 [nrows, ncols] = size(Prs);
1198 % sn.rtorig uses station indices which
map to non-CS
nodes
1199 % Find the java node indices by matching station index to node
1200 jsrc_idx = i - 1; % Direct mapping since rtorig excludes CS
1202 jrt_matrix.set(jclasses.get(r-1), jclasses.get(s-1), jnodes.get(jsrc_idx), jnodes.get(jdest_idx), Prs(i,j));
1210 % Original logic
for models without
auto-added ClassSwitch
1212 line_node = line_nodes{i};
1214 % Skip
auto-added ClassSwitch
nodes - Java will add them automatically
1215 if isa(line_node, 'ClassSwitch') && line_node.autoAdded
1219 jnode_idx = matlab2java_node_idx(i);
1221 output_strat = line_node.output.outputStrategy{k};
1222 switch RoutingStrategy.fromText(output_strat{2})
1223 case RoutingStrategy.DISABLED
1224 jnodes.get(jnode_idx).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.DISABLED);
1225 case RoutingStrategy.RAND
1226 jnodes.get(jnode_idx).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.RAND);
1227 outlinks_i=find(connections(i,:));
1229 % Do NOT add routing matrix entries
for RAND routing.
1230 % JAR
's getRoutingMatrix computes RAND routing from
1231 % the connection matrix (matching MATLAB behavior).
1232 % Adding entries would cause link() to convert RAND
1233 % to PROB, and for closed classes would incorrectly
1234 % include Sink connections.
1236 for j= outlinks_i(:)'
1237 jdest_idx = matlab2java_node_idx(j);
1239 jmodel.addLink(jnodes.get(jnode_idx), jnodes.get(jdest_idx));
1243 case RoutingStrategy.RROBIN
1244 jnodes.get(jnode_idx).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.RROBIN);
1245 outlinks_i=find(connections(i,:))
';
1247 line_error(mfilename,'RROBIN cannot be used together with the link() command.
');
1249 for j= outlinks_i(:)'
1250 jdest_idx = matlab2java_node_idx(j);
1252 jmodel.addLink(jnodes.get(jnode_idx), jnodes.get(jdest_idx));
1255 case RoutingStrategy.WRROBIN
1256 outlinks_i=find(connections(i,:))
';
1257 for j= outlinks_i(:)'
1258 jdest_idx = matlab2java_node_idx(j);
1260 jmodel.addLink(jnodes.get(jnode_idx), jnodes.get(jdest_idx));
1264 line_error(mfilename,
'RROBIN cannot be used together with the link() command.');
1266 for j= 1:length(output_strat{3})
1267 node_target = jmodel.getNodeByName(output_strat{3}{j}{1}.getName());
1268 weight = output_strat{3}{j}{2};
1269 jnodes.get(jnode_idx).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.WRROBIN, node_target, weight);
1271 case RoutingStrategy.PROB
1272 outlinks_i=find(connections(i,:));
1273 jnodes.get(jnode_idx).setRouting(jclasses.get(k-1), jline.lang.constant.RoutingStrategy.PROB);
1275 for j= outlinks_i(:)
'
1276 jdest_idx = matlab2java_node_idx(j);
1278 jmodel.addLink(jnodes.get(jnode_idx), jnodes.get(jdest_idx));
1282 if length(output_strat) >= 3
1283 probabilities = output_strat{3};
1284 for j = 1:length(probabilities)
1285 dest_idx = probabilities{j}{1}.index;
1286 jdest_idx = matlab2java_node_idx(dest_idx);
1287 if (connections(i, dest_idx) ~= 0) && jdest_idx >= 0
1289 jrt_matrix.set(jclasses.get(k-1), jclasses.get(k-1), jnodes.get(jnode_idx), jnodes.get(jdest_idx), probabilities{j}{2});
1291 jnodes.get(jnode_idx).setProbRouting(jclasses.get(k-1), jnodes.get(jdest_idx), probabilities{j}{2});
1296 case RoutingStrategy.JSQ
1297 jnodes.get(jnode_idx).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.JSQ);
1298 outlinks_i=find(connections(i,:))';
1300 for j= outlinks_i(:)
'
1301 jdest_idx = matlab2java_node_idx(j);
1303 jmodel.addLink(jnodes.get(jnode_idx), jnodes.get(jdest_idx));
1308 line_warning(mfilename, sprintf('''%s
'' routing strategy not supported by JLINE, setting as Disabled.\n
',output_strat{2}));
1309 jnodes.get(jnode_idx).setRouting(jclasses.get(k-1),jline.lang.constant.RoutingStrategy.DISABLED);
1315 jmodel.link(jrt_matrix);
1316 % Align the sn.rtorig be the same, treating artificial
1317 % ClassSwitch nodes as if they were explicitly specified
1318 jsn = jmodel.getStruct(true);
1319 rtorig = java.util.HashMap();
1320 if ~isempty(model.sn.rtorig)
1321 if iscell(model.sn.rtorig)
1323 sub_rtorig = java.util.HashMap();
1325 sub_rtorig.put(jclasses.get(s-1), JLINE.from_line_matrix(model.sn.rtorig{r,s}));
1327 rtorig.put(jclasses.get(r-1), sub_rtorig);
1331 jsn.rtorig = rtorig;
1335 function model = from_jline_routing(model, jnetwork)
1336 jnodes = jnetwork.getNodes();
1337 jclasses = jnetwork.getClasses();
1338 n_nodes = jnodes.size();
1339 network_nodes = model.getNodes;
1340 network_classes = model.getClasses;
1342 % Build name-to-MATLAB-node map (JAR and MATLAB may order nodes differently)
1343 node_by_name = containers.Map();
1344 for nn = 1:length(network_nodes)
1345 node_by_name(network_nodes{nn}.name) = network_nodes{nn};
1348 connections = JLINE.from_jline_matrix(jnetwork.getConnectionMatrix());
1349 [row,col] = find(connections);
1351 from_name = char(jnodes.get(row(i)-1).getName());
1352 to_name = char(jnodes.get(col(i)-1).getName());
1353 model.addLink(node_by_name(from_name), node_by_name(to_name));
1357 jnode = jnodes.get(n-1);
1358 cur_node = node_by_name(char(jnode.getName()));
1359 output_strategies = jnode.getOutputStrategies();
1360 n_strategies = output_strategies.size();
1361 for m = 1 : n_strategies
1362 output_strat = output_strategies.get(m-1);
1363 routing_strat = output_strat.getRoutingStrategy;
1364 routing_strat_classidx = output_strat.getJobClass.getIndex();
1365 switch char(routing_strat)
1367 cur_node.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.RAND);
1369 cur_node.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.RROBIN);
1371 dest = output_strat.getDestination();
1373 dest_name = char(dest.getName());
1374 if node_by_name.isKey(dest_name)
1375 weight = output_strat.getProbability();
1376 cur_node.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.WRROBIN, node_by_name(dest_name), weight);
1380 cur_node.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.DISABLED);
1386 function model = from_jline_links(model, jnetwork)
1387 P = model.initRoutingMatrix;
1388 jnodes = jnetwork.getNodes();
1389 jclasses = jnetwork.getClasses();
1390 n_classes = jclasses.size();
1391 n_nodes = jnodes.size();
1392 network_nodes = model.getNodes;
1394 % Build JAR-to-MATLAB node index mapping (node orders may differ)
1395 jar2ml = zeros(1, n_nodes);
1397 jar_name = char(jnodes.get(jj-1).getName());
1398 for mm = 1:length(network_nodes)
1399 if strcmp(network_nodes{mm}.name, jar_name)
1406 hasDestinations = false;
1408 jnode = jnodes.get(n-1);
1409 output_strategies = jnode.getOutputStrategies();
1410 n_strategies = output_strategies.size();
1411 for m = 1 : n_strategies
1412 output_strat = output_strategies.get(m-1);
1413 dest = output_strat.getDestination();
1414 if~isempty(dest) % disabled strategy
1415 hasDestinations = true;
1416 in_idx = jar2ml(jnetwork.getNodeIndex(jnode)+1);
1417 out_idx = jar2ml(jnetwork.getNodeIndex(dest)+1);
1419 P{1}(in_idx,out_idx) = output_strat.getProbability();
1421 strat_class = output_strat.getJobClass();
1422 class_idx = jnetwork.getJobClassIndex(strat_class)+1;
1423 P{class_idx,class_idx}(in_idx,out_idx) = output_strat.getProbability();
1429 % If no OutputStrategy entries had destinations (e.g., model
1430 % loaded from JSON via LineModelIO.load), fall back to rtorig
1432 sn = jnetwork.getStruct;
1433 if ~isempty(sn.rtorig)
1434 % rtorig is station-indexed (no permutation needed —
1435 % station ordering matches between JAR and MATLAB)
1438 rtMat = JLINE.from_jline_matrix(sn.rtorig.get(jclasses.get(r-1)).get(jclasses.get(s-1)));
1449 % Restore non-PROB routing strategies (RROBIN, WRROBIN, etc.)
1450 % after link(), which sets all routing to PROB
1451 network_nodes = model.getNodes;
1452 network_classes = model.getClasses;
1453 node_by_name = containers.Map();
1454 for nn = 1:length(network_nodes)
1455 node_by_name(network_nodes{nn}.name) = network_nodes{nn};
1458 jnode = jnodes.get(n-1);
1459 cur_node = node_by_name(char(jnode.getName()));
1460 output_strategies = jnode.getOutputStrategies();
1461 n_strategies = output_strategies.size();
1462 for m = 1 : n_strategies
1463 output_strat = output_strategies.get(m-1);
1464 routing_strat = output_strat.getRoutingStrategy;
1465 routing_strat_classidx = output_strat.getJobClass.getIndex();
1466 switch char(routing_strat)
1468 cur_node.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.RROBIN);
1470 dest = output_strat.getDestination();
1472 dest_name = char(dest.getName());
1473 if node_by_name.isKey(dest_name)
1474 % Clear stale PROB entries before first WRROBIN weight
1475 classIdx = routing_strat_classidx;
1476 if length(cur_node.output.outputStrategy) >= classIdx && ...
1477 length(cur_node.output.outputStrategy{1, classIdx}) >= 3
1478 curStrat = cur_node.output.outputStrategy{1, classIdx}{2};
1479 if ~strcmp(curStrat, 'WeightedRoundRobin
')
1480 cur_node.output.outputStrategy{1, classIdx}{3} = {};
1483 weight = output_strat.getProbability();
1484 cur_node.setRouting(network_classes{routing_strat_classidx}, RoutingStrategy.WRROBIN, node_by_name(dest_name), weight);
1491 % Invalidate cached struct after modifying routing strategies
1492 model.resetStruct();
1494 %Align the sn.rtorig be the same (Assume Java network is
1495 %created by calling Network.link)
1496 sn = jnetwork.getStruct;
1497 rtorig = cell(n_classes, n_classes);
1500 rtorig{r,s} = JLINE.from_jline_matrix(sn.rtorig.get(jclasses.get(r-1)).get(jclasses.get(s-1)));
1503 model.sn.rtorig = rtorig;
1506 function [jnetwork] = from_line_network(model)
1509 sn = model.getStruct;
1511 jnetwork = javaObject('jline.lang.Network
', model.getName);
1512 line_nodes = model.getNodes;
1513 line_classes = model.getClasses;
1515 jnodes = cell(1,length(line_nodes));
1516 jclasses = cell(1,length(line_classes));
1518 for n = 1 : length(line_nodes)
1519 % Skip auto-added ClassSwitch nodes - Java's link() will add them automatically
1520 if isa(line_nodes{n},
'ClassSwitch') && line_nodes{n}.autoAdded
1523 if isa(line_nodes{n},
'Join')
1524 jnodes{n} = JLINE.from_line_node(line_nodes{n}, jnetwork, line_classes, jnodes{line_nodes{n}.joinOf.index}, sn);
1526 jnodes{n} = JLINE.from_line_node(line_nodes{n}, jnetwork, line_classes, [], sn);
1530 for n = 1 : length(line_classes)
1531 jclasses{n} = JLINE.from_line_class(line_classes{n}, jnetwork);
1534 % Set up forJobClass associations
for signal
classes
1535 for n = 1 : length(line_classes)
1536 if (isa(line_classes{n},
'Signal') || isa(line_classes{n},
'OpenSignal') || isa(line_classes{n},
'ClosedSignal'))
1537 if ~isempty(line_classes{n}.targetJobClass)
1538 targetIdx = line_classes{n}.targetJobClass.index;
1539 jclasses{n}.forJobClass(jclasses{targetIdx});
1544 for n = 1: length(jnodes)
1545 if isempty(jnodes{n})
1546 continue; % Skip
nodes that were not converted (e.g.,
auto-added ClassSwitch)
1548 JLINE.set_service(line_nodes{n}, jnodes{n}, line_classes);
1549 JLINE.set_delayoff(line_nodes{n}, jnodes{n}, line_classes);
1552 % Set drop rules
for stations (after
classes are created)
1553 for n = 1: length(jnodes)
1554 if isempty(jnodes{n})
1555 continue; % Skip
nodes that were not converted
1557 if isa(line_nodes{n},
'Station') && ~isa(line_nodes{n},
'Source')
1558 for r = 1:length(line_classes)
1559 if length(line_nodes{n}.dropRule) >= r && ~isempty(line_nodes{n}.dropRule(r))
1560 dropRule = line_nodes{n}.dropRule(r);
1562 case DropStrategy.DROP
1563 jnodes{n}.setDropRule(jclasses{r}, jline.lang.constant.DropStrategy.Drop);
1564 case DropStrategy.BAS
1565 jnodes{n}.setDropRule(jclasses{r}, jline.lang.constant.DropStrategy.BlockingAfterService);
1566 case DropStrategy.WAITQ
1567 jnodes{n}.setDropRule(jclasses{r}, jline.lang.constant.DropStrategy.WaitingQueue);
1574 % Transfer LJCD (Limited Joint Class Dependence) scaling
for stations
1575 % This must be done after
classes are created since LJCD
is indexed per-class
1576 for n = 1:length(jnodes)
1577 if isempty(jnodes{n})
1580 if isa(line_nodes{n},
'Station') && ~isempty(line_nodes{n}.ljcdScaling) && ~isempty(line_nodes{n}.ljcdCutoffs)
1581 jCutoffs = JLINE.from_line_matrix(line_nodes{n}.ljcdCutoffs(:));
1582 K = length(line_nodes{n}.ljcdScaling);
1583 jScalingMap = java.util.HashMap();
1585 if ~isempty(line_nodes{n}.ljcdScaling{c})
1586 jScalingVec = JLINE.from_line_matrix(line_nodes{n}.ljcdScaling{c}(:));
1587 jScalingMap.put(jclasses{c}, jScalingVec);
1590 jnodes{n}.setLimitedJointClassDependence(jScalingMap, jCutoffs);
1594 % Set polling type and switchover times
for polling queues
1595 for n = 1: length(jnodes)
1596 if isempty(jnodes{n})
1599 if isa(line_nodes{n},
'Queue') && line_nodes{n}.schedStrategy == SchedStrategy.POLLING
1601 if ~isempty(line_nodes{n}.pollingType) && ~isempty(line_nodes{n}.pollingType{1})
1602 pollingType = line_nodes{n}.pollingType{1};
1604 case PollingType.GATED
1605 jPollingType = jline.lang.constant.PollingType.GATED;
1606 case PollingType.EXHAUSTIVE
1607 jPollingType = jline.lang.constant.PollingType.EXHAUSTIVE;
1608 case PollingType.KLIMITED
1609 jPollingType = jline.lang.constant.PollingType.KLIMITED;
1611 if pollingType == PollingType.KLIMITED && ~isempty(line_nodes{n}.pollingPar)
1612 jnodes{n}.setPollingType(jPollingType, int32(line_nodes{n}.pollingPar));
1614 jnodes{n}.setPollingType(jPollingType);
1617 % Set switchover times
1618 if ~isempty(line_nodes{n}.switchoverTime)
1619 for r = 1:length(line_classes)
1620 if length(line_nodes{n}.switchoverTime) >= r && ~isempty(line_nodes{n}.switchoverTime{r})
1621 soTime = line_nodes{n}.switchoverTime{r};
1622 if ~isa(soTime,
'Immediate')
1623 jnodes{n}.setSwitchover(jclasses{r}, JLINE.from_line_distribution(soTime));
1631 for n = 1: length(jnodes)
1632 if isempty(jnodes{n})
1633 continue; % Skip
nodes that were not converted
1635 if isa(line_nodes{n},
"ClassSwitch") && ~line_nodes{n}.autoAdded
1636 % Only set csMatrix
for user-defined ClassSwitch
nodes (not auto-added)
1637 JLINE.set_csMatrix(line_nodes{n}, jnodes{n}, jclasses);
1638 elseif isa(line_nodes{n},
"Join")
1639 jnodes{n}.initJoinJobClasses();
1640 % Restore RAND routing
for all
classes, matching ClosedClass/OpenClass
1641 % constructor behavior (initJoinJobClasses sets DISABLED by
default)
1642 for r = 1 : sn.nclasses
1643 jnodes{n}.setRouting(jclasses{r}, jline.lang.constant.RoutingStrategy.RAND);
1645 elseif isa(line_nodes{n},
"Cache")
1646 for r = 1 : sn.nclasses
1647 if length(line_nodes{n}.server.hitClass) >= r && ~isempty(line_nodes{n}.server.hitClass(r))
1648 if ~isa(line_nodes{n}.popularity{r},
'Disabled')
1649 jnodes{n}.setRead(jclasses{r}, JLINE.from_line_distribution(line_nodes{n}.popularity{r}));
1650 jnodes{n}.setHitClass(jclasses{r}, jclasses{line_nodes{n}.server.hitClass(r)});
1651 jnodes{n}.setMissClass(jclasses{r}, jclasses{line_nodes{n}.server.missClass(r)});
1655 % Transfer accessProb from MATLAB to Java
1656 if ~isempty(line_nodes{n}.accessProb)
1657 accessProbMat = line_nodes{n}.accessProb;
1658 [K1, K2] = size(accessProbMat);
1659 jAccessProb = javaArray(
'jline.util.matrix.Matrix', K1, K2);
1662 if ~isempty(accessProbMat{k1, k2})
1663 jAccessProb(k1, k2) = JLINE.from_line_matrix(accessProbMat{k1, k2});
1667 jnodes{n}.setAccessProb(jAccessProb);
1669 elseif isa(line_nodes{n},
"Transition")
1670 % First, add modes (must be done after
classes are created)
1671 for m = 1:line_nodes{n}.getNumberOfModes()
1672 modeName = line_nodes{n}.modeNames{m};
1673 jmode = jnodes{n}.addMode(modeName);
1674 % Set timing strategy
1675 switch line_nodes{n}.timingStrategies(m)
1676 case TimingStrategy.TIMED
1677 jnodes{n}.setTimingStrategy(jmode, jline.lang.constant.TimingStrategy.TIMED);
1678 case TimingStrategy.IMMEDIATE
1679 jnodes{n}.setTimingStrategy(jmode, jline.lang.constant.TimingStrategy.IMMEDIATE);
1682 jnodes{n}.setDistribution(jmode, JLINE.from_line_distribution(line_nodes{n}.distributions{m}));
1683 % Set firing weights and priorities
1684 jnodes{n}.setFiringWeights(jmode, line_nodes{n}.firingWeights(m));
1685 jnodes{n}.setFiringPriorities(jmode, int32(line_nodes{n}.firingPriorities(m)));
1686 % Set number of servers
1687 jnodes{n}.setNumberOfServers(jmode, java.lang.Integer(line_nodes{n}.numberOfServers(m)));
1689 % Now set enabling conditions, inhibiting conditions, and firing outcomes
1690 jmodes = jnodes{n}.getModes();
1691 for m = 1:line_nodes{n}.getNumberOfModes()
1692 jmode = jmodes.get(m-1);
1693 enabCond = line_nodes{n}.enablingConditions{m};
1694 inhibCond = line_nodes{n}.inhibitingConditions{m};
1695 firingOut = line_nodes{n}.firingOutcomes{m};
1696 for r = 1:sn.nclasses
1697 for i = 1:length(line_nodes)
1698 % Set enabling conditions
1699 if enabCond(i, r) > 0 && isa(line_nodes{i},
'Place')
1700 jnodes{n}.setEnablingConditions(jmode, jclasses{r}, jnodes{i}, enabCond(i, r));
1702 % Set inhibiting conditions
1703 if inhibCond(i, r) < Inf && isa(line_nodes{i},
'Place')
1704 jnodes{n}.setInhibitingConditions(jmode, jclasses{r}, jnodes{i}, inhibCond(i, r));
1706 % Set firing outcomes
1707 if firingOut(i, r) ~= 0
1708 jnodes{n}.setFiringOutcome(jmode, jclasses{r}, jnodes{i}, firingOut(i, r));
1716 % Assume JLINE and LINE network are both created via link
1717 JLINE.from_line_links(model, jnetwork);
1719 % Transfer finite capacity regions from MATLAB to Java
1720 if ~isempty(model.regions)
1721 for f = 1:length(model.regions)
1722 fcr = model.regions{f};
1723 % Convert MATLAB node list to Java list
1724 javaNodeList = java.util.ArrayList();
1725 for i = 1:length(fcr.nodes)
1726 matlabNode = fcr.
nodes{i};
1727 % Find corresponding Java node by name
1728 nodeName = matlabNode.getName();
1729 for j = 1:length(line_nodes)
1730 if strcmp(line_nodes{j}.getName(), nodeName) && ~isempty(jnodes{j})
1731 javaNodeList.add(jnodes{j});
1737 jfcr = jnetwork.addRegion(javaNodeList);
1738 % Set global max jobs
1739 if fcr.globalMaxJobs > 0 && ~isinf(fcr.globalMaxJobs)
1740 jfcr.setGlobalMaxJobs(fcr.globalMaxJobs);
1742 % Set per-class max jobs and drop rules
1743 for r = 1:length(line_classes)
1744 if length(fcr.classMaxJobs) >= r && fcr.classMaxJobs(r) > 0 && ~isinf(fcr.classMaxJobs(r))
1745 jfcr.setClassMaxJobs(jclasses{r}, fcr.classMaxJobs(r));
1747 if length(fcr.dropRule) >= r
1748 % Convert MATLAB DropStrategy numeric to Java DropStrategy
enum
1749 jDropStrategy = jline.lang.constant.DropStrategy.fromID(fcr.dropRule(r));
1750 jfcr.setDropRule(jclasses{r}, jDropStrategy);
1753 % Transfer linear constraints
if set
1754 if fcr.hasLinearConstraints()
1755 jA = JLINE.from_line_matrix(fcr.constraintA);
1756 jb = JLINE.from_line_matrix(fcr.constraintB);
1757 jfcr.setLinearConstraints(jA, jb);
1762 jnetwork.initDefault;
1763 for n = 1: length(line_nodes)
1764 if isempty(jnodes{n})
1765 continue; % Skip
nodes that were not converted
1767 if line_nodes{n}.isStateful
1768 jnodes{n}.setState(JLINE.from_line_matrix(line_nodes{n}.getState));
1769 jnodes{n}.setStateSpace(JLINE.from_line_matrix(line_nodes{n}.getStateSpace));
1770 jnodes{n}.setStatePrior(JLINE.from_line_matrix(line_nodes{n}.getStatePrior));
1773 % Force
struct refresh so sn.state reflects updated node states
1774 jnetwork.setHasStruct(
false);
1778 function jnetwork = line_to_jline(model)
1779 jnetwork = LINE2JLINE(model);
1782 function model = jline_to_line(jnetwork)
1783 if isa(jnetwork,
'JNetwork')
1784 jnetwork = jnetwork.obj;
1786 %javaaddpath(jar_loc);
1787 model = Network(
char(jnetwork.getName));
1788 network_nodes = jnetwork.getNodes;
1789 job_classes = jnetwork.getClasses;
1791 line_nodes = cell(network_nodes.size,1);
1792 line_classes = cell(job_classes.size,1);
1795 for n = 1 : network_nodes.size
1796 if ~isa(network_nodes.get(n-1), 'jline.lang.
nodes.ClassSwitch')
1797 line_nodes{n} = JLINE.from_jline_node(network_nodes.get(n-1), model, job_classes);
1801 for n = 1 : job_classes.size
1802 line_classes{n} = JLINE.from_jline_class(job_classes.get(n-1), model);
1805 for n = 1 : network_nodes.size
1806 if isa(network_nodes.get(n-1),
'jline.lang.nodes.ClassSwitch')
1807 line_nodes{n} = JLINE.from_jline_node(network_nodes.get(n-1), model, job_classes);
1811 % Deferred Fork/Join linking: set joinOf on Join
nodes
1812 for n = 1 : network_nodes.size
1813 jnode = network_nodes.get(n-1);
1814 if isa(jnode,
'jline.lang.nodes.Join') && ~isempty(jnode.joinOf)
1815 forkName =
char(jnode.joinOf.getName);
1816 for m = 1 : network_nodes.size
1817 if ~isempty(line_nodes{m}) && isa(line_nodes{m},
'Fork') && strcmp(line_nodes{m}.name, forkName)
1818 line_nodes{n}.joinOf = line_nodes{m};
1825 % Deferred Cache setup: set hitClass, missClass, popularity
1826 for n = 1 : network_nodes.size
1827 jnode = network_nodes.get(n-1);
1828 if isa(jnode,
'jline.lang.nodes.Cache') && isa(line_nodes{n},
'Cache')
1829 cacheNode = line_nodes{n};
1830 % hitClass and missClass are stored as index vectors
1831 hitClassVec = JLINE.from_jline_matrix(jnode.getHitClass());
1832 missClassVec = JLINE.from_jline_matrix(jnode.getMissClass());
1833 for r = 1:job_classes.size
1834 hitIdx = hitClassVec(r);
1835 if hitIdx >= 0 && (hitIdx + 1) <= job_classes.size
1836 cacheNode.setHitClass(line_classes{r}, line_classes{hitIdx + 1});
1838 missIdx = missClassVec(r);
1839 if missIdx >= 0 && (missIdx + 1) <= job_classes.size
1840 cacheNode.setMissClass(line_classes{r}, line_classes{missIdx + 1});
1843 % Popularity distributions
1844 for r = 1:job_classes.size
1846 popDist = jnode.popularityGet(0, r-1);
1847 if ~isempty(popDist) && popDist.isDiscrete()
1848 matlabDist = JLINE.from_jline_distribution(popDist);
1849 if ~isempty(matlabDist)
1850 cacheNode.setRead(line_classes{r}, matlabDist);
1854 % No popularity
for this class
1860 for n = 1 : network_nodes.size
1861 JLINE.set_line_service(network_nodes.get(n-1), line_nodes{n}, job_classes, line_classes);
1864 % Check
for state-dependent routing (RROBIN, WRROBIN, JSQ)
1865 % These cannot go through link(
P) because it overrides routing strategies
1866 hasSDRouting = false;
1867 for n = 1 : network_nodes.size
1868 jnode = network_nodes.get(n-1);
1869 output_strategies = jnode.getOutputStrategies();
1870 for m = 1 : output_strategies.size()
1871 rs = char(output_strategies.get(m-1).getRoutingStrategy);
1872 if any(strcmp(rs, {
'RROBIN',
'WRROBIN',
'JSQ',
'KCHOICES'}))
1873 hasSDRouting = true;
1877 if hasSDRouting; break; end
1881 % State-dependent routing: use addLink + setRouting
1882 model = JLINE.from_jline_routing(model, jnetwork);
1883 elseif ~isempty(jnetwork.getStruct.rtorig)
1885 model = JLINE.from_jline_links(model, jnetwork);
1887 % Do not use link() method
1888 model = JLINE.from_jline_routing(model, jnetwork);
1892 function matrix = arraylist_to_matrix(jline_matrix)
1893 if isempty(jline_matrix)
1896 matrix = zeros(jline_matrix.size(), 1);
1897 for row = 1:jline_matrix.size()
1898 matrix(row, 1) = jline_matrix.get(row-1);
1903 function matrix = from_jline_matrix(jline_matrix)
1904 if isempty(jline_matrix)
1907 matrix = zeros(jline_matrix.getNumRows(), jline_matrix.getNumCols());
1908 for row = 1:jline_matrix.getNumRows()
1909 for col = 1:jline_matrix.getNumCols()
1910 val = jline_matrix.get(row-1, col-1);
1911 if (val >= 33333333 && val <= 33333334)
1912 matrix(row, col) = GlobalConstants.Immediate;
1913 elseif (val >= -33333334 && val <= -33333333)
1914 matrix(row, col) = -GlobalConstants.Immediate;
1915 elseif (val >= 2147483647 - 1) % Integer.MAX_VALUE with -1 tolerance
1916 matrix(row, col) = Inf;
1917 elseif (val <= -2147483648 + 1) % Integer.MIN_VALUE with +1 tolerance
1918 matrix(row, col) = -Inf;
1920 matrix(row, col) = val;
1927 function jline_matrix = from_line_matrix(matrix)
1928 [rows, cols] = size(matrix);
1929 jline_matrix = jline.util.matrix.Matrix(rows, cols);
1932 if matrix(row,col) ~= 0
1933 jline_matrix.set(row-1, col-1, matrix(row, col));
1939 function lsn = from_jline_struct_layered(jlayerednetwork, jlsn)
1940 lsn = LayeredNetworkStruct();
1941 lsn.nidx= jlsn.nidx;
1942 lsn.nhosts= jlsn.nhosts;
1943 lsn.ntasks= jlsn.ntasks;
1944 lsn.nentries= jlsn.nentries;
1945 lsn.nacts= jlsn.nacts;
1946 lsn.ncalls= jlsn.ncalls;
1947 lsn.hshift= jlsn.hshift;
1948 lsn.tshift= jlsn.tshift;
1949 lsn.eshift= jlsn.eshift;
1950 lsn.ashift= jlsn.ashift;
1951 lsn.cshift= jlsn.cshift;
1953 lsn.tasksof{h,1} = JLINE.arraylist_to_matrix(jlsn.tasksof.get(uint32(h)))
';
1956 lsn.entriesof{lsn.tshift+t,1} = JLINE.arraylist_to_matrix(jlsn.entriesof.get(uint32(jlsn.tshift+t)))';
1958 for t=1:(jlsn.ntasks+jlsn.nentries)
1959 lsn.actsof{lsn.tshift+t,1} = JLINE.arraylist_to_matrix(jlsn.actsof.get(uint32(jlsn.tshift+t)))';
1962 lsn.callsof{lsn.ashift+a,1} = JLINE.arraylist_to_matrix(jlsn.callsof.get(uint32(jlsn.ashift+a)))';
1964 for i = 1:jlsn.sched.size
1965 lsn.sched(i,1) = SchedStrategy.(char(jlsn.sched.get(uint32(i))));
1967 for i = 1:jlsn.names.size
1968 lsn.names{i,1} = jlsn.names.get(uint32(i));
1969 lsn.hashnames{i,1} = jlsn.hashnames.get(uint32(i));
1971 lsn.mult = JLINE.from_jline_matrix(jlsn.mult);
1972 lsn.mult = lsn.mult(2:(lsn.eshift+1))
'; % remove 0-padding
1973 lsn.maxmult = JLINE.from_jline_matrix(jlsn.maxmult);
1974 lsn.maxmult = lsn.maxmult(2:(lsn.eshift+1))'; % remove 0-padding
1976 lsn.repl = JLINE.from_jline_matrix(jlsn.repl)';
1977 lsn.repl = lsn.repl(2:end); % remove 0-padding
1978 lsn.type = JLINE.from_jline_matrix(jlsn.type)';
1979 lsn.type = lsn.type(2:end); % remove 0-padding
1980 lsn.parent = JLINE.from_jline_matrix(jlsn.parent);
1981 lsn.parent = lsn.parent(2:end); % remove 0-padding
1982 lsn.nitems = JLINE.from_jline_matrix(jlsn.nitems);
1983 % Ensure proper column vector format matching MATLAB
's (nhosts+ntasks+nentries) x 1
1984 if isrow(lsn.nitems)
1985 lsn.nitems = lsn.nitems(2:end)'; % remove 0-padding and transpose
1987 lsn.nitems = lsn.nitems(2:end); % remove 0-padding (already column)
1989 % Ensure correct size
1990 expectedSize = lsn.nhosts + lsn.ntasks + lsn.nentries;
1991 if length(lsn.nitems) < expectedSize
1992 lsn.nitems(expectedSize,1) = 0;
1993 elseif length(lsn.nitems) > expectedSize
1994 lsn.nitems = lsn.nitems(1:expectedSize);
1996 lsn.replacestrat = JLINE.from_jline_matrix(jlsn.replacestrat);
1997 lsn.replacestrat = lsn.replacestrat(2:end)
'; % remove 0-padding
1998 for i = 1:jlsn.callnames.size
1999 lsn.callnames{i,1} = jlsn.callnames.get(uint32(i));
2000 lsn.callhashnames{i,1} = jlsn.callhashnames.get(uint32(i));
2002 for i = 1:jlsn.calltype.size % calltype may be made into a matrix in Java
2003 ct = char(jlsn.calltype.get(uint32(i)));
2004 lsn.calltype(i) = CallType.(ct);
2006 lsn.calltype = sparse(lsn.calltype'); % remove 0-padding
2007 lsn.callpair = JLINE.from_jline_matrix(jlsn.callpair);
2008 lsn.callpair = lsn.callpair(2:end,2:end); % remove 0-paddings
2009 if isempty(lsn.callpair)
2012 lsn.actpretype = sparse(JLINE.from_jline_matrix(jlsn.actpretype)
');
2013 lsn.actpretype = lsn.actpretype(2:end); % remove 0-padding
2014 lsn.actposttype = sparse(JLINE.from_jline_matrix(jlsn.actposttype)');
2015 lsn.actposttype = lsn.actposttype(2:end); % remove 0-padding
2016 lsn.graph = JLINE.from_jline_matrix(jlsn.graph);
2017 lsn.graph = lsn.graph(2:end,2:end); % remove 0-paddings
2018 lsn.dag = JLINE.from_jline_matrix(jlsn.dag);
2019 lsn.dag = lsn.dag(2:end,2:end); % remove 0-paddings
2020 lsn.taskgraph = JLINE.from_jline_matrix(jlsn.taskgraph);
2021 lsn.taskgraph = sparse(lsn.taskgraph(2:end,2:end)); % remove 0-paddings
2022 lsn.replygraph = JLINE.from_jline_matrix(jlsn.replygraph);
2023 lsn.replygraph = logical(lsn.replygraph(2:end,2:end)); % remove 0-paddings
2024 lsn.iscache = JLINE.from_jline_matrix(jlsn.iscache);
2025 % Ensure proper column vector format matching MATLAB
's (nhosts+ntasks) x 1
2026 expectedCacheSize = lsn.nhosts + lsn.ntasks;
2027 if isrow(lsn.iscache)
2028 if length(lsn.iscache) > expectedCacheSize
2029 lsn.iscache = lsn.iscache(2:(expectedCacheSize+1))'; % remove 0-padding and transpose
2031 lsn.iscache = lsn.iscache'; % just transpose
2034 % Ensure correct size
2035 if length(lsn.iscache) < expectedCacheSize
2036 lsn.iscache(expectedCacheSize,1) = 0;
2037 elseif length(lsn.iscache) > expectedCacheSize
2038 lsn.iscache = lsn.iscache(1:expectedCacheSize);
2040 lsn.iscaller = JLINE.from_jline_matrix(jlsn.iscaller);
2041 lsn.iscaller = full(lsn.iscaller(2:end,2:end)); % remove 0-paddings
2042 lsn.issynccaller = JLINE.from_jline_matrix(jlsn.issynccaller);
2043 lsn.issynccaller = full(lsn.issynccaller(2:end,2:end)); % remove 0-paddings
2044 lsn.isasynccaller = JLINE.from_jline_matrix(jlsn.isasynccaller);
2045 lsn.isasynccaller = full(lsn.isasynccaller(2:end,2:end)); % remove 0-paddings
2046 lsn.isref = JLINE.from_jline_matrix(jlsn.isref);
2047 lsn.isref = lsn.isref(2:end)
'; % remove 0-paddings
2050 function sn = from_jline_struct(jnetwork, jsn)
2051 %lst and rtfun are not implemented
2052 %Due to the transformation of Java lambda to matlab function
2054 jsn = jnetwork.getStruct(false);
2056 jclasses = jnetwork.getClasses();
2057 jnodes = jnetwork.getNodes();
2058 jstateful = jnetwork.getStatefulNodes();
2059 jstations = jnetwork.getStations();
2060 sn = NetworkStruct();
2062 sn.nnodes = jsn.nnodes;
2063 sn.nclasses = jsn.nclasses;
2064 sn.nclosedjobs = jsn.nclosedjobs;
2065 sn.nstations = jsn.nstations;
2066 sn.nstateful = jsn.nstateful;
2067 sn.nchains = jsn.nchains;
2069 sn.refstat = JLINE.from_jline_matrix(jsn.refstat) + 1;
2070 sn.njobs = JLINE.from_jline_matrix(jsn.njobs);
2071 sn.nservers = JLINE.from_jline_matrix(jsn.nservers);
2072 sn.connmatrix = JLINE.from_jline_matrix(jsn.connmatrix);
2073 % Fix for Java getConnectionMatrix bug: ensure connmatrix is nnodes x nnodes
2074 if size(sn.connmatrix,1) < sn.nnodes
2075 sn.connmatrix(sn.nnodes,1) = 0;
2077 if size(sn.connmatrix,2) < sn.nnodes
2078 sn.connmatrix(1,sn.nnodes) = 0;
2080 sn.scv = JLINE.from_jline_matrix(jsn.scv);
2081 sn.isstation = logical(JLINE.from_jline_matrix(jsn.isstation));
2082 sn.isstateful = logical(JLINE.from_jline_matrix(jsn.isstateful));
2083 sn.isstatedep = logical(JLINE.from_jline_matrix(jsn.isstatedep));
2084 sn.nodeToStateful = JLINE.from_jline_matrix(jsn.nodeToStateful)+1;
2085 sn.nodeToStateful(sn.nodeToStateful==0) = nan;
2086 sn.nodeToStation = JLINE.from_jline_matrix(jsn.nodeToStation)+1;
2087 sn.nodeToStation(sn.nodeToStation==0) = nan;
2088 sn.stationToNode = JLINE.from_jline_matrix(jsn.stationToNode)+1;
2089 sn.stationToNode(sn.stationToNode==0) = nan;
2090 sn.stationToStateful = JLINE.from_jline_matrix(jsn.stationToStateful)+1;
2091 sn.stationToStateful(sn.stationToStateful==0) = nan;
2092 sn.statefulToStation = JLINE.from_jline_matrix(jsn.statefulToStation)+1;
2093 sn.statefulToStation(sn.statefulToStation==0) = nan;
2094 sn.statefulToNode = JLINE.from_jline_matrix(jsn.statefulToNode)+1;
2095 sn.statefulToNode(sn.statefulToNode==0) = nan;
2096 sn.rates = JLINE.from_jline_matrix(jsn.rates);
2097 sn.fj = JLINE.from_jline_matrix(jsn.fj);
2098 sn.classprio = JLINE.from_jline_matrix(jsn.classprio);
2099 sn.phases = JLINE.from_jline_matrix(jsn.phases);
2100 sn.phasessz = JLINE.from_jline_matrix(jsn.phasessz);
2101 sn.phaseshift = JLINE.from_jline_matrix(jsn.phaseshift);
2102 sn.schedparam = JLINE.from_jline_matrix(jsn.schedparam);
2103 sn.chains = logical(JLINE.from_jline_matrix(jsn.chains));
2104 sn.rt = JLINE.from_jline_matrix(jsn.rt);
2105 sn.nvars = JLINE.from_jline_matrix(jsn.nvars);
2106 sn.rtnodes = JLINE.from_jline_matrix(jsn.rtnodes);
2107 sn.csmask = logical(JLINE.from_jline_matrix(jsn.csmask));
2108 sn.isslc = logical(JLINE.from_jline_matrix(jsn.isslc));
2109 sn.cap = JLINE.from_jline_matrix(jsn.cap);
2110 sn.classcap = JLINE.from_jline_matrix(jsn.classcap);
2111 sn.refclass = JLINE.from_jline_matrix(jsn.refclass)+1;
2112 sn.lldscaling = JLINE.from_jline_matrix(jsn.lldscaling);
2114 if ~isempty(jsn.cdscaling) && jsn.cdscaling.size() > 0
2115 % Convert Java SerializableFunction to MATLAB function handles
2116 sn.cdscaling = cell(sn.nstations, 1);
2117 % Iterate through the map entries to handle null values properly
2118 entrySet = jsn.cdscaling.entrySet();
2119 entryIter = entrySet.iterator();
2120 stationFunMap = containers.Map();
2121 while entryIter.hasNext()
2122 entry = entryIter.next();
2123 stationName = char(entry.getKey().getName());
2125 jfun = entry.getValue();
2127 stationFunMap(stationName) = jfun;
2130 % getValue() returns null for default lambda functions
2131 % Skip and use default value
2134 % Assign functions to stations
2135 for i = 1:sn.nstations
2136 jstation = jstations.get(i-1);
2137 stationName = char(jstation.getName());
2138 if isKey(stationFunMap, stationName)
2139 jfun = stationFunMap(stationName);
2140 % Create a MATLAB function handle that calls the Java apply() method
2141 sn.cdscaling{i} = @(ni) JLINE.call_java_cdscaling(jfun, ni);
2143 sn.cdscaling{i} = @(ni) 1;
2147 sn.cdscaling = cell(sn.nstations, 0);
2150 if ~isempty(jsn.nodetype)
2151 sn.nodetype = zeros(sn.nnodes, 1);
2152 for i = 1:jsn.nodetype.size
2153 nodetype = jsn.nodetype.get(i-1);
2154 switch nodetype.name().toCharArray'
2156 sn.nodetype(i) = NodeType.Queue;
2158 sn.nodetype(i) = NodeType.Delay;
2160 sn.nodetype(i) = NodeType.Source;
2162 sn.nodetype(i) = NodeType.Sink;
2164 sn.nodetype(i) = NodeType.Join;
2166 sn.nodetype(i) = NodeType.Fork;
2168 sn.nodetype(i) = NodeType.ClassSwitch;
2170 sn.nodetype(i) = NodeType.Logger;
2172 sn.nodetype(i) = NodeType.Cache;
2174 sn.nodetype(i) = NodeType.Place;
2176 sn.nodetype(i) = NodeType.Transition;
2178 sn.nodetype(i) = NodeType.Router;
2185 if ~isempty(jsn.classnames)
2186 for i = 1:jsn.classnames.size
2187 sn.classnames(i,1) = jsn.classnames.get(i-1);
2193 if ~isempty(jsn.nodenames)
2194 for i = 1:jsn.nodenames.size
2195 sn.nodenames(i,1) = jsn.nodenames.get(i-1);
2201 if ~isempty(jsn.rtorig) && jsn.rtorig.size()>0
2202 sn.rtorig = cell(sn.nclasses, sn.nclasses);
2203 for r = 1:sn.nclasses
2204 for s = 1:sn.nclasses
2205 sn.rtorig{r,s} = JLINE.from_jline_matrix(jsn.rtorig.get(jclasses.get(r-1)).get(jclasses.get(s-1)));
2212 if ~isempty(jsn.state)
2213 sn.state = cell(sn.nstateful, 1);
2214 for i = 1:sn.nstateful
2215 sn.state{i} = JLINE.from_jline_matrix(jstateful.get(i-1).getState());
2221 if ~isempty(jsn.stateprior)
2222 sn.stateprior = cell(sn.nstateful, 1);
2223 for i = 1:sn.nstateful
2224 sn.stateprior{i} = JLINE.from_jline_matrix(jstateful.get(i-1).getStatePrior());
2230 if ~isempty(jsn.space)
2231 sn.space = cell(sn.nstateful, 1);
2232 for i = 1:sn.nstateful
2233 sn.space{i} = JLINE.from_jline_matrix(jstateful.get(i-1).getStateSpace());
2239 if ~isempty(jsn.routing)
2240 sn.routing = zeros(sn.nnodes, sn.nclasses);
2242 for j = 1:sn.nclasses
2243 routingStrategy = jsn.routing.get(jnodes.get(i-1)).get(jclasses.get(j-1));
2244 switch routingStrategy.name().toCharArray'
2246 sn.routing(i,j) = RoutingStrategy.PROB;
2248 sn.routing(i,j) = RoutingStrategy.RAND;
2250 sn.routing(i,j) = RoutingStrategy.RROBIN;
2252 sn.routing(i,j) = RoutingStrategy.WRROBIN;
2254 sn.routing(i,j) = RoutingStrategy.JSQ;
2256 sn.routing(i,j) = RoutingStrategy.DISABLED;
2258 sn.routing(i,j) = RoutingStrategy.FIRING;
2260 sn.routing(i,j) = RoutingStrategy.KCHOICES;
2268 if ~isempty(jsn.procid)
2269 sn.procid = nan(sn.nstations, sn.nclasses); % Initialize with NaN to match MATLAB behavior
2270 for i = 1:sn.nstations
2271 for j = 1:sn.nclasses
2272 stationMap = jsn.procid.get(jstations.get(i-1));
2273 if isempty(stationMap)
2274 sn.procid(i,j) = ProcessType.DISABLED;
2277 processType = stationMap.get(jclasses.get(j-1));
2278 if isempty(processType)
2279 sn.procid(i,j) = ProcessType.DISABLED;
2282 switch processType.name.toCharArray'
2284 sn.procid(i,j) = ProcessType.EXP;
2286 sn.procid(i,j) = ProcessType.ERLANG;
2288 sn.procid(i,j) = ProcessType.HYPEREXP;
2290 sn.procid(i,j) = ProcessType.PH;
2292 sn.procid(i,j) = ProcessType.APH;
2294 sn.procid(i,j) = ProcessType.MAP;
2296 sn.procid(i,j) = ProcessType.UNIFORM;
2298 sn.procid(i,j) = ProcessType.DET;
2300 sn.procid(i,j) = ProcessType.COXIAN;
2302 sn.procid(i,j) = ProcessType.GAMMA;
2304 sn.procid(i,j) = ProcessType.PARETO;
2306 sn.procid(i,j) = ProcessType.WEIBULL;
2308 sn.procid(i,j) = ProcessType.LOGNORMAL;
2310 sn.procid(i,j) = ProcessType.MMPP2;
2312 sn.procid(i,j) = ProcessType.REPLAYER;
2314 sn.procid(i,j) = ProcessType.TRACE;
2316 sn.procid(i,j) = ProcessType.IMMEDIATE;
2318 sn.procid(i,j) = ProcessType.DISABLED;
2320 sn.procid(i,j) = ProcessType.COX2;
2322 sn.procid(i,j) = ProcessType.BMAP;
2324 sn.procid(i,j) = ProcessType.ME;
2326 sn.procid(i,j) = ProcessType.RAP;
2328 sn.procid(i,j) = ProcessType.BINOMIAL;
2330 sn.procid(i,j) = ProcessType.POISSON;
2332 sn.procid(i,j) = ProcessType.GEOMETRIC;
2334 sn.procid(i,j) = ProcessType.DUNIFORM;
2336 sn.procid(i,j) = ProcessType.BERNOULLI;
2338 sn.procid(i,j) = ProcessType.PRIOR;
2340 % Unknown ProcessType - default to DISABLED
2341 sn.procid(i,j) = ProcessType.DISABLED;
2350 sn.mu = cell(sn.nstations, 1);
2351 for i = 1:sn.nstations
2352 sn.mu{i} = cell(1, sn.nclasses);
2353 for j = 1:sn.nclasses
2354 sn.mu{i}{j} = JLINE.from_jline_matrix(jsn.mu.get(jstations.get(i-1)).get(jclasses.get(j-1)));
2361 if ~isempty(jsn.phi)
2362 sn.phi = cell(sn.nstations, 1);
2363 for i = 1:sn.nstations
2364 sn.phi{i} = cell(1, sn.nclasses);
2365 for j = 1:sn.nclasses
2366 sn.phi{i}{j} = JLINE.from_jline_matrix(jsn.phi.get(jstations.get(i-1)).get(jclasses.get(j-1)));
2373 if ~isempty(jsn.proc)
2374 sn.proc = cell(sn.nstations, 1);
2375 for i = 1:sn.nstations
2376 sn.proc{i} = cell(1, sn.nclasses);
2377 for j = 1:sn.nclasses
2378 proc_i_j = jsn.proc.get(jstations.get(i-1)).get(jclasses.get(j-1));
2379 sn.proc{i}{j} = cell(1, proc_i_j.size);
2380 for k = 1:proc_i_j.size
2381 sn.proc{i}{j}{k} = JLINE.from_jline_matrix(proc_i_j.get(uint32(k-1)));
2389 if ~isempty(jsn.pie)
2390 sn.pie = cell(sn.nstations, 1);
2391 for i = 1:sn.nstations
2392 sn.pie{i} = cell(1, sn.nclasses);
2393 for j = 1:sn.nclasses
2394 sn.pie{i}{j} = JLINE.from_jline_matrix(jsn.pie.get(jstations.get(i-1)).get(jclasses.get(j-1)));
2401 if ~isempty(jsn.sched)
2402 sn.sched = zeros(sn.nstations, 1);
2403 for i = 1:sn.nstations
2404 schedStrategy = jsn.sched.get(jstations.get(i-1));
2405 switch schedStrategy.name.toCharArray'
2407 sn.sched(i) = SchedStrategy.INF;
2409 sn.sched(i) = SchedStrategy.FCFS;
2411 sn.sched(i) = SchedStrategy.LCFS;
2413 sn.sched(i) = SchedStrategy.LCFSPR;
2415 sn.sched(i) = SchedStrategy.SIRO;
2417 sn.sched(i) = SchedStrategy.SJF;
2419 sn.sched(i) = SchedStrategy.LJF;
2421 sn.sched(i) = SchedStrategy.PS;
2423 sn.sched(i) = SchedStrategy.DPS;
2425 sn.sched(i) = SchedStrategy.GPS;
2427 sn.sched(i) = SchedStrategy.PSPRIO;
2429 sn.sched(i) = SchedStrategy.DPSPRIO;
2431 sn.sched(i) = SchedStrategy.GPSPRIO;
2433 sn.sched(i) = SchedStrategy.SEPT;
2435 sn.sched(i) = SchedStrategy.LEPT;
2436 case {
'HOL',
'FCFSPRIO'}
2437 sn.sched(i) = SchedStrategy.FCFSPRIO;
2439 sn.sched(i) = SchedStrategy.FORK;
2441 sn.sched(i) = SchedStrategy.EXT;
2443 sn.sched(i) = SchedStrategy.REF;
2450 if ~isempty(jsn.inchain)
2451 sn.inchain = cell(1, sn.nchains);
2452 for i = 1:sn.nchains
2453 sn.inchain{1,i} = JLINE.from_jline_matrix(jsn.inchain.get(uint32(i-1)))+1;
2459 if ~isempty(jsn.visits)
2460 sn.
visits = cell(sn.nchains, 1);
2461 for i = 1:sn.nchains
2462 sn.
visits{i,1} = JLINE.from_jline_matrix(jsn.visits.get(uint32(i-1)));
2468 if ~isempty(jsn.nodevisits)
2470 for i = 1:sn.nchains
2471 sn.
nodevisits{1,i} = JLINE.from_jline_matrix(jsn.nodevisits.get(uint32(i-1)));
2477 if ~isempty(jsn.droprule)
2478 sn.droprule = zeros(sn.nstations, sn.nclasses);
2479 for i = 1:sn.nstations
2480 for j = 1:sn.nclasses
2481 dropStrategy = jsn.droprule.get(jstations.get(i-1)).get(jclasses.get(j-1));
2482 switch dropStrategy.name.toCharArray'
2484 sn.droprule(i,j) = DropStrategy.WAITQ;
2486 sn.droprule(i,j) = DropStrategy.DROP;
2487 case 'BlockingAfterService'
2488 sn.droprule(i,j) = DropStrategy.BAS;
2496 if ~isempty(jsn.nodeparam)
2497 sn.nodeparam = cell(sn.nnodes, 1);
2500 jnode = jnodes.get(i-1);
2501 jparam = jsn.nodeparam.get(jnode);
2504 % sn.nodeparam{i} = [];
2509 if isa(jparam,
'jline.lang.nodeparam.StationNodeParam')
2510 if ~isempty(jparam.fileName)
2511 sn.nodeparam{i}.fileName = cell(1, sn.nclasses);
2512 for r = 1:sn.nclasses
2513 fname = jparam.fileName.get(r-1);
2515 sn.nodeparam{i}.fileName{r} = char(fname);
2521 % TransitionNodeParam
2522 if isa(jparam,
'jline.lang.nodeparam.TransitionNodeParam')
2523 if ~isempty(jparam.firingprocid)
2524 sn.nodeparam{i}.firingprocid = containers.Map(
'KeyType',
'char',
'ValueType',
'any');
2525 keys = jparam.firingprocid.keySet.iterator;
2528 proc = jparam.firingprocid.get(key);
2529 sn.nodeparam{i}.firingprocid(
char(key.toString)) = char(proc.toString);
2532 if ~isempty(jparam.firingphases)
2533 sn.nodeparam{i}.firingphases = JLINE.from_jline_matrix(jparam.firingphases);
2535 if ~isempty(jparam.fireweight)
2536 sn.nodeparam{i}.fireweight = JLINE.from_jline_matrix(jparam.fireweight);
2541 if isa(jparam,
'jline.lang.nodeparam.JoinNodeParam')
2542 if ~isempty(jparam.joinStrategy)
2543 sn.nodeparam{i}.joinStrategy = cell(1, sn.nclasses);
2544 sn.nodeparam{i}.fanIn = cell(1, sn.nclasses);
2545 for r = 1:sn.nclasses
2546 jclass = jclasses.get(r-1);
2547 joinStrategy = jparam.joinStrategy.get(jclass);
2548 if ~isempty(joinStrategy)
2549 strategyStr = char(joinStrategy.name.toString);
2552 sn.nodeparam{i}.joinStrategy{r} = JoinStrategy.STD;
2554 sn.nodeparam{i}.joinStrategy{r} = JoinStrategy.PARTIAL;
2556 sn.nodeparam{i}.joinStrategy{r} = strategyStr;
2558 sn.nodeparam{i}.fanIn{r} = jparam.fanIn.get(jclass);
2565 if isa(jparam,
'jline.lang.nodeparam.RoutingNodeParam')
2566 for r = 1:sn.nclasses
2567 jclass = jclasses.get(r-1);
2569 if ~isempty(jparam.weights) && jparam.weights.containsKey(jclass)
2570 sn.nodeparam{i}.weights{r} = JLINE.from_jline_matrix(jparam.weights.get(jclass));
2573 if ~isempty(jparam.outlinks) && jparam.outlinks.containsKey(jclass)
2574 sn.nodeparam{i}.outlinks{r} = JLINE.from_jline_matrix(jparam.outlinks.get(jclass));
2580 if isa(jparam,
'jline.lang.nodeparam.ForkNodeParam')
2581 if ~isnan(jparam.fanOut)
2582 sn.nodeparam{i}.fanOut = jparam.fanOut;
2587 if isa(jparam,
'jline.lang.nodeparam.CacheNodeParam')
2589 if ~isnan(jparam.nitems)
2590 sn.nodeparam{i}.nitems = jparam.nitems;
2594 if ~isempty(jparam.accost)
2595 % For Java 2D arrays (Matrix[][]), size(arr,2) returns 1 in MATLAB
2596 % We need to get length of first row to get actual second dimension
2597 K1 = size(jparam.accost, 1);
2599 firstRow = jparam.accost(1); % Get first row (Java
array)
2600 K2 = length(firstRow);
2604 sn.nodeparam{i}.accost = cell(K1, K2);
2607 mat = jparam.accost(k1, k2); % MATLAB handles Java
array indexing
2609 sn.nodeparam{i}.accost{k1, k2} = JLINE.from_jline_matrix(mat);
2616 if ~isempty(jparam.itemcap)
2617 sn.nodeparam{i}.itemcap = JLINE.from_jline_matrix(jparam.itemcap);
2620 % pread - convert from Java Map<Integer, List<Double>> to MATLAB cell
array {R}
2621 if ~isempty(jparam.pread)
2622 nclasses = sn.nclasses;
2623 sn.nodeparam{i}.pread = cell(1, nclasses);
2625 list = jparam.pread.get(int32(r-1)); % Java 0-based indexing
2627 values = zeros(1, list.size);
2629 values(j) = list.get(j-1);
2631 sn.nodeparam{i}.pread{r} = values;
2633 sn.nodeparam{i}.pread{r} = NaN;
2639 if ~isempty(jparam.replacestrat)
2640 switch
char(jparam.replacestrat)
2642 sn.nodeparam{i}.replacestrat = ReplacementStrategy.RR;
2644 sn.nodeparam{i}.replacestrat = ReplacementStrategy.FIFO;
2646 sn.nodeparam{i}.replacestrat = ReplacementStrategy.SFIFO;
2648 sn.nodeparam{i}.replacestrat = ReplacementStrategy.LRU;
2653 if ~isempty(jparam.hitclass)
2654 sn.nodeparam{i}.hitclass = 1+JLINE.from_jline_matrix(jparam.hitclass);
2658 if ~isempty(jparam.missclass)
2659 sn.nodeparam{i}.missclass =1+ JLINE.from_jline_matrix(jparam.missclass);
2662 % actual hit/miss probabilities
2663 if ~isempty(jparam.actualhitprob)
2664 sn.nodeparam{i}.actualhitprob = JLINE.from_jline_matrix(jparam.actualhitprob);
2666 if ~isempty(jparam.actualmissprob)
2667 sn.nodeparam{i}.actualmissprob = JLINE.from_jline_matrix(jparam.actualmissprob);
2675 %
if ~isempty(jsn.nodeparam)
2676 % sn.nodeparam = cell(sn.nnodes, 1);
2677 % % Note that JLINE only support node parameters related to
2678 % % Fork, Join, WWROBIN and RROBIN
2679 %
for i = 1:sn.nnodes
2680 %
if jsn.nodeparam.get(jnodes.get(i-1)).isEmpty
2681 % sn.nodeparam{i} = [];
2683 %
if ~isnan(jsn.nodeparam.get(jnodes.get(i-1)).nitems)
2684 % sn.nodeparam{i}.nitems = jsn.nodeparam.get(jnodes.get(i-1)).nitems;
2686 %
if ~isnan(jsn.nodeparam.get(jnodes.get(i-1)).fanOut)
2687 % sn.nodeparam{i}.fanOut = jsn.nodeparam.get(jnodes.get(i-1)).fanOut;
2689 %
if ~isempty(jsn.nodeparam.get(jnodes.get(i-1)).joinStrategy)
2690 %
if ~jsn.nodeparam.get(jnodes.get(i-1)).joinStrategy.isEmpty
2691 % sn.nodeparam{i}.joinStrategy = cell(1, sn.nclasses);
2692 % sn.nodeparam{i}.fanIn = cell(1, sn.nclasses);
2693 %
for r = 1:sn.nclasses
2694 % joinStrategy = jsn.nodeparam.get(jnodes.get(i-1)).joinStrategy.get(jclasses.get(r-1));
2695 %
switch joinStrategy.name.toCharArray
'
2697 % sn.nodeparam{i}.joinStrategy{r} = JoinStrategy.STD;
2699 % sn.nodeparam{i}.joinStrategy{r} = JoinStrategy.PARTIAL;
2701 % sn.nodeparam{i}.fanIn{r} = jsn.nodeparam.get(jnodes.get(i-1)).fanIn.get(jclasses.get(r-1));
2706 % if ~isempty(jsn.nodeparam.get(jnodes.get(i-1)).weights)
2707 % for r = 1:sn.nclasses
2708 % sn.nodeparam{i}{r}.weights = JLINE.from_jline_matrix(jsn.nodeparam.get(jnodes.get(i-1)).weights.get(jclasses.get(r-1)));
2712 % if ~isempty(jsn.nodeparam.get(jnodes.get(i-1)).outlinks)
2713 % for r = 1:sn.nclasses
2714 % sn.nodeparam{i}{r}.outlinks = JLINE.from_jline_matrix(jsn.nodeparam.get(jnodes.get(i-1)).outlinks.get(jclasses.get(r-1)));
2720 % sn.nodeparam = {};
2723 if ~isempty(jsn.sync)
2725 sn.sync = cell(jsync.size, 1);
2726 for i = 1:jsync.size
2727 jsync_i = jsync.get(uint32(i-1));
2728 sn.sync{i,1} = struct('active
',cell(1),'passive
',cell(1));
2730 jactive = jsync_i.active.get(uint32(0));
2731 jpassive = jsync_i.passive.get(uint32(0));
2733 %Currently assume that prob would always be a value
2734 %instead of lambda function (No idea of how to convert
2735 %Java lambda function to matlab lambda function)
2736 switch jactive.getEvent.name.toCharArray'
2738 sn.sync{i,1}.active{1} = Event(EventType.INIT, jactive.getNode+1, jactive.getJobClass+1, ...
2739 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2740 jactive.getT, jactive.getJob);
2742 sn.sync{i,1}.active{1} = Event(EventType.LOCAL, jactive.getNode+1, jactive.getJobClass+1, ...
2743 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2744 jactive.getT, jactive.getJob);
2746 sn.sync{i,1}.active{1} = Event(EventType.ARV, jactive.getNode+1, jactive.getJobClass+1, ...
2747 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2748 jactive.getT, jactive.getJob);
2750 sn.sync{i,1}.active{1} = Event(EventType.DEP, jactive.getNode+1, jactive.getJobClass+1, ...
2751 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2752 jactive.getT, jactive.getJob);
2754 sn.sync{i,1}.active{1} = Event(EventType.PHASE, jactive.getNode+1, jactive.getJobClass+1, ...
2755 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2756 jactive.getT, jactive.getJob);
2758 sn.sync{i,1}.active{1} = Event(EventType.READ, jactive.getNode+1, jactive.getJobClass+1, ...
2759 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2760 jactive.getT, jactive.getJob);
2762 sn.sync{i,1}.active{1} = Event(EventType.STAGE, jactive.getNode+1, jactive.getJobClass+1, ...
2763 jactive.getProb, JLINE.from_jline_matrix(jactive.getState), ...
2764 jactive.getT, jactive.getJob);
2767 switch jpassive.getEvent.name.toCharArray
'
2769 sn.sync{i,1}.passive{1} = Event(EventType.INIT, jpassive.getNode+1, jpassive.getJobClass+1, ...
2770 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2771 jpassive.getT, jpassive.getJob);
2773 sn.sync{i,1}.passive{1} = Event(EventType.LOCAL, jpassive.getNode+1, jpassive.getJobClass+1, ...
2774 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2775 jpassive.getT, jpassive.getJob);
2777 sn.sync{i,1}.passive{1} = Event(EventType.ARV, jpassive.getNode+1, jpassive.getJobClass+1, ...
2778 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2779 jpassive.getT, jpassive.getJob);
2781 sn.sync{i,1}.passive{1} = Event(EventType.DEP, jpassive.getNode+1, jpassive.getJobClass+1, ...
2782 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2783 jpassive.getT, jpassive.getJob);
2785 sn.sync{i,1}.passive{1} = Event(EventType.PHASE, jpassive.getNode+1, jpassive.getJobClass+1, ...
2786 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2787 jpassive.getT, jpassive.getJob);
2789 sn.sync{i,1}.passive{1} = Event(EventType.READ, jpassive.getNode+1, jpassive.getJobClass+1, ...
2790 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2791 jpassive.getT, jpassive.getJob);
2793 sn.sync{i,1}.passive{1} = Event(EventType.STAGE, jpassive.getNode+1, jpassive.getJobClass+1, ...
2794 jpassive.getProb, JLINE.from_jline_matrix(jpassive.getState), ...
2795 jpassive.getT, jpassive.getJob);
2803 function [QN,UN,RN,WN,AN,TN] = arrayListToResults(alist)
2805 case 'jline.solvers.LayeredNetworkAvgTable
'
2806 QN = JLINE.arraylist_to_matrix(alist.getQLen());
2807 UN = JLINE.arraylist_to_matrix(alist.getUtil());
2808 RN = JLINE.arraylist_to_matrix(alist.getRespT());
2809 WN = JLINE.arraylist_to_matrix(alist.getResidT());
2810 AN = NaN*JLINE.arraylist_to_matrix(alist.getTput()); % getArvR not yet available in JLINE
2811 TN = JLINE.arraylist_to_matrix(alist.getTput());
2813 QN = JLINE.arraylist_to_matrix(alist.getQLen());
2814 UN = JLINE.arraylist_to_matrix(alist.getUtil());
2815 RN = JLINE.arraylist_to_matrix(alist.getRespT());
2816 WN = JLINE.arraylist_to_matrix(alist.getResidT());
2817 AN = JLINE.arraylist_to_matrix(alist.getArvR());
2818 TN = JLINE.arraylist_to_matrix(alist.getTput());
2822 function featSupported = getFeatureSet()
2823 % FEATSUPPORTED = GETFEATURESET()
2825 featSupported = SolverFeatureSet;
2826 featSupported.setTrue({'Sink
','Source
',...
2827 'ClassSwitch
','Delay
','DelayStation
','Queue
',...
2828 'APH
','Coxian
','Erlang
','Exp
','HyperExp
',...
2829 'StatelessClassSwitcher
','InfiniteServer
','SharedServer
','Buffer
','Dispatcher
',...
2830 'Server
','JobSink
','RandomSource
','ServiceTunnel
',...
2831 'SchedStrategy_INF
','SchedStrategy_PS
',...
2832 'RoutingStrategy_PROB
','RoutingStrategy_RAND
',...
2833 'ClosedClass
','OpenClass
'});
2836 function [bool, featSupported] = supports(model)
2837 % [BOOL, FEATSUPPORTED] = SUPPORTS(MODEL)
2839 featUsed = model.getUsedLangFeatures();
2840 featSupported = JLINE.getFeatureSet();
2841 bool = SolverFeatureSet.supports(featSupported, featUsed);
2845 function solverOptions = parseSolverOptions(solverOptions, options)
2846 fn = fieldnames(options);
2847 fn2 = fieldnames(solverOptions);
2848 for f = 1:length(fn)
2850 for j = 1:length(fn2)
2851 if strcmp(fn{f}, fn2{j})
2855 solverOptions.seed = options.seed;
2857 solverOptions.samples = options.samples;
2859 % Parse confint - can be a level (0.95) or 0 to disable
2860 [confintEnabled, confintLevel] = Solver.parseConfInt(options.confint);
2862 solverOptions.confint = confintLevel;
2864 solverOptions.confint = 0;
2867 solverOptions.method = options.method;
2869 if isfield(options.config,'eventcache
')
2870 solverOptions.config.eventcache = options.config.eventcache;
2872 if isfield(options.config,'fork_join
')
2873 solverOptions.config.fork_join = options.config.fork_join;
2875 if isfield(options.config,'highvar
')
2876 solverOptions.config.highvar = options.config.highvar;
2878 if isfield(options.config,'multiserver
')
2879 solverOptions.config.multiserver = options.config.multiserver;
2881 if isfield(options.config,'np_priority
')
2882 solverOptions.config.np_priority = options.config.np_priority;
2885 switch options.(fn{f})
2886 case {VerboseLevel.SILENT}
2887 solverOptions.verbose = solverOptions.verbose.SILENT;
2888 case {VerboseLevel.STD}
2889 solverOptions.verbose = solverOptions.verbose.STD;
2890 case {VerboseLevel.DEBUG}
2891 solverOptions.verbose = solverOptions.verbose.DEBUG;
2894 solverOptions.(fn{f}) = JLINE.from_line_matrix(options.init_sol);
2896 if isscalar(options.cutoff)
2897 solverOptions.(fn{f}) = jline.util.matrix.Matrix.singleton(options.cutoff);
2899 solverOptions.(fn{f}) = JLINE.from_line_matrix(options.cutoff);
2902 case 'rewardIterations
'
2903 solverOptions.rewardIterations = java.lang.Integer(options.rewardIterations);
2905 solverOptions.(fn{f}) = options.(fn{f});
2912 line_printf('Could not find option %s in the JLINE options.\n
', fn{f});
2917 function [ssa] = SolverSSA(network_object, options)
2918 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.SSA);
2920 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
2922 jline.util.Maths.setRandomNumbersMatlab(true);
2923 ssa = jline.solvers.ssa.SolverSSA(network_object, solverOptions);
2926 function [mam] = SolverMAM(network_object, options)
2927 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.MAM);
2929 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
2931 mam = jline.solvers.mam.SolverMAM(network_object, solverOptions);
2934 function [jmt] = SolverJMT(network_object, options)
2935 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.JMT);
2937 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
2939 jmt = jline.solvers.jmt.SolverJMT(network_object, solverOptions);
2942 function [ctmc] = SolverCTMC(network_object, options)
2943 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.CTMC);
2945 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
2947 ctmc = jline.solvers.ctmc.SolverCTMC(network_object,solverOptions);
2950 function [fluid] = SolverFluid(network_object, options)
2951 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.FLUID);
2953 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
2955 fluid = jline.solvers.fluid.SolverFluid(network_object, solverOptions);
2958 function [QN, UN, RN, TN, CN, XN, t, QNt, UNt, TNt, xvec] = runFluidAnalyzer(network, options)
2959 % RUNFLUIDANALYZER Run JLINE fluid analyzer and return results
2961 % [QN, UN, RN, TN, CN, XN, T, QNT, UNT, TNT, XVEC] = JLINE.runFluidAnalyzer(NETWORK, OPTIONS)
2963 % Runs the JLINE fluid solver on the given network and converts
2964 % results back to MATLAB data structures.
2967 % network - LINE Network model
2968 % options - Solver options structure with fields:
2969 % .method - solver method
2970 % .stiff - use stiff ODE solver
2973 % QN, UN, RN, TN - Steady-state metrics [M x K]
2974 % CN, XN - System metrics [1 x K]
2975 % t - Time vector [Tmax x 1]
2976 % QNt, UNt, TNt - Transient metrics {M x K} cells
2977 % xvec - State vector structure
2979 jmodel = LINE2JLINE(network);
2980 jsolver = JLINE.SolverFluid(jmodel);
2981 import jline.solvers.fluid.*;
2983 jsolver.options.method = options.method;
2984 jsolver.options.stiff = options.stiff;
2985 result = jsolver.runMethodSpecificAnalyzerViaLINE();
2987 % Convert JLINE result to MATLAB data structures
2988 M = jmodel.getNumberOfStatefulNodes();
2989 K = jmodel.getNumberOfClasses();
2991 QN = NaN * zeros(M, K);
2992 UN = NaN * zeros(M, K);
2993 RN = NaN * zeros(M, K);
2994 TN = NaN * zeros(M, K);
2995 CN = NaN * zeros(1, K);
2996 XN = NaN * zeros(1, K);
3002 Tmax = result.t.length();
3003 t = NaN * zeros(Tmax, 1);
3007 QN(ist, jst) = result.QN.get(ist-1, jst-1);
3008 UN(ist, jst) = result.UN.get(ist-1, jst-1);
3009 RN(ist, jst) = result.RN.get(ist-1, jst-1);
3010 TN(ist, jst) = result.TN.get(ist-1, jst-1);
3015 CN(1, jst) = result.CN.get(0, jst-1);
3016 XN(1, jst) = result.XN.get(0, jst-1);
3022 QNt{ist, jst}(p, 1) = result.QNt(ist, jst).get(p-1, 0);
3023 UNt{ist, jst}(p, 1) = result.UNt(ist, jst).get(p-1, 0);
3024 TNt{ist, jst}(p, 1) = result.TNt(ist, jst).get(p-1, 0);
3030 t(p, 1) = result.t.get(p-1, 0);
3033 % JLINE does not return odeStateVec
3034 xvec.odeStateVec = [];
3038 function [ldes] = SolverLDES(network_object, options)
3039 % Create LDES-specific options object
3040 ldesOptions = jline.solvers.ldes.LDESOptions();
3042 % Copy standard options
3043 ldesOptions.samples = options.samples;
3044 ldesOptions.seed = options.seed;
3046 [confintEnabled, confintLevel] = Solver.parseConfInt(options.confint);
3048 ldesOptions.confint = confintLevel;
3050 ldesOptions.confint = 0;
3052 % Pass timespan for transient analysis
3053 if isfield(options, 'timespan
') && length(options.timespan) >= 2
3054 ldesOptions.timespan = options.timespan;
3056 % Pass LDES-specific options if configured
3057 if isfield(options, 'config
')
3058 % Transient detection options
3059 if isfield(options.config, 'tranfilter
')
3060 ldesOptions.tranfilter = options.config.tranfilter;
3062 if isfield(options.config, 'mserbatch
')
3063 ldesOptions.mserbatch = options.config.mserbatch;
3065 if isfield(options.config, 'warmupfrac
')
3066 ldesOptions.warmupfrac = options.config.warmupfrac;
3068 % Confidence interval options
3069 if isfield(options.config, 'cimethod
')
3070 ldesOptions.cimethod = options.config.cimethod;
3072 if isfield(options.config, 'obmoverlap
')
3073 ldesOptions.obmoverlap = options.config.obmoverlap;
3075 if isfield(options.config, 'ciminbatch
')
3076 ldesOptions.ciminbatch = options.config.ciminbatch;
3078 if isfield(options.config, 'ciminobs
')
3079 ldesOptions.ciminobs = options.config.ciminobs;
3081 if isfield(options.config, 'spectralLowFreqFrac
')
3082 ldesOptions.spectralLowFreqFrac = options.config.spectralLowFreqFrac;
3084 % Convergence options
3085 if isfield(options.config, 'cnvgon
')
3086 ldesOptions.cnvgon = options.config.cnvgon;
3088 if isfield(options.config, 'cnvgtol
')
3089 ldesOptions.cnvgtol = options.config.cnvgtol;
3091 if isfield(options.config, 'cnvgbatch
')
3092 ldesOptions.cnvgbatch = options.config.cnvgbatch;
3094 if isfield(options.config, 'cnvgchk
')
3095 ldesOptions.cnvgchk = options.config.cnvgchk;
3099 ldes = jline.solvers.ldes.SolverLDES(network_object, ldesOptions);
3102 function [mva] = SolverMVA(network_object, options)
3103 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.MVA);
3105 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3107 mva = jline.solvers.mva.SolverMVA(network_object, solverOptions);
3110 function [nc] = SolverNC(network_object, options)
3111 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.NC);
3113 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3115 nc = jline.solvers.nc.SolverNC(network_object, solverOptions);
3118 function [auto] = SolverAuto(network_object, options)
3119 solverOptions = jline.solvers.auto.AUTOptions();
3121 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3123 auto = jline.solvers.auto.SolverAUTO(network_object, solverOptions);
3126 function streamOpts = StreamingOptions(varargin)
3127 % STREAMINGOPTIONS Create Java StreamingOptions for SSA/LDES stream() method
3129 % @brief Creates StreamingOptions for streaming simulation metrics
3131 % @param varargin Name-value pairs for options:
3132 % 'transport
' - 'http
' (recommended) or 'grpc
' (default: 'http
')
3133 % 'endpoint
' - Receiver endpoint (default: 'localhost:8080/metrics
' for HTTP)
3134 % 'mode
' - 'sampled
' or 'time_window
' (default: 'sampled
')
3135 % 'sampleFrequency
' - Push every N events in sampled mode (default: 100)
3136 % 'timeWindowSeconds
' - Window duration in time_window mode (default: 1.0)
3137 % 'serviceName
' - Service identifier (default: 'line-stream')
3138 % 'includeQueueLength' - Include queue length metrics (default: true)
3139 % 'includeUtilization' - Include utilization metrics (default: true)
3140 % 'includeThroughput' - Include throughput metrics (default: true)
3141 % 'includeResponseTime' - Include response time metrics (default: true)
3142 % 'includeArrivalRate' - Include arrival rate metrics (default: true)
3144 % @return streamOpts Java StreamingOptions object
3148 % streamOpts = JLINE.StreamingOptions('transport', 'http', 'sampleFrequency', 50);
3151 streamOpts = jline.streaming.StreamingOptions();
3153 % Parse optional arguments
3155 addParameter(p,
'transport',
'http', @ischar);
3156 addParameter(p,
'endpoint',
'', @ischar); % Empty means use
default for transport
3157 addParameter(p,
'mode',
'sampled', @ischar);
3158 addParameter(p,
'sampleFrequency', 100, @isnumeric);
3159 addParameter(p,
'timeWindowSeconds', 1.0, @isnumeric);
3160 addParameter(p,
'serviceName',
'line-stream', @ischar);
3161 addParameter(p,
'includeQueueLength',
true, @islogical);
3162 addParameter(p,
'includeUtilization',
true, @islogical);
3163 addParameter(p,
'includeThroughput',
true, @islogical);
3164 addParameter(p,
'includeResponseTime',
true, @islogical);
3165 addParameter(p,
'includeArrivalRate',
true, @islogical);
3166 parse(p, varargin{:});
3168 % Set transport type
3169 transportTypes = javaMethod(
'values',
'jline.streaming.StreamingOptions$TransportType');
3170 switch lower(p.Results.transport)
3172 streamOpts.transport = transportTypes(1); % HTTP
3174 streamOpts.transport = transportTypes(2); % GRPC
3176 streamOpts.transport = transportTypes(1); % Default to HTTP
3179 % Set endpoint (use provided or default based on transport)
3180 if ~isempty(p.Results.endpoint)
3181 streamOpts.endpoint = p.Results.endpoint;
3183 % If empty, StreamingOptions uses its default for the transport type
3186 streamModes = javaMethod('values', 'jline.streaming.StreamingOptions$StreamMode');
3187 switch lower(p.Results.mode)
3189 streamOpts.mode = streamModes(1); % SAMPLED
3191 streamOpts.mode = streamModes(2); % TIME_WINDOW
3193 streamOpts.mode = streamModes(1); % Default to SAMPLED
3197 streamOpts.sampleFrequency = p.Results.sampleFrequency;
3198 streamOpts.timeWindowSeconds = p.Results.timeWindowSeconds;
3199 streamOpts.serviceName = p.Results.serviceName;
3200 streamOpts.includeQueueLength = p.Results.includeQueueLength;
3201 streamOpts.includeUtilization = p.Results.includeUtilization;
3202 streamOpts.includeThroughput = p.Results.includeThroughput;
3203 streamOpts.includeResponseTime = p.Results.includeResponseTime;
3204 streamOpts.includeArrivalRate = p.Results.includeArrivalRate;
3207 function result = convertSampleResult(jresult)
3208 % CONVERTSAMPLERESULT Convert Java sample result to MATLAB struct
3210 % @brief Converts Java SampleNodeState to MATLAB structure
3212 % @param jresult Java SampleNodeState
object
3213 % @return result MATLAB struct with fields: t, state, isaggregate
3217 % Convert time matrix
3218 if ~isempty(jresult.t)
3219 result.t = JLINE.from_jline_matrix(jresult.t);
3224 % Convert state matrix
3225 if ~isempty(jresult.state) && isa(jresult.state, 'jline.util.matrix.Matrix')
3226 result.state = JLINE.from_jline_matrix(jresult.state);
3231 result.isaggregate = jresult.isaggregate;
3234 function [ln] = SolverLN(layered_network_object, options)
3235 solverOptions = jline.solvers.SolverOptions(jline.lang.constant.SolverType.LN);
3237 solverOptions = JLINE.parseSolverOptions(solverOptions, options);
3239 ln = jline.solvers.ln.SolverLN(layered_network_object, solverOptions);
3242 function serfun = handle_to_serializablefun(handle, sn)
3243 % HANDLE_TO_SERIALIZABLEFUN Convert MATLAB function handle to Java SerializableFunction
3245 % This function pre-computes the function values for all possible state
3246 % combinations and creates a Java PrecomputedCDFunction
object.
3248 % @param handle MATLAB function handle that takes a vector ni and returns a scalar
3249 % @param sn Network struct containing njobs (population per class)
3250 % @return serfun Java PrecomputedCDFunction
object
3252 % Get number of
classes and maximum populations
3253 nclasses = sn.nclasses;
3254 njobs = sn.njobs; % Population per class
3256 % For open
classes (njobs=0), use a reasonable bound
3259 if maxPop(r) == 0 || isinf(maxPop(r))
3260 % For open
classes, use sum of closed class populations or 100 as bound
3261 maxPop(r) = max(100, sum(njobs(isfinite(njobs) & njobs > 0)));
3265 % Create Java PrecomputedCDFunction
object
3266 serfun = jline.util.PrecomputedCDFunction(nclasses);
3268 % Enumerate all possible state combinations and pre-compute function values
3269 % Use recursive enumeration to handle arbitrary number of
classes
3270 JLINE.enumerate_states(handle, serfun, maxPop, zeros(1, nclasses), 1);
3273 function enumerate_states(handle, serfun, maxPop, currentState, classIdx)
3274 % ENUMERATE_STATES Recursively enumerate all state combinations
3276 % @param handle MATLAB function handle
3277 % @param serfun Java PrecomputedCDFunction
object to populate
3278 % @param maxPop Maximum population per class
3279 % @param currentState Current state being built
3280 % @param classIdx Current class index being enumerated
3282 nclasses = length(maxPop);
3284 if classIdx > nclasses
3285 % We have a complete state, compute and store the function value
3287 value = handle(currentState);
3288 % Convert to Java
int array and add to serfun
3289 jstate = jline.util.matrix.Matrix(1, nclasses);
3291 jstate.set(0, r-1, currentState(r));
3293 serfun.addValue(jstate, value);
3295 % If function evaluation fails, skip this state
3300 % Enumerate all populations for current class
3301 for n = 0:maxPop(classIdx)
3302 currentState(classIdx) = n;
3303 JLINE.enumerate_states(handle, serfun, maxPop, currentState, classIdx + 1);
3307 function result = call_java_cdscaling(jfun, ni)
3308 % CALL_JAVA_CDSCALING Call a Java SerializableFunction for class dependence
3310 % This function converts a MATLAB vector to a Java Matrix and calls
3311 % the Java function's apply() method.
3313 % @param jfun Java SerializableFunction<Matrix, Double>
object
3314 % @param ni MATLAB vector representing the state (jobs per class)
3315 % @return result The scaling factor returned by the Java function
3317 % Convert MATLAB vector to Java Matrix
3319 jmatrix = jline.util.matrix.Matrix(1, length(ni));
3320 for r = 1:length(ni)
3321 jmatrix.set(0, r-1, ni(r));
3324 jmatrix = jline.util.matrix.Matrix(length(ni), 1);
3325 for r = 1:length(ni)
3326 jmatrix.set(r-1, 0, ni(r));
3330 % Call the Java function and convert result to MATLAB
double
3331 jresult = jfun.apply(jmatrix);
3332 result =
double(jresult);
3335 function jSched = to_jline_sched_strategy(schedId)
3336 % Convert MATLAB SchedStrategy
id to jline SchedStrategy enum
3338 case SchedStrategy.REF
3339 jSched = jline.lang.constant.SchedStrategy.REF;
3340 case SchedStrategy.INF
3341 jSched = jline.lang.constant.SchedStrategy.INF;
3342 case SchedStrategy.FCFS
3343 jSched = jline.lang.constant.SchedStrategy.FCFS;
3344 case SchedStrategy.LCFS
3345 jSched = jline.lang.constant.SchedStrategy.LCFS;
3346 case SchedStrategy.SIRO
3347 jSched = jline.lang.constant.SchedStrategy.SIRO;
3348 case SchedStrategy.SJF
3349 jSched = jline.lang.constant.SchedStrategy.SJF;
3350 case SchedStrategy.LJF
3351 jSched = jline.lang.constant.SchedStrategy.LJF;
3352 case SchedStrategy.PS
3353 jSched = jline.lang.constant.SchedStrategy.PS;
3354 case SchedStrategy.DPS
3355 jSched = jline.lang.constant.SchedStrategy.DPS;
3356 case SchedStrategy.GPS
3357 jSched = jline.lang.constant.SchedStrategy.GPS;
3358 case SchedStrategy.SEPT
3359 jSched = jline.lang.constant.SchedStrategy.SEPT;
3360 case SchedStrategy.LEPT
3361 jSched = jline.lang.constant.SchedStrategy.LEPT;
3362 case {SchedStrategy.HOL, SchedStrategy.FCFSPRIO}
3363 jSched = jline.lang.constant.SchedStrategy.FCFSPRIO;
3364 case SchedStrategy.FORK
3365 jSched = jline.lang.constant.SchedStrategy.FORK;
3366 case SchedStrategy.EXT
3367 jSched = jline.lang.constant.SchedStrategy.EXT;
3368 case SchedStrategy.LCFSPR
3369 jSched = jline.lang.constant.SchedStrategy.LCFSPR;
3370 case SchedStrategy.PSPRIO
3371 jSched = jline.lang.constant.SchedStrategy.PSPRIO;
3372 case SchedStrategy.DPSPRIO
3373 jSched = jline.lang.constant.SchedStrategy.DPSPRIO;
3374 case SchedStrategy.GPSPRIO
3375 jSched = jline.lang.constant.SchedStrategy.GPSPRIO;
3377 jSched = jline.lang.constant.SchedStrategy.FCFS;