libpetri 2.9.0 → 2.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2847,6 +2847,15 @@ var IncrementalMatcher = class {
2847
2847
  this.ts = requireds.map(() => /* @__PURE__ */ new Map());
2848
2848
  }
2849
2849
  ts;
2850
+ /** Monotonic fast path: ascending `(rep_ts, name)`; `fifo[fifoHead]` (after
2851
+ * `cleanTop`) is the min. Active while `!heaped`. Advance `fifoHead` instead of
2852
+ * `shift()` (O(1)); reset when the head catches the length. */
2853
+ fifo = [];
2854
+ fifoHead = 0;
2855
+ /** Largest entry appended to `fifo` in the current monotonic run. */
2856
+ maxPushed = null;
2857
+ /** Once an out-of-order push migrates `fifo` into `heap`. */
2858
+ heaped = false;
2850
2859
  heap = new ReadyHeap();
2851
2860
  ready = /* @__PURE__ */ new Map();
2852
2861
  /** Add one (already guard-passing) token carrying `name` at `createdAt` to input `i`. */
@@ -2874,8 +2883,35 @@ var IncrementalMatcher = class {
2874
2883
  }
2875
2884
  /** The name `selectMatchName` would pick, or `null`. O(1) read. */
2876
2885
  best() {
2877
- const top = this.heap.peek();
2878
- return top ? top.name : null;
2886
+ if (this.heaped) {
2887
+ const top = this.heap.peek();
2888
+ return top ? top.name : null;
2889
+ }
2890
+ return this.fifoHead < this.fifo.length ? this.fifo[this.fifoHead].name : null;
2891
+ }
2892
+ /**
2893
+ * Route a ready name's `(rep, name)` to the active structure: append to the
2894
+ * FIFO in O(1) while pushes stay non-decreasing; on the first inversion,
2895
+ * migrate the FIFO into the heap and stay heap-backed.
2896
+ */
2897
+ pushReady(rep, name) {
2898
+ const entry = { ts: rep, name };
2899
+ if (this.heaped) {
2900
+ this.heap.push(entry);
2901
+ return;
2902
+ }
2903
+ const max = this.maxPushed;
2904
+ const monotonic = max === null || rep > max.ts || rep === max.ts && name >= max.name;
2905
+ if (monotonic) {
2906
+ this.maxPushed = entry;
2907
+ this.fifo.push(entry);
2908
+ } else {
2909
+ this.heaped = true;
2910
+ for (let i = this.fifoHead; i < this.fifo.length; i++) this.heap.push(this.fifo[i]);
2911
+ this.fifo.length = 0;
2912
+ this.fifoHead = 0;
2913
+ this.heap.push(entry);
2914
+ }
2879
2915
  }
2880
2916
  repTs(name) {
2881
2917
  let rep = Infinity;
@@ -2892,19 +2928,40 @@ var IncrementalMatcher = class {
2892
2928
  if (rep !== null) {
2893
2929
  if (this.ready.get(name) !== rep) {
2894
2930
  this.ready.set(name, rep);
2895
- this.heap.push({ ts: rep, name });
2931
+ this.pushReady(rep, name);
2896
2932
  }
2897
2933
  } else {
2898
2934
  this.ready.delete(name);
2899
2935
  }
2900
2936
  }
2901
2937
  cleanTop() {
2902
- for (; ; ) {
2903
- const top = this.heap.peek();
2904
- if (top && this.ready.get(top.name) !== top.ts) this.heap.pop();
2905
- else break;
2938
+ if (this.heaped) {
2939
+ for (; ; ) {
2940
+ const top = this.heap.peek();
2941
+ if (top && this.ready.get(top.name) !== top.ts) this.heap.pop();
2942
+ else break;
2943
+ }
2944
+ if (this.heap.size === 0) {
2945
+ this.heaped = false;
2946
+ this.maxPushed = null;
2947
+ }
2948
+ } else {
2949
+ while (this.fifoHead < this.fifo.length) {
2950
+ const top = this.fifo[this.fifoHead];
2951
+ if (this.ready.get(top.name) !== top.ts) this.fifoHead++;
2952
+ else break;
2953
+ }
2954
+ if (this.fifoHead >= this.fifo.length) {
2955
+ this.fifo.length = 0;
2956
+ this.fifoHead = 0;
2957
+ this.maxPushed = null;
2958
+ }
2906
2959
  }
2907
2960
  }
2961
+ /** Test-only: has the matcher fallen back from the FIFO fast path to the heap? */
2962
+ isHeaped() {
2963
+ return this.heaped;
2964
+ }
2908
2965
  };
2909
2966
 
2910
2967
  // src/runtime/out-violation-error.ts