parseman 0.61.5 → 0.61.6

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.
@@ -3636,7 +3636,7 @@ function regex(pattern, flags = "") {
3636
3636
  }
3637
3637
 
3638
3638
  // src/version.ts
3639
- var PARSEMAN_VERSION = "0.61.5";
3639
+ var PARSEMAN_VERSION = "0.61.6";
3640
3640
 
3641
3641
  // src/table/lex-body.ts
3642
3642
  function buildLexBodyRecognizer(spec, constants) {
@@ -18479,21 +18479,70 @@ function collectGrammarReflection(ruleMap, opts) {
18479
18479
  var LOOP = 8;
18480
18480
  var ROUNDS = 60;
18481
18481
  var CAP = 1e12;
18482
+ var CROSSING_WEIGHT = 4;
18483
+ var TAKEN = -1;
18482
18484
  function selectHotSites(code, entries, siteBytes, budget, profile) {
18483
18485
  const selected = /* @__PURE__ */ new Set();
18484
18486
  if (budget <= 0) return selected;
18485
- const weight = profile === void 0 ? staticWeights(code, entries) : void 0;
18486
- const w = (ip) => (weight !== void 0 ? weight.get(ip) : profile[ip]) ?? 0;
18487
- const ranked = [...siteBytes.keys()].sort((a, b) => w(b) / siteBytes.get(b) - w(a) / siteBytes.get(a) || a - b);
18488
18487
  let spent = 0;
18489
- for (const ip of ranked) {
18490
- if (w(ip) === 0) break;
18488
+ for (const ip of profile === void 0 ? staticRanking(code, entries, siteBytes) : connectedRanking(code, siteBytes, profile)) {
18491
18489
  spent += siteBytes.get(ip);
18492
18490
  if (spent > budget) break;
18493
18491
  selected.add(ip);
18494
18492
  }
18495
18493
  return selected;
18496
18494
  }
18495
+ function edgesAsLowered(code, siteBytes, ip, out) {
18496
+ out.length = 0;
18497
+ if (code[ip] !== OP_CONT) childSlots(code, ip, out);
18498
+ else if (siteBytes.has(ip)) out.push(code[ip + 1], code[ip + 3]);
18499
+ else out.push(code[ip + 2]);
18500
+ for (let i = 0; i < out.length; i++) {
18501
+ let row = out[i];
18502
+ for (; ; ) {
18503
+ const op = code[row];
18504
+ if (op === OP_GAPGATE || op === OP_SEED) row = code[row + 1];
18505
+ else if (op === OP_CONT && !siteBytes.has(row)) row = code[row + 2];
18506
+ else break;
18507
+ }
18508
+ out[i] = row;
18509
+ }
18510
+ }
18511
+ function staticRanking(code, entries, siteBytes) {
18512
+ const weight = staticWeights(code, entries, siteBytes);
18513
+ const w = (ip) => weight.get(ip) ?? 0;
18514
+ return [...siteBytes.keys()].filter((ip) => w(ip) > 0).sort((a, b) => w(b) / siteBytes.get(b) - w(a) / siteBytes.get(a) || a - b);
18515
+ }
18516
+ function* connectedRanking(code, siteBytes, calls) {
18517
+ const ran = [...siteBytes.keys()].filter((ip) => calls[ip] > 0).sort((a, b) => a - b);
18518
+ const slot = new Map(ran.map((ip, i) => [ip, i]));
18519
+ const bytes = ran.map((ip) => siteBytes.get(ip));
18520
+ const worth = ran.map((ip) => calls[ip]);
18521
+ const score = worth.map((value, i) => value / bytes[i]);
18522
+ const crossings = ran.map(() => []);
18523
+ const kids = [];
18524
+ ran.forEach((ip, from) => {
18525
+ edgesAsLowered(code, siteBytes, ip, kids);
18526
+ for (const callee of kids) {
18527
+ const to = slot.get(callee);
18528
+ if (to === void 0) continue;
18529
+ const gain = CROSSING_WEIGHT * calls[callee];
18530
+ crossings[from].push([to, gain]);
18531
+ crossings[to].push([from, gain]);
18532
+ }
18533
+ });
18534
+ for (let left = ran.length; left > 0; left--) {
18535
+ let best = 0;
18536
+ for (let i = 1; i < score.length; i++) if (score[i] > score[best]) best = i;
18537
+ score[best] = TAKEN;
18538
+ yield ran[best];
18539
+ for (const [neighbour, gain] of crossings[best]) {
18540
+ if (score[neighbour] === TAKEN) continue;
18541
+ worth[neighbour] = worth[neighbour] + gain;
18542
+ score[neighbour] = worth[neighbour] / bytes[neighbour];
18543
+ }
18544
+ }
18545
+ }
18497
18546
  function fitHotSites(code, entries, siteBytes, fixed, ceiling, sourceBytes, profile) {
18498
18547
  const ranked = [...selectHotSites(code, entries, siteBytes, ceiling - fixed, profile)];
18499
18548
  for (; ranked.length > 0; ranked.pop()) {
@@ -18503,25 +18552,17 @@ function fitHotSites(code, entries, siteBytes, fixed, ceiling, sourceBytes, prof
18503
18552
  }
18504
18553
  return void 0;
18505
18554
  }
18506
- function staticWeights(code, entries) {
18555
+ function staticWeights(code, entries, siteBytes) {
18507
18556
  let weight = /* @__PURE__ */ new Map();
18508
18557
  const kids = [];
18509
18558
  for (let round = 0; round < ROUNDS; round++) {
18510
18559
  const next = /* @__PURE__ */ new Map();
18511
18560
  for (const ip of entries) next.set(ip, 1);
18512
18561
  for (const [ip, w] of weight) {
18513
- kids.length = 0;
18514
- childSlots(code, ip, kids);
18562
+ edgesAsLowered(code, siteBytes, ip, kids);
18515
18563
  const op = code[ip];
18516
- if (op === OP_CONT && continuationGate(code, code[ip + 3]) !== void 0) {
18517
- kids.length = 0;
18518
- kids.push(code[ip + 1], code[ip + 3]);
18519
- }
18520
18564
  const scale = op === OP_REP || op === OP_REPV ? LOOP : op === OP_CHOICE || op === OP_DISPATCH ? 1 / Math.max(1, kids.length) : 1;
18521
- for (const k of kids) {
18522
- const kid = code[k] === OP_GAPGATE ? code[k + 1] : k;
18523
- next.set(kid, Math.min(CAP, (next.get(kid) ?? 0) + w * scale));
18524
- }
18565
+ for (const kid of kids) next.set(kid, Math.min(CAP, (next.get(kid) ?? 0) + w * scale));
18525
18566
  }
18526
18567
  weight = next;
18527
18568
  }