@hviana/sema 0.5.1 → 0.5.2

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.
@@ -8,6 +8,13 @@
8
8
  import { cosine } from "../vec.js";
9
9
  import { gistOf, read } from "./primitives.js";
10
10
  import { leafIdRun } from "./canonical.js";
11
+ //
12
+ // Budgeted on the same terms as the reach memo below (AGENTS §2.12): these
13
+ // three maps are cleared on every write, but a long read-only session over a
14
+ // large store converges on one entry per node per map with nothing to bound
15
+ // it. Past the cap all three are dropped together and re-derived, costing
16
+ // cold structural probes and never a wrong answer.
17
+ const STRUCT_MEMO_MAX = 100_000;
11
18
  const structCaches = new WeakMap();
12
19
  // ── The shared ancestor-reach memo ──────────────────────────────────────
13
20
  //
@@ -59,6 +66,13 @@ function getStructCache(ctx) {
59
66
  hasParents: new Map(),
60
67
  });
61
68
  }
69
+ else if (c.hasNext.size >= STRUCT_MEMO_MAX ||
70
+ c.prevCount.size >= STRUCT_MEMO_MAX ||
71
+ c.hasParents.size >= STRUCT_MEMO_MAX) {
72
+ c.hasNext.clear();
73
+ c.prevCount.clear();
74
+ c.hasParents.clear();
75
+ }
62
76
  return c;
63
77
  }
64
78
  /** Invalidate every session-lifetime structural read after a write. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hviana/sema",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "description": "Sema: a non-parametric, instance-based reasoning system.",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -31,6 +31,13 @@ interface StructCache {
31
31
  prevCount: Map<number, number>;
32
32
  hasParents: Map<number, boolean>;
33
33
  }
34
+ //
35
+ // Budgeted on the same terms as the reach memo below (AGENTS §2.12): these
36
+ // three maps are cleared on every write, but a long read-only session over a
37
+ // large store converges on one entry per node per map with nothing to bound
38
+ // it. Past the cap all three are dropped together and re-derived, costing
39
+ // cold structural probes and never a wrong answer.
40
+ const STRUCT_MEMO_MAX = 100_000;
34
41
  const structCaches = new WeakMap<object, StructCache>();
35
42
 
36
43
  // ── The shared ancestor-reach memo ──────────────────────────────────────
@@ -85,6 +92,14 @@ function getStructCache(ctx: MindContext): StructCache | null {
85
92
  hasParents: new Map(),
86
93
  },
87
94
  );
95
+ } else if (
96
+ c.hasNext.size >= STRUCT_MEMO_MAX ||
97
+ c.prevCount.size >= STRUCT_MEMO_MAX ||
98
+ c.hasParents.size >= STRUCT_MEMO_MAX
99
+ ) {
100
+ c.hasNext.clear();
101
+ c.prevCount.clear();
102
+ c.hasParents.clear();
88
103
  }
89
104
  return c;
90
105
  }