@claude-flow/memory 3.0.0-alpha.2 → 3.0.0-alpha.20

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.
Files changed (253) hide show
  1. package/README.md +858 -249
  2. package/dist/agent-memory-scope.d.ts +131 -0
  3. package/dist/agent-memory-scope.d.ts.map +1 -0
  4. package/dist/agent-memory-scope.js +223 -0
  5. package/dist/agent-memory-scope.js.map +1 -0
  6. package/dist/agent-memory-scope.test.d.ts +8 -0
  7. package/dist/agent-memory-scope.test.d.ts.map +1 -0
  8. package/dist/agent-memory-scope.test.js +463 -0
  9. package/dist/agent-memory-scope.test.js.map +1 -0
  10. package/dist/agentdb-adapter.d.ts +82 -4
  11. package/dist/agentdb-adapter.d.ts.map +1 -1
  12. package/dist/agentdb-adapter.js +388 -17
  13. package/dist/agentdb-adapter.js.map +1 -1
  14. package/dist/agentdb-backend.d.ts +6 -0
  15. package/dist/agentdb-backend.d.ts.map +1 -1
  16. package/dist/agentdb-backend.js +115 -51
  17. package/dist/agentdb-backend.js.map +1 -1
  18. package/dist/auto-memory-bridge.d.ts +237 -0
  19. package/dist/auto-memory-bridge.d.ts.map +1 -0
  20. package/dist/auto-memory-bridge.js +758 -0
  21. package/dist/auto-memory-bridge.js.map +1 -0
  22. package/dist/auto-memory-bridge.test.d.ts +8 -0
  23. package/dist/auto-memory-bridge.test.d.ts.map +1 -0
  24. package/dist/auto-memory-bridge.test.js +849 -0
  25. package/dist/auto-memory-bridge.test.js.map +1 -0
  26. package/dist/benchmark.test.d.ts +2 -0
  27. package/dist/benchmark.test.d.ts.map +1 -0
  28. package/dist/benchmark.test.js +277 -0
  29. package/dist/benchmark.test.js.map +1 -0
  30. package/dist/consolidator.d.ts +96 -0
  31. package/dist/consolidator.d.ts.map +1 -0
  32. package/dist/consolidator.js +209 -0
  33. package/dist/consolidator.js.map +1 -0
  34. package/dist/consolidator.test.d.ts +17 -0
  35. package/dist/consolidator.test.d.ts.map +1 -0
  36. package/dist/consolidator.test.js +239 -0
  37. package/dist/consolidator.test.js.map +1 -0
  38. package/dist/controller-registry.d.ts +232 -0
  39. package/dist/controller-registry.d.ts.map +1 -0
  40. package/dist/controller-registry.js +1049 -0
  41. package/dist/controller-registry.js.map +1 -0
  42. package/dist/controller-registry.test.d.ts +14 -0
  43. package/dist/controller-registry.test.d.ts.map +1 -0
  44. package/dist/controller-registry.test.js +691 -0
  45. package/dist/controller-registry.test.js.map +1 -0
  46. package/dist/database-provider.d.ts +14 -2
  47. package/dist/database-provider.d.ts.map +1 -1
  48. package/dist/database-provider.js +63 -3
  49. package/dist/database-provider.js.map +1 -1
  50. package/dist/database-provider.test.js +56 -3
  51. package/dist/database-provider.test.js.map +1 -1
  52. package/dist/entity-tagger.d.ts +31 -0
  53. package/dist/entity-tagger.d.ts.map +1 -0
  54. package/dist/entity-tagger.js +80 -0
  55. package/dist/entity-tagger.js.map +1 -0
  56. package/dist/entity-tagger.test.d.ts +12 -0
  57. package/dist/entity-tagger.test.d.ts.map +1 -0
  58. package/dist/entity-tagger.test.js +70 -0
  59. package/dist/entity-tagger.test.js.map +1 -0
  60. package/dist/fts5.test.d.ts +13 -0
  61. package/dist/fts5.test.d.ts.map +1 -0
  62. package/dist/fts5.test.js +144 -0
  63. package/dist/fts5.test.js.map +1 -0
  64. package/dist/graceful-retrieval.test.d.ts +14 -0
  65. package/dist/graceful-retrieval.test.d.ts.map +1 -0
  66. package/dist/graceful-retrieval.test.js +192 -0
  67. package/dist/graceful-retrieval.test.js.map +1 -0
  68. package/dist/hnsw-index.d.ts +51 -0
  69. package/dist/hnsw-index.d.ts.map +1 -1
  70. package/dist/hnsw-index.js +396 -12
  71. package/dist/hnsw-index.js.map +1 -1
  72. package/dist/hnsw-persistence.test.d.ts +13 -0
  73. package/dist/hnsw-persistence.test.d.ts.map +1 -0
  74. package/dist/hnsw-persistence.test.js +208 -0
  75. package/dist/hnsw-persistence.test.js.map +1 -0
  76. package/dist/hybrid-backend.d.ts +28 -0
  77. package/dist/hybrid-backend.d.ts.map +1 -1
  78. package/dist/hybrid-backend.js +82 -4
  79. package/dist/hybrid-backend.js.map +1 -1
  80. package/dist/hybrid-backend.test.js +6 -5
  81. package/dist/hybrid-backend.test.js.map +1 -1
  82. package/dist/index.d.ts +167 -9
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +277 -30
  85. package/dist/index.js.map +1 -1
  86. package/dist/index.test.d.ts +10 -0
  87. package/dist/index.test.d.ts.map +1 -0
  88. package/dist/index.test.js +71 -0
  89. package/dist/index.test.js.map +1 -0
  90. package/dist/json-security.d.ts +12 -0
  91. package/dist/json-security.d.ts.map +1 -0
  92. package/dist/json-security.js +20 -0
  93. package/dist/json-security.js.map +1 -0
  94. package/dist/learning-bridge.d.ts +137 -0
  95. package/dist/learning-bridge.d.ts.map +1 -0
  96. package/dist/learning-bridge.js +335 -0
  97. package/dist/learning-bridge.js.map +1 -0
  98. package/dist/learning-bridge.test.d.ts +8 -0
  99. package/dist/learning-bridge.test.d.ts.map +1 -0
  100. package/dist/learning-bridge.test.js +578 -0
  101. package/dist/learning-bridge.test.js.map +1 -0
  102. package/dist/memory-graph.d.ts +100 -0
  103. package/dist/memory-graph.d.ts.map +1 -0
  104. package/dist/memory-graph.js +333 -0
  105. package/dist/memory-graph.js.map +1 -0
  106. package/dist/memory-graph.test.d.ts +8 -0
  107. package/dist/memory-graph.test.d.ts.map +1 -0
  108. package/dist/memory-graph.test.js +609 -0
  109. package/dist/memory-graph.test.js.map +1 -0
  110. package/dist/persistent-sona.d.ts +144 -0
  111. package/dist/persistent-sona.d.ts.map +1 -0
  112. package/dist/persistent-sona.js +332 -0
  113. package/dist/persistent-sona.js.map +1 -0
  114. package/dist/rvf-backend.d.ts +53 -0
  115. package/dist/rvf-backend.d.ts.map +1 -0
  116. package/dist/rvf-backend.js +643 -0
  117. package/dist/rvf-backend.js.map +1 -0
  118. package/dist/rvf-learning-store.d.ts +139 -0
  119. package/dist/rvf-learning-store.d.ts.map +1 -0
  120. package/dist/rvf-learning-store.js +295 -0
  121. package/dist/rvf-learning-store.js.map +1 -0
  122. package/dist/rvf-migration.d.ts +45 -0
  123. package/dist/rvf-migration.d.ts.map +1 -0
  124. package/dist/rvf-migration.js +254 -0
  125. package/dist/rvf-migration.js.map +1 -0
  126. package/dist/smart-retrieval.d.ts +118 -0
  127. package/dist/smart-retrieval.d.ts.map +1 -0
  128. package/dist/smart-retrieval.js +322 -0
  129. package/dist/smart-retrieval.js.map +1 -0
  130. package/dist/smart-retrieval.test.d.ts +2 -0
  131. package/dist/smart-retrieval.test.d.ts.map +1 -0
  132. package/dist/smart-retrieval.test.js +238 -0
  133. package/dist/smart-retrieval.test.js.map +1 -0
  134. package/dist/sqlite-backend.d.ts +10 -0
  135. package/dist/sqlite-backend.d.ts.map +1 -1
  136. package/dist/sqlite-backend.js +170 -74
  137. package/dist/sqlite-backend.js.map +1 -1
  138. package/dist/sqljs-backend.d.ts +9 -0
  139. package/dist/sqljs-backend.d.ts.map +1 -1
  140. package/dist/sqljs-backend.js +120 -29
  141. package/dist/sqljs-backend.js.map +1 -1
  142. package/dist/types.d.ts +3 -0
  143. package/dist/types.d.ts.map +1 -1
  144. package/package.json +48 -35
  145. package/.agentic-flow/intelligence.json +0 -16
  146. package/__tests__/coverage/base.css +0 -224
  147. package/__tests__/coverage/block-navigation.js +0 -87
  148. package/__tests__/coverage/coverage-final.json +0 -19
  149. package/__tests__/coverage/favicon.png +0 -0
  150. package/__tests__/coverage/index.html +0 -206
  151. package/__tests__/coverage/lcov-report/base.css +0 -224
  152. package/__tests__/coverage/lcov-report/block-navigation.js +0 -87
  153. package/__tests__/coverage/lcov-report/favicon.png +0 -0
  154. package/__tests__/coverage/lcov-report/index.html +0 -206
  155. package/__tests__/coverage/lcov-report/prettify.css +0 -1
  156. package/__tests__/coverage/lcov-report/prettify.js +0 -2
  157. package/__tests__/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  158. package/__tests__/coverage/lcov-report/sorter.js +0 -210
  159. package/__tests__/coverage/lcov-report/src/agentdb-adapter.ts.html +0 -2737
  160. package/__tests__/coverage/lcov-report/src/agentdb-backend.ts.html +0 -3130
  161. package/__tests__/coverage/lcov-report/src/application/commands/delete-memory.command.ts.html +0 -601
  162. package/__tests__/coverage/lcov-report/src/application/commands/index.html +0 -131
  163. package/__tests__/coverage/lcov-report/src/application/commands/store-memory.command.ts.html +0 -394
  164. package/__tests__/coverage/lcov-report/src/application/queries/index.html +0 -116
  165. package/__tests__/coverage/lcov-report/src/application/queries/search-memory.query.ts.html +0 -796
  166. package/__tests__/coverage/lcov-report/src/application/services/index.html +0 -116
  167. package/__tests__/coverage/lcov-report/src/application/services/memory-application-service.ts.html +0 -793
  168. package/__tests__/coverage/lcov-report/src/cache-manager.ts.html +0 -1633
  169. package/__tests__/coverage/lcov-report/src/database-provider.ts.html +0 -1618
  170. package/__tests__/coverage/lcov-report/src/domain/entities/index.html +0 -116
  171. package/__tests__/coverage/lcov-report/src/domain/entities/memory-entry.ts.html +0 -952
  172. package/__tests__/coverage/lcov-report/src/domain/services/index.html +0 -116
  173. package/__tests__/coverage/lcov-report/src/domain/services/memory-domain-service.ts.html +0 -1294
  174. package/__tests__/coverage/lcov-report/src/hnsw-index.ts.html +0 -3124
  175. package/__tests__/coverage/lcov-report/src/hybrid-backend.ts.html +0 -2167
  176. package/__tests__/coverage/lcov-report/src/index.html +0 -266
  177. package/__tests__/coverage/lcov-report/src/infrastructure/repositories/hybrid-memory-repository.ts.html +0 -1633
  178. package/__tests__/coverage/lcov-report/src/infrastructure/repositories/index.html +0 -116
  179. package/__tests__/coverage/lcov-report/src/migration.ts.html +0 -2092
  180. package/__tests__/coverage/lcov-report/src/query-builder.ts.html +0 -1711
  181. package/__tests__/coverage/lcov-report/src/sqlite-backend.ts.html +0 -2281
  182. package/__tests__/coverage/lcov-report/src/sqljs-backend.ts.html +0 -2374
  183. package/__tests__/coverage/lcov-report/src/types.ts.html +0 -2266
  184. package/__tests__/coverage/lcov.info +0 -10238
  185. package/__tests__/coverage/prettify.css +0 -1
  186. package/__tests__/coverage/prettify.js +0 -2
  187. package/__tests__/coverage/sort-arrow-sprite.png +0 -0
  188. package/__tests__/coverage/sorter.js +0 -210
  189. package/__tests__/coverage/src/agentdb-adapter.ts.html +0 -2737
  190. package/__tests__/coverage/src/agentdb-backend.ts.html +0 -3130
  191. package/__tests__/coverage/src/application/commands/delete-memory.command.ts.html +0 -601
  192. package/__tests__/coverage/src/application/commands/index.html +0 -131
  193. package/__tests__/coverage/src/application/commands/store-memory.command.ts.html +0 -394
  194. package/__tests__/coverage/src/application/queries/index.html +0 -116
  195. package/__tests__/coverage/src/application/queries/search-memory.query.ts.html +0 -796
  196. package/__tests__/coverage/src/application/services/index.html +0 -116
  197. package/__tests__/coverage/src/application/services/memory-application-service.ts.html +0 -793
  198. package/__tests__/coverage/src/cache-manager.ts.html +0 -1633
  199. package/__tests__/coverage/src/database-provider.ts.html +0 -1618
  200. package/__tests__/coverage/src/domain/entities/index.html +0 -116
  201. package/__tests__/coverage/src/domain/entities/memory-entry.ts.html +0 -952
  202. package/__tests__/coverage/src/domain/services/index.html +0 -116
  203. package/__tests__/coverage/src/domain/services/memory-domain-service.ts.html +0 -1294
  204. package/__tests__/coverage/src/hnsw-index.ts.html +0 -3124
  205. package/__tests__/coverage/src/hybrid-backend.ts.html +0 -2167
  206. package/__tests__/coverage/src/index.html +0 -266
  207. package/__tests__/coverage/src/infrastructure/repositories/hybrid-memory-repository.ts.html +0 -1633
  208. package/__tests__/coverage/src/infrastructure/repositories/index.html +0 -116
  209. package/__tests__/coverage/src/migration.ts.html +0 -2092
  210. package/__tests__/coverage/src/query-builder.ts.html +0 -1711
  211. package/__tests__/coverage/src/sqlite-backend.ts.html +0 -2281
  212. package/__tests__/coverage/src/sqljs-backend.ts.html +0 -2374
  213. package/__tests__/coverage/src/types.ts.html +0 -2266
  214. package/benchmarks/cache-hit-rate.bench.ts +0 -535
  215. package/benchmarks/hnsw-indexing.bench.ts +0 -552
  216. package/benchmarks/memory-write.bench.ts +0 -469
  217. package/benchmarks/vector-search.bench.ts +0 -449
  218. package/docs/AGENTDB-INTEGRATION.md +0 -388
  219. package/docs/CROSS_PLATFORM.md +0 -505
  220. package/docs/WINDOWS_SUPPORT.md +0 -422
  221. package/examples/agentdb-example.ts +0 -345
  222. package/examples/cross-platform-usage.ts +0 -326
  223. package/framework/benchmark.ts +0 -112
  224. package/src/agentdb-adapter.ts +0 -884
  225. package/src/agentdb-backend.test.ts +0 -339
  226. package/src/agentdb-backend.ts +0 -1016
  227. package/src/application/commands/delete-memory.command.ts +0 -172
  228. package/src/application/commands/store-memory.command.ts +0 -103
  229. package/src/application/index.ts +0 -36
  230. package/src/application/queries/search-memory.query.ts +0 -237
  231. package/src/application/services/memory-application-service.ts +0 -236
  232. package/src/cache-manager.ts +0 -516
  233. package/src/database-provider.test.ts +0 -364
  234. package/src/database-provider.ts +0 -511
  235. package/src/domain/entities/memory-entry.ts +0 -289
  236. package/src/domain/index.ts +0 -35
  237. package/src/domain/repositories/memory-repository.interface.ts +0 -120
  238. package/src/domain/services/memory-domain-service.ts +0 -403
  239. package/src/hnsw-index.ts +0 -1013
  240. package/src/hybrid-backend.test.ts +0 -399
  241. package/src/hybrid-backend.ts +0 -694
  242. package/src/index.ts +0 -515
  243. package/src/infrastructure/index.ts +0 -23
  244. package/src/infrastructure/repositories/hybrid-memory-repository.ts +0 -516
  245. package/src/migration.ts +0 -669
  246. package/src/query-builder.ts +0 -542
  247. package/src/sqlite-backend.ts +0 -732
  248. package/src/sqljs-backend.ts +0 -763
  249. package/src/types.ts +0 -727
  250. package/tmp.json +0 -0
  251. package/tsconfig.json +0 -9
  252. package/tsconfig.tsbuildinfo +0 -1
  253. package/verify-cross-platform.ts +0 -170
@@ -1,535 +0,0 @@
1
- /**
2
- * Cache Hit Rate Benchmark
3
- *
4
- * Target: <0.1ms for cache hits
5
- *
6
- * Measures cache performance including hit rate,
7
- * lookup time, and eviction strategies.
8
- */
9
-
10
- import { benchmark, BenchmarkRunner, formatTime, meetsTarget } from '../framework/benchmark.js';
11
-
12
- // ============================================================================
13
- // Cache Implementations
14
- // ============================================================================
15
-
16
- /**
17
- * Simple LRU Cache implementation
18
- */
19
- class LRUCache<K, V> {
20
- private cache = new Map<K, V>();
21
- private maxSize: number;
22
- private hits = 0;
23
- private misses = 0;
24
-
25
- constructor(maxSize: number) {
26
- this.maxSize = maxSize;
27
- }
28
-
29
- get(key: K): V | undefined {
30
- const value = this.cache.get(key);
31
- if (value !== undefined) {
32
- // Move to end (most recently used)
33
- this.cache.delete(key);
34
- this.cache.set(key, value);
35
- this.hits++;
36
- return value;
37
- }
38
- this.misses++;
39
- return undefined;
40
- }
41
-
42
- set(key: K, value: V): void {
43
- if (this.cache.has(key)) {
44
- this.cache.delete(key);
45
- } else if (this.cache.size >= this.maxSize) {
46
- // Evict oldest (first) entry
47
- const firstKey = this.cache.keys().next().value;
48
- this.cache.delete(firstKey);
49
- }
50
- this.cache.set(key, value);
51
- }
52
-
53
- get hitRate(): number {
54
- const total = this.hits + this.misses;
55
- return total > 0 ? this.hits / total : 0;
56
- }
57
-
58
- get size(): number {
59
- return this.cache.size;
60
- }
61
-
62
- clear(): void {
63
- this.cache.clear();
64
- this.hits = 0;
65
- this.misses = 0;
66
- }
67
- }
68
-
69
- /**
70
- * TTL Cache with expiration
71
- */
72
- class TTLCache<K, V> {
73
- private cache = new Map<K, { value: V; expiry: number }>();
74
- private defaultTTL: number;
75
- private hits = 0;
76
- private misses = 0;
77
-
78
- constructor(defaultTTL: number = 60000) {
79
- this.defaultTTL = defaultTTL;
80
- }
81
-
82
- get(key: K): V | undefined {
83
- const entry = this.cache.get(key);
84
- if (entry !== undefined) {
85
- if (Date.now() < entry.expiry) {
86
- this.hits++;
87
- return entry.value;
88
- }
89
- // Expired
90
- this.cache.delete(key);
91
- }
92
- this.misses++;
93
- return undefined;
94
- }
95
-
96
- set(key: K, value: V, ttl?: number): void {
97
- const expiry = Date.now() + (ttl || this.defaultTTL);
98
- this.cache.set(key, { value, expiry });
99
- }
100
-
101
- get hitRate(): number {
102
- const total = this.hits + this.misses;
103
- return total > 0 ? this.hits / total : 0;
104
- }
105
-
106
- get size(): number {
107
- return this.cache.size;
108
- }
109
-
110
- cleanup(): number {
111
- const now = Date.now();
112
- let cleaned = 0;
113
- for (const [key, entry] of this.cache) {
114
- if (now >= entry.expiry) {
115
- this.cache.delete(key);
116
- cleaned++;
117
- }
118
- }
119
- return cleaned;
120
- }
121
-
122
- clear(): void {
123
- this.cache.clear();
124
- this.hits = 0;
125
- this.misses = 0;
126
- }
127
- }
128
-
129
- /**
130
- * Two-level cache (L1 fast, L2 larger)
131
- */
132
- class TwoLevelCache<K, V> {
133
- private l1: LRUCache<K, V>;
134
- private l2: LRUCache<K, V>;
135
- private l1Hits = 0;
136
- private l2Hits = 0;
137
- private misses = 0;
138
-
139
- constructor(l1Size: number = 100, l2Size: number = 1000) {
140
- this.l1 = new LRUCache<K, V>(l1Size);
141
- this.l2 = new LRUCache<K, V>(l2Size);
142
- }
143
-
144
- get(key: K): V | undefined {
145
- // Check L1 first
146
- let value = this.l1.get(key);
147
- if (value !== undefined) {
148
- this.l1Hits++;
149
- return value;
150
- }
151
-
152
- // Check L2
153
- value = this.l2.get(key);
154
- if (value !== undefined) {
155
- this.l2Hits++;
156
- // Promote to L1
157
- this.l1.set(key, value);
158
- return value;
159
- }
160
-
161
- this.misses++;
162
- return undefined;
163
- }
164
-
165
- set(key: K, value: V): void {
166
- this.l1.set(key, value);
167
- this.l2.set(key, value);
168
- }
169
-
170
- get stats(): { l1HitRate: number; l2HitRate: number; missRate: number } {
171
- const total = this.l1Hits + this.l2Hits + this.misses;
172
- return {
173
- l1HitRate: total > 0 ? this.l1Hits / total : 0,
174
- l2HitRate: total > 0 ? this.l2Hits / total : 0,
175
- missRate: total > 0 ? this.misses / total : 0,
176
- };
177
- }
178
-
179
- clear(): void {
180
- this.l1.clear();
181
- this.l2.clear();
182
- this.l1Hits = 0;
183
- this.l2Hits = 0;
184
- this.misses = 0;
185
- }
186
- }
187
-
188
- /**
189
- * Memoization cache for function results
190
- */
191
- class MemoCache<T extends (...args: unknown[]) => unknown> {
192
- private cache = new Map<string, ReturnType<T>>();
193
- private fn: T;
194
-
195
- constructor(fn: T) {
196
- this.fn = fn;
197
- }
198
-
199
- call(...args: Parameters<T>): ReturnType<T> {
200
- const key = JSON.stringify(args);
201
- if (this.cache.has(key)) {
202
- return this.cache.get(key)!;
203
- }
204
- const result = this.fn(...args) as ReturnType<T>;
205
- this.cache.set(key, result);
206
- return result;
207
- }
208
-
209
- get size(): number {
210
- return this.cache.size;
211
- }
212
-
213
- clear(): void {
214
- this.cache.clear();
215
- }
216
- }
217
-
218
- // ============================================================================
219
- // Benchmark Suite
220
- // ============================================================================
221
-
222
- export async function runCacheHitRateBenchmarks(): Promise<void> {
223
- const runner = new BenchmarkRunner('Cache Hit Rate');
224
-
225
- console.log('\n--- Cache Hit Rate Benchmarks ---\n');
226
-
227
- // Prepare test data
228
- const testKeys = Array.from({ length: 10000 }, (_, i) => `key-${i}`);
229
- const testValues = testKeys.map((k) => ({ key: k, data: Math.random() }));
230
-
231
- // Benchmark 1: LRU Cache - Cache Hit
232
- const lruCache = new LRUCache<string, object>(1000);
233
-
234
- // Pre-populate cache
235
- for (let i = 0; i < 1000; i++) {
236
- lruCache.set(testKeys[i]!, testValues[i]!);
237
- }
238
-
239
- const lruHitResult = await runner.run(
240
- 'lru-cache-hit',
241
- async () => {
242
- lruCache.get(testKeys[500]!);
243
- },
244
- { iterations: 100000 }
245
- );
246
-
247
- console.log(`LRU Cache Hit: ${formatTime(lruHitResult.mean)}`);
248
- const hitTarget = meetsTarget('cache-hit', lruHitResult.mean);
249
- console.log(` Target (<0.1ms): ${hitTarget.met ? 'PASS' : 'FAIL'}`);
250
-
251
- // Benchmark 2: LRU Cache - Cache Miss
252
- const lruMissResult = await runner.run(
253
- 'lru-cache-miss',
254
- async () => {
255
- lruCache.get('non-existent-key');
256
- },
257
- { iterations: 100000 }
258
- );
259
-
260
- console.log(`LRU Cache Miss: ${formatTime(lruMissResult.mean)}`);
261
-
262
- // Benchmark 3: LRU Cache - Set Operation
263
- const lruSetResult = await runner.run(
264
- 'lru-cache-set',
265
- async () => {
266
- lruCache.set(`new-key-${Date.now()}`, { data: 'test' });
267
- },
268
- { iterations: 10000 }
269
- );
270
-
271
- console.log(`LRU Cache Set: ${formatTime(lruSetResult.mean)}`);
272
-
273
- // Benchmark 4: TTL Cache - Hit
274
- const ttlCache = new TTLCache<string, object>(60000);
275
-
276
- for (let i = 0; i < 1000; i++) {
277
- ttlCache.set(testKeys[i]!, testValues[i]!);
278
- }
279
-
280
- const ttlHitResult = await runner.run(
281
- 'ttl-cache-hit',
282
- async () => {
283
- ttlCache.get(testKeys[500]!);
284
- },
285
- { iterations: 100000 }
286
- );
287
-
288
- console.log(`TTL Cache Hit: ${formatTime(ttlHitResult.mean)}`);
289
-
290
- // Benchmark 5: TTL Cache - Cleanup
291
- // Add some expired entries
292
- for (let i = 0; i < 100; i++) {
293
- ttlCache.set(`expired-${i}`, { data: i }, -1); // Already expired
294
- }
295
-
296
- const ttlCleanupResult = await runner.run(
297
- 'ttl-cache-cleanup',
298
- async () => {
299
- ttlCache.cleanup();
300
- },
301
- { iterations: 1000 }
302
- );
303
-
304
- console.log(`TTL Cache Cleanup: ${formatTime(ttlCleanupResult.mean)}`);
305
-
306
- // Benchmark 6: Two-Level Cache - L1 Hit
307
- const twoLevelCache = new TwoLevelCache<string, object>(100, 1000);
308
-
309
- for (let i = 0; i < 1000; i++) {
310
- twoLevelCache.set(testKeys[i]!, testValues[i]!);
311
- }
312
-
313
- // Warm up L1
314
- for (let i = 0; i < 50; i++) {
315
- twoLevelCache.get(testKeys[i]!);
316
- }
317
-
318
- const l1HitResult = await runner.run(
319
- 'two-level-cache-l1-hit',
320
- async () => {
321
- twoLevelCache.get(testKeys[25]!);
322
- },
323
- { iterations: 100000 }
324
- );
325
-
326
- console.log(`Two-Level Cache L1 Hit: ${formatTime(l1HitResult.mean)}`);
327
-
328
- // Benchmark 7: Two-Level Cache - L2 Hit (promotes to L1)
329
- const l2HitResult = await runner.run(
330
- 'two-level-cache-l2-hit',
331
- async () => {
332
- twoLevelCache.get(testKeys[500]!);
333
- },
334
- { iterations: 50000 }
335
- );
336
-
337
- console.log(`Two-Level Cache L2 Hit: ${formatTime(l2HitResult.mean)}`);
338
-
339
- // Benchmark 8: Memoization Cache
340
- const expensiveFn = (n: number): number => {
341
- let result = 0;
342
- for (let i = 0; i < n; i++) {
343
- result += Math.sqrt(i);
344
- }
345
- return result;
346
- };
347
-
348
- const memoCache = new MemoCache(expensiveFn);
349
-
350
- // Prime the cache
351
- memoCache.call(1000);
352
-
353
- const memoHitResult = await runner.run(
354
- 'memo-cache-hit',
355
- async () => {
356
- memoCache.call(1000);
357
- },
358
- { iterations: 100000 }
359
- );
360
-
361
- console.log(`Memo Cache Hit: ${formatTime(memoHitResult.mean)}`);
362
-
363
- const memoMissResult = await runner.run(
364
- 'memo-cache-miss',
365
- async () => {
366
- memoCache.call(Math.floor(Math.random() * 10000000));
367
- },
368
- { iterations: 100 }
369
- );
370
-
371
- console.log(`Memo Cache Miss (compute): ${formatTime(memoMissResult.mean)}`);
372
-
373
- // Benchmark 9: Cache with Different Hit Rates
374
- const cache90 = new LRUCache<string, object>(1000);
375
- for (let i = 0; i < 1000; i++) {
376
- cache90.set(testKeys[i]!, testValues[i]!);
377
- }
378
-
379
- const hitRate90Result = await runner.run(
380
- 'workload-90-percent-hits',
381
- async () => {
382
- const isHit = Math.random() < 0.9;
383
- if (isHit) {
384
- cache90.get(testKeys[Math.floor(Math.random() * 1000)]!);
385
- } else {
386
- cache90.get(`miss-${Date.now()}`);
387
- }
388
- },
389
- { iterations: 10000 }
390
- );
391
-
392
- console.log(`90% Hit Rate Workload: ${formatTime(hitRate90Result.mean)}`);
393
-
394
- // Benchmark 10: Cache Eviction Under Pressure
395
- const smallCache = new LRUCache<string, object>(100);
396
-
397
- const evictionResult = await runner.run(
398
- 'cache-with-eviction',
399
- async () => {
400
- // Write 200 items to a cache of size 100
401
- for (let i = 0; i < 200; i++) {
402
- smallCache.set(`evict-key-${i}`, { data: i });
403
- }
404
- },
405
- { iterations: 100 }
406
- );
407
-
408
- console.log(`Cache with Eviction (200 to 100): ${formatTime(evictionResult.mean)}`);
409
-
410
- // Summary
411
- console.log('\n--- Summary ---');
412
- console.log(`LRU hit: ${formatTime(lruHitResult.mean)} (${lruHitResult.opsPerSecond.toFixed(0)} ops/sec)`);
413
- console.log(`LRU miss: ${formatTime(lruMissResult.mean)}`);
414
- console.log(`TTL hit: ${formatTime(ttlHitResult.mean)}`);
415
- console.log(`L1 hit: ${formatTime(l1HitResult.mean)}`);
416
- console.log(`L2 hit: ${formatTime(l2HitResult.mean)}`);
417
- console.log(`Memo hit: ${formatTime(memoHitResult.mean)}`);
418
- console.log(`\nTwo-Level Cache Stats:`, twoLevelCache.stats);
419
-
420
- // Print full results
421
- runner.printResults();
422
- }
423
-
424
- // ============================================================================
425
- // Cache Optimization Strategies
426
- // ============================================================================
427
-
428
- export const cacheOptimizations = {
429
- /**
430
- * Optimal cache sizing
431
- */
432
- optimalSizing: {
433
- description: 'Size cache based on working set and memory constraints',
434
- expectedImprovement: '20-50% hit rate',
435
- implementation: `
436
- function calculateOptimalCacheSize(workingSetSize: number, memoryLimit: number): number {
437
- const avgItemSize = estimateAverageItemSize();
438
- const maxItems = Math.floor(memoryLimit / avgItemSize);
439
- return Math.min(workingSetSize * 0.8, maxItems);
440
- }
441
- `,
442
- },
443
-
444
- /**
445
- * Adaptive TTL
446
- */
447
- adaptiveTTL: {
448
- description: 'Adjust TTL based on access patterns',
449
- expectedImprovement: '10-30% hit rate',
450
- implementation: `
451
- class AdaptiveTTLCache {
452
- private accessCounts = new Map<string, number>();
453
-
454
- getTTL(key: string): number {
455
- const count = this.accessCounts.get(key) || 0;
456
- // Hot keys get longer TTL
457
- return this.baseTTL * Math.min(10, 1 + Math.log2(count + 1));
458
- }
459
- }
460
- `,
461
- },
462
-
463
- /**
464
- * Probabilistic early expiration
465
- */
466
- probabilisticExpiry: {
467
- description: 'Refresh items before expiry to avoid thundering herd',
468
- expectedImprovement: 'Reduces load spikes by 80%',
469
- implementation: `
470
- function shouldRefresh(ttl: number, remaining: number): boolean {
471
- const beta = 1.0;
472
- const delta = ttl - remaining;
473
- const xFetch = Date.now() + delta * beta * Math.log(Math.random());
474
- return xFetch > Date.now() + remaining;
475
- }
476
- `,
477
- },
478
-
479
- /**
480
- * Segmented cache
481
- */
482
- segmentedCache: {
483
- description: 'Reduce lock contention with segmented caches',
484
- expectedImprovement: '2-4x concurrent performance',
485
- implementation: `
486
- class SegmentedCache<K, V> {
487
- private segments: LRUCache<K, V>[];
488
-
489
- constructor(numSegments: number, sizePerSegment: number) {
490
- this.segments = Array.from(
491
- { length: numSegments },
492
- () => new LRUCache<K, V>(sizePerSegment)
493
- );
494
- }
495
-
496
- private getSegment(key: K): LRUCache<K, V> {
497
- const hash = this.hash(key);
498
- return this.segments[hash % this.segments.length]!;
499
- }
500
- }
501
- `,
502
- },
503
-
504
- /**
505
- * Read-through caching
506
- */
507
- readThrough: {
508
- description: 'Automatically fetch missing items',
509
- expectedImprovement: 'Simplifies code, consistent performance',
510
- implementation: `
511
- class ReadThroughCache<K, V> {
512
- constructor(
513
- private cache: LRUCache<K, V>,
514
- private loader: (key: K) => Promise<V>
515
- ) {}
516
-
517
- async get(key: K): Promise<V> {
518
- let value = this.cache.get(key);
519
- if (value === undefined) {
520
- value = await this.loader(key);
521
- this.cache.set(key, value);
522
- }
523
- return value;
524
- }
525
- }
526
- `,
527
- },
528
- };
529
-
530
- // Run if executed directly
531
- if (import.meta.url === `file://${process.argv[1]}`) {
532
- runCacheHitRateBenchmarks().catch(console.error);
533
- }
534
-
535
- export default runCacheHitRateBenchmarks;