| Algorithm 1: Phase II—Per-Switch Local Refinement |
|
Input: Baseline GCL from Phase I, device-specific caps C_cap(S) Output: Refined GCLs satisfying hardware entry limits per switch 1: function PHASE_II_REFINE(GCL, {C_cap(S)}) 2: // Distribute to switches and refine in parallel 3: parallel for each switch S do 4: windows ← PARTITION_BY_PORT(GCL, S) 5: for iter = 1 to I do // I = 8 6: for each port P in S.egress_ports do 7: if COUNT_ENTRIES(windows[P]) ≤ C_cap(S) then continue 8: 9: // Step 1: Gap filling-absorb sub-slot intervals 10: windows[P] ← GAP_FILL(windows[P], t_slot) 11: 12: // Step 2: Greedy merge-coalesce compatible windows 13: windows[P] ← GREEDY_MERGE(windows[P]) 14: 15: // Step 3: Offset alignment-adjust timing for merging 16: if COUNT_ENTRIES(windows[P]) > C_cap(S) then 17: windows[P] ← ALIGN_OFFSETS(windows[P], C_cap(S)) 18: 19: // Step 4: Cap enforcement-force merge if needed 20: if COUNT_ENTRIES(windows[P]) > C_cap(S) then 21: windows[P] ← FORCE_MERGE_TO_CAP(windows[P], C_cap(S)) 22: 23: GCL_refined[S] ← RECONSTRUCT(windows) 24: 25: // Synchronization and delay recomputation 26: return MERGE_ALL(GCL_refined), RECOMPUTE_DELAYS() 27: function GREEDY_MERGE(windows) 28: // Sweep-line merge of overlapping/contiguous TT intervals after GAP_FILL/ALIGN_OFFSETS 29: windows ← SORT_BY_START(windows) 30: merged ← [] 31: for each (st, en) in windows do 32: if merged is not empty and st ≤ merged[-1].end then 33: merged[-1].end ← max(merged[-1].end, en) 34: else 35: merged.append((st, en)) 36: return merged |