claude-flow-novice 2.0.3 → 2.0.4

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 (272) hide show
  1. package/dist/src/cli/commands/guidance.js +487 -668
  2. package/dist/src/cli/commands/index-validate.js +18 -29
  3. package/dist/src/cli/commands/mcp-troubleshoot.js +230 -282
  4. package/dist/src/cli/commands/neural-goal-init.js +92 -125
  5. package/dist/src/cli/commands/swarm-exec.js +317 -393
  6. package/dist/src/cli/commands/swarm.js +1 -1
  7. package/dist/src/cli/commands/validate-framework.js +983 -1100
  8. package/dist/src/cli/commands/validate.js +144 -223
  9. package/dist/src/cli/simple-commands/__tests__/agent.test.js +265 -277
  10. package/dist/src/cli/simple-commands/__tests__/memory.test.js +6 -7
  11. package/dist/src/cli/simple-commands/__tests__/swarm.test.js +373 -356
  12. package/dist/src/cli/simple-commands/__tests__/task.test.js +6 -7
  13. package/dist/src/cli/simple-commands/agent.js +157 -193
  14. package/dist/src/cli/simple-commands/analysis.js +336 -446
  15. package/dist/src/cli/simple-commands/automation-executor.js +1095 -1339
  16. package/dist/src/cli/simple-commands/automation.js +481 -469
  17. package/dist/src/cli/simple-commands/batch-manager.js +261 -313
  18. package/dist/src/cli/simple-commands/claude-telemetry.js +241 -267
  19. package/dist/src/cli/simple-commands/claude-track.js +68 -90
  20. package/dist/src/cli/simple-commands/concurrent-display.js +266 -320
  21. package/dist/src/cli/simple-commands/config.js +245 -290
  22. package/dist/src/cli/simple-commands/coordination.js +182 -234
  23. package/dist/src/cli/simple-commands/enhanced-ui-views.js +812 -615
  24. package/dist/src/cli/simple-commands/enhanced-webui-complete.js +922 -981
  25. package/dist/src/cli/simple-commands/fix-hook-variables.js +274 -294
  26. package/dist/src/cli/simple-commands/github/gh-coordinator.js +378 -457
  27. package/dist/src/cli/simple-commands/github/github-api.js +535 -574
  28. package/dist/src/cli/simple-commands/github/init.js +276 -303
  29. package/dist/src/cli/simple-commands/github.js +222 -247
  30. package/dist/src/cli/simple-commands/goal.js +51 -63
  31. package/dist/src/cli/simple-commands/hive-mind/auto-save-middleware.js +208 -278
  32. package/dist/src/cli/simple-commands/hive-mind/communication.js +601 -696
  33. package/dist/src/cli/simple-commands/hive-mind/core.js +907 -979
  34. package/dist/src/cli/simple-commands/hive-mind/db-optimizer.js +406 -655
  35. package/dist/src/cli/simple-commands/hive-mind/mcp-wrapper.js +1125 -1245
  36. package/dist/src/cli/simple-commands/hive-mind/memory.js +854 -1090
  37. package/dist/src/cli/simple-commands/hive-mind/performance-optimizer.js +459 -574
  38. package/dist/src/cli/simple-commands/hive-mind/performance-test.js +263 -347
  39. package/dist/src/cli/simple-commands/hive-mind/queen.js +727 -768
  40. package/dist/src/cli/simple-commands/hive-mind/session-manager.js +745 -1049
  41. package/dist/src/cli/simple-commands/hive-mind-optimize.js +227 -283
  42. package/dist/src/cli/simple-commands/hive-mind-wizard.js +174 -217
  43. package/dist/src/cli/simple-commands/hive-mind.js +1842 -2283
  44. package/dist/src/cli/simple-commands/hive.js +90 -79
  45. package/dist/src/cli/simple-commands/hook-safety.js +431 -521
  46. package/dist/src/cli/simple-commands/hooks/session-start-soul.js +203 -254
  47. package/dist/src/cli/simple-commands/hooks.js +1064 -1204
  48. package/dist/src/cli/simple-commands/init/agent-copier.js +294 -319
  49. package/dist/src/cli/simple-commands/init/batch-init.js +496 -562
  50. package/dist/src/cli/simple-commands/init/claude-commands/claude-flow-commands.js +13 -19
  51. package/dist/src/cli/simple-commands/init/claude-commands/optimized-claude-flow-commands.js +13 -19
  52. package/dist/src/cli/simple-commands/init/claude-commands/optimized-slash-commands.js +61 -88
  53. package/dist/src/cli/simple-commands/init/claude-commands/optimized-sparc-commands.js +125 -150
  54. package/dist/src/cli/simple-commands/init/claude-commands/slash-commands.js +42 -49
  55. package/dist/src/cli/simple-commands/init/claude-commands/sparc-commands.js +43 -61
  56. package/dist/src/cli/simple-commands/init/copy-revised-templates.js +141 -147
  57. package/dist/src/cli/simple-commands/init/executable-wrapper.js +31 -44
  58. package/dist/src/cli/simple-commands/init/gitignore-updater.js +64 -90
  59. package/dist/src/cli/simple-commands/init/help.js +104 -107
  60. package/dist/src/cli/simple-commands/init/hive-mind-init.js +509 -528
  61. package/dist/src/cli/simple-commands/init/index.js +1510 -1759
  62. package/dist/src/cli/simple-commands/init/performance-monitor.js +234 -317
  63. package/dist/src/cli/simple-commands/init/rollback/backup-manager.js +441 -504
  64. package/dist/src/cli/simple-commands/init/rollback/index.js +289 -364
  65. package/dist/src/cli/simple-commands/init/rollback/recovery-manager.js +652 -728
  66. package/dist/src/cli/simple-commands/init/rollback/rollback-executor.js +416 -481
  67. package/dist/src/cli/simple-commands/init/rollback/state-tracker.js +369 -448
  68. package/dist/src/cli/simple-commands/init/sparc/roo-readme.js +1 -2
  69. package/dist/src/cli/simple-commands/init/sparc/roomodes-config.js +122 -99
  70. package/dist/src/cli/simple-commands/init/sparc/workflows.js +32 -37
  71. package/dist/src/cli/simple-commands/init/sparc-structure.js +55 -62
  72. package/dist/src/cli/simple-commands/init/template-copier.js +421 -533
  73. package/dist/src/cli/simple-commands/init/templates/coordination-md.js +3 -6
  74. package/dist/src/cli/simple-commands/init/templates/enhanced-templates.js +344 -318
  75. package/dist/src/cli/simple-commands/init/templates/github-safe-enhanced.js +173 -218
  76. package/dist/src/cli/simple-commands/init/templates/github-safe.js +65 -75
  77. package/dist/src/cli/simple-commands/init/templates/memory-bank-md.js +3 -6
  78. package/dist/src/cli/simple-commands/init/templates/readme-files.js +2 -4
  79. package/dist/src/cli/simple-commands/init/templates/safe-hook-patterns.js +187 -230
  80. package/dist/src/cli/simple-commands/init/templates/sparc-modes.js +53 -80
  81. package/dist/src/cli/simple-commands/init/templates/verification-claude-md.js +101 -85
  82. package/dist/src/cli/simple-commands/init/validation/config-validator.js +283 -330
  83. package/dist/src/cli/simple-commands/init/validation/health-checker.js +495 -561
  84. package/dist/src/cli/simple-commands/init/validation/index.js +302 -358
  85. package/dist/src/cli/simple-commands/init/validation/mode-validator.js +308 -359
  86. package/dist/src/cli/simple-commands/init/validation/post-init-validator.js +389 -366
  87. package/dist/src/cli/simple-commands/init/validation/pre-init-validator.js +270 -268
  88. package/dist/src/cli/simple-commands/init/validation/test-runner.js +427 -447
  89. package/dist/src/cli/simple-commands/init.js +1 -2
  90. package/dist/src/cli/simple-commands/mcp-health.js +131 -158
  91. package/dist/src/cli/simple-commands/mcp-integration-layer.js +533 -634
  92. package/dist/src/cli/simple-commands/mcp.js +345 -400
  93. package/dist/src/cli/simple-commands/memory-consolidation.js +426 -537
  94. package/dist/src/cli/simple-commands/memory.js +247 -311
  95. package/dist/src/cli/simple-commands/migrate-hooks.js +39 -46
  96. package/dist/src/cli/simple-commands/monitor.js +294 -363
  97. package/dist/src/cli/simple-commands/neural.js +51 -65
  98. package/dist/src/cli/simple-commands/pair-autofix-only.js +538 -662
  99. package/dist/src/cli/simple-commands/pair-basic.js +528 -656
  100. package/dist/src/cli/simple-commands/pair-old.js +430 -543
  101. package/dist/src/cli/simple-commands/pair-working.js +615 -751
  102. package/dist/src/cli/simple-commands/pair.js +615 -751
  103. package/dist/src/cli/simple-commands/performance-hooks.js +83 -111
  104. package/dist/src/cli/simple-commands/performance-metrics.js +348 -433
  105. package/dist/src/cli/simple-commands/process-ui-enhanced.js +708 -787
  106. package/dist/src/cli/simple-commands/process-ui.js +230 -254
  107. package/dist/src/cli/simple-commands/realtime-update-system.js +525 -611
  108. package/dist/src/cli/simple-commands/sparc/architecture.js +1704 -1530
  109. package/dist/src/cli/simple-commands/sparc/commands.js +438 -516
  110. package/dist/src/cli/simple-commands/sparc/completion.js +1224 -1481
  111. package/dist/src/cli/simple-commands/sparc/coordinator.js +913 -978
  112. package/dist/src/cli/simple-commands/sparc/index.js +241 -298
  113. package/dist/src/cli/simple-commands/sparc/phase-base.js +314 -390
  114. package/dist/src/cli/simple-commands/sparc/pseudocode.js +965 -869
  115. package/dist/src/cli/simple-commands/sparc/refinement.js +980 -1273
  116. package/dist/src/cli/simple-commands/sparc/specification.js +559 -645
  117. package/dist/src/cli/simple-commands/sparc-modes/architect.js +1 -1
  118. package/dist/src/cli/simple-commands/sparc-modes/ask.js +1 -1
  119. package/dist/src/cli/simple-commands/sparc-modes/code.js +1 -1
  120. package/dist/src/cli/simple-commands/sparc-modes/debug.js +1 -1
  121. package/dist/src/cli/simple-commands/sparc-modes/devops.js +1 -1
  122. package/dist/src/cli/simple-commands/sparc-modes/docs-writer.js +1 -1
  123. package/dist/src/cli/simple-commands/sparc-modes/generic.js +1 -1
  124. package/dist/src/cli/simple-commands/sparc-modes/index.js +47 -55
  125. package/dist/src/cli/simple-commands/sparc-modes/integration.js +1 -1
  126. package/dist/src/cli/simple-commands/sparc-modes/mcp.js +1 -1
  127. package/dist/src/cli/simple-commands/sparc-modes/monitoring.js +1 -1
  128. package/dist/src/cli/simple-commands/sparc-modes/optimization.js +1 -1
  129. package/dist/src/cli/simple-commands/sparc-modes/security-review.js +1 -1
  130. package/dist/src/cli/simple-commands/sparc-modes/sparc-orchestrator.js +1 -1
  131. package/dist/src/cli/simple-commands/sparc-modes/spec-pseudocode.js +1 -1
  132. package/dist/src/cli/simple-commands/sparc-modes/supabase-admin.js +1 -1
  133. package/dist/src/cli/simple-commands/sparc-modes/swarm.js +101 -87
  134. package/dist/src/cli/simple-commands/sparc-modes/tdd.js +1 -1
  135. package/dist/src/cli/simple-commands/sparc-modes/tutorial.js +1 -1
  136. package/dist/src/cli/simple-commands/sparc.js +465 -493
  137. package/dist/src/cli/simple-commands/start-ui.js +108 -132
  138. package/dist/src/cli/simple-commands/start-wrapper.js +240 -268
  139. package/dist/src/cli/simple-commands/start.js +1 -1
  140. package/dist/src/cli/simple-commands/status.js +254 -275
  141. package/dist/src/cli/simple-commands/stream-chain-clean.js +128 -171
  142. package/dist/src/cli/simple-commands/stream-chain-fixed.js +61 -82
  143. package/dist/src/cli/simple-commands/stream-chain-real.js +267 -331
  144. package/dist/src/cli/simple-commands/stream-chain-working.js +211 -263
  145. package/dist/src/cli/simple-commands/stream-chain.js +260 -318
  146. package/dist/src/cli/simple-commands/stream-processor.js +290 -315
  147. package/dist/src/cli/simple-commands/swarm-executor.js +189 -222
  148. package/dist/src/cli/simple-commands/swarm-metrics-integration.js +208 -300
  149. package/dist/src/cli/simple-commands/swarm-ui.js +623 -703
  150. package/dist/src/cli/simple-commands/swarm-webui-integration.js +258 -286
  151. package/dist/src/cli/simple-commands/swarm.js +887 -1082
  152. package/dist/src/cli/simple-commands/task.js +161 -206
  153. package/dist/src/cli/simple-commands/timestamp-fix.js +59 -89
  154. package/dist/src/cli/simple-commands/token-tracker.js +258 -316
  155. package/dist/src/cli/simple-commands/tool-execution-framework.js +433 -519
  156. package/dist/src/cli/simple-commands/train-and-stream.js +275 -331
  157. package/dist/src/cli/simple-commands/training-pipeline.js +619 -725
  158. package/dist/src/cli/simple-commands/training.js +170 -227
  159. package/dist/src/cli/simple-commands/verification-hooks.js +261 -284
  160. package/dist/src/cli/simple-commands/verification-integration.js +389 -417
  161. package/dist/src/cli/simple-commands/verification-training-integration.js +486 -606
  162. package/dist/src/cli/simple-commands/verification.js +493 -513
  163. package/dist/src/cli/simple-commands/web-server.js +766 -836
  164. package/dist/src/cli/simple-commands/webui-validator.js +106 -124
  165. package/dist/src/coordination/event-bus/demo-wasm-integration.js +212 -251
  166. package/dist/src/coordination/event-bus/qe-event-bus.js +608 -748
  167. package/dist/src/coordination/event-bus/qe-event-bus.test.js +379 -454
  168. package/dist/src/coordination/iteration-tracker.js +363 -454
  169. package/dist/src/enterprise/analytics-manager.js +1135 -0
  170. package/dist/src/enterprise/audit-manager.js +1115 -0
  171. package/dist/src/enterprise/cloud-manager.js +891 -0
  172. package/dist/src/enterprise/deployment-manager.js +966 -0
  173. package/dist/src/enterprise/index.js +6 -0
  174. package/dist/src/enterprise/project-manager.js +584 -0
  175. package/dist/src/enterprise/security-manager.js +991 -0
  176. package/dist/src/index.js +1 -1
  177. package/dist/src/mcp/DEPRECATED.js +46 -60
  178. package/dist/src/mcp/fixes/mcp-error-fixes.js +115 -134
  179. package/dist/src/mcp/implementations/agent-tracker.js +114 -128
  180. package/dist/src/mcp/implementations/daa-tools.js +292 -350
  181. package/dist/src/mcp/implementations/workflow-tools.js +329 -361
  182. package/dist/src/mcp/mcp-config-manager.js +1183 -1331
  183. package/dist/src/mcp/mcp-server-novice-simplified.js +11 -17
  184. package/dist/src/mcp/mcp-server-novice.js +11 -17
  185. package/dist/src/mcp/mcp-server-sdk.js +11 -17
  186. package/dist/src/mcp/mcp-server.js +1620 -1484
  187. package/dist/src/mcp/ruv-swarm-wrapper.js +209 -239
  188. package/dist/src/memory/advanced-serializer.js +609 -589
  189. package/dist/src/memory/enhanced-examples.js +220 -305
  190. package/dist/src/memory/enhanced-memory.js +295 -336
  191. package/dist/src/memory/enhanced-session-serializer.js +408 -492
  192. package/dist/src/memory/fallback-memory-system.js +900 -1021
  193. package/dist/src/memory/fallback-store.js +93 -131
  194. package/dist/src/memory/high-performance-serialization.js +592 -730
  195. package/dist/src/memory/in-memory-store.js +161 -213
  196. package/dist/src/memory/index.js +123 -157
  197. package/dist/src/memory/lock-free-structures.js +578 -764
  198. package/dist/src/memory/memory-mapped-persistence.js +585 -766
  199. package/dist/src/memory/memory-pressure-manager.js +569 -707
  200. package/dist/src/memory/migration.js +358 -445
  201. package/dist/src/memory/shared-memory.js +641 -768
  202. package/dist/src/memory/sqlite-store.js +245 -325
  203. package/dist/src/memory/sqlite-wrapper.js +122 -151
  204. package/dist/src/memory/swarm-memory.js +470 -603
  205. package/dist/src/memory/test-example.js +126 -134
  206. package/dist/src/memory/ultra-fast-memory-store.js +622 -821
  207. package/dist/src/memory/unified-memory-manager.js +356 -437
  208. package/dist/src/migration/index.js +92 -0
  209. package/dist/src/migration/logger.js +121 -0
  210. package/dist/src/migration/migration-analyzer.js +268 -0
  211. package/dist/src/migration/migration-runner.js +522 -0
  212. package/dist/src/migration/migration-validator.js +285 -0
  213. package/dist/src/migration/progress-reporter.js +150 -0
  214. package/dist/src/migration/rollback-manager.js +321 -0
  215. package/dist/src/migration/tests/migration-system.test.js +7 -0
  216. package/dist/src/migration/types.js +3 -0
  217. package/dist/src/swarm/CodeRefactoringSwarm.js +777 -952
  218. package/dist/src/swarm/__tests__/integration.test.js +227 -0
  219. package/dist/src/swarm/__tests__/prompt-copier.test.js +344 -0
  220. package/dist/src/swarm/advanced-orchestrator.js +1095 -0
  221. package/dist/src/swarm/claude-code-interface.js +961 -0
  222. package/dist/src/swarm/claude-flow-executor.js +229 -0
  223. package/dist/src/swarm/consensus-coordinator.js +475 -0
  224. package/dist/src/swarm/coordinator.js +2993 -0
  225. package/dist/src/swarm/direct-executor.js +1180 -0
  226. package/dist/src/swarm/error-recovery/advanced-error-detection.js +691 -0
  227. package/dist/src/swarm/error-recovery/automated-recovery-workflows.js +998 -0
  228. package/dist/src/swarm/error-recovery/error-recovery-coordinator.js +1197 -0
  229. package/dist/src/swarm/error-recovery/recovery-monitoring.js +772 -0
  230. package/dist/src/swarm/error-recovery/resilience-architecture.js +714 -0
  231. package/dist/src/swarm/error-recovery/self-healing-mechanisms.js +1319 -0
  232. package/dist/src/swarm/error-recovery/test-error-recovery-effectiveness.js +808 -0
  233. package/dist/src/swarm/executor-v2.js +322 -0
  234. package/dist/src/swarm/executor.js +815 -0
  235. package/dist/src/swarm/hive-mind-integration.js +703 -0
  236. package/dist/src/swarm/index.js +41 -0
  237. package/dist/src/swarm/json-output-aggregator.js +267 -0
  238. package/dist/src/swarm/large-scale-coordinator.js +542 -0
  239. package/dist/src/swarm/mcp-integration-wrapper.js +628 -0
  240. package/dist/src/swarm/memory.js +1117 -0
  241. package/dist/src/swarm/optimizations/__tests__/optimization.test.js +348 -0
  242. package/dist/src/swarm/optimizations/async-file-manager.js +285 -0
  243. package/dist/src/swarm/optimizations/circular-buffer.js +162 -0
  244. package/dist/src/swarm/optimizations/connection-pool.js +244 -0
  245. package/dist/src/swarm/optimizations/index.js +28 -0
  246. package/dist/src/swarm/optimizations/optimized-executor.js +320 -0
  247. package/dist/src/swarm/optimizations/ttl-map.js +234 -0
  248. package/dist/src/swarm/prompt-cli.js +200 -0
  249. package/dist/src/swarm/prompt-copier-enhanced.js +202 -0
  250. package/dist/src/swarm/prompt-copier.js +381 -0
  251. package/dist/src/swarm/prompt-manager.js +295 -0
  252. package/dist/src/swarm/prompt-utils.js +310 -0
  253. package/dist/src/swarm/result-aggregator.js +718 -0
  254. package/dist/src/swarm/sparc-executor.js +1568 -0
  255. package/dist/src/swarm/strategies/auto.js +758 -0
  256. package/dist/src/swarm/strategies/base.js +128 -0
  257. package/dist/src/swarm/strategies/research.js +914 -0
  258. package/dist/src/swarm/strategies/strategy-metrics-patch.js +2 -0
  259. package/dist/src/swarm/types.js +52 -0
  260. package/dist/src/swarm/workers/copy-worker.js +56 -0
  261. package/dist/src/utils/__tests__/github-cli-safety-wrapper.test.js +332 -400
  262. package/dist/src/utils/github-cli-safe.js +56 -64
  263. package/dist/src/utils/github-cli-safety-wrapper.js +451 -546
  264. package/dist/src/utils/npx-isolated-cache.js +104 -119
  265. package/dist/src/utils/preference-manager.js +622 -652
  266. package/dist/src/utils/timezone-utils.js +86 -105
  267. package/dist/src/validators/epic-config-schema.js +214 -0
  268. package/dist/src/validators/index.js +10 -0
  269. package/dist/src/validators/swarm-init-validator.js +259 -0
  270. package/dist/src/validators/todowrite-batching-validator.js +215 -0
  271. package/dist/src/validators/todowrite-integration.js +187 -0
  272. package/package.json +2 -2
@@ -9,812 +9,626 @@
9
9
  * - Write operations: <500ns
10
10
  * - Zero lock contention
11
11
  * - Linear scalability with CPU cores
12
- */
13
-
14
- /**
12
+ */ /**
15
13
  * Atomic operations wrapper with performance optimizations
16
- */
17
- export class AtomicOperations {
18
- /**
14
+ */ export class AtomicOperations {
15
+ /**
19
16
  * Compare-and-swap with retry logic and backoff
20
- */
21
- static compareAndSwap32(buffer, offset, expected, value) {
22
- const view = new Uint32Array(buffer);
23
- const index = offset >> 2;
24
- return Atomics.compareExchange(view, index, expected, value);
25
- }
26
-
27
- /**
17
+ */ static compareAndSwap32(buffer, offset, expected, value) {
18
+ const view = new Uint32Array(buffer);
19
+ const index = offset >> 2;
20
+ return Atomics.compareExchange(view, index, expected, value);
21
+ }
22
+ /**
28
23
  * Compare-and-swap for 64-bit values (using two 32-bit operations)
29
- */
30
- static compareAndSwap64(buffer, offset, expectedLow, expectedHigh, valueLow, valueHigh) {
31
- const view = new Uint32Array(buffer);
32
- const lowIndex = offset >> 2;
33
- const highIndex = lowIndex + 1;
34
-
35
- // Atomic 64-bit CAS requires platform-specific implementation
36
- // This is a simplified version for demonstration
37
- while (true) {
38
- const currentLow = Atomics.load(view, lowIndex);
39
- const currentHigh = Atomics.load(view, highIndex);
40
-
41
- if (currentLow === expectedLow && currentHigh === expectedHigh) {
42
- const successLow = Atomics.compareExchange(view, lowIndex, expectedLow, valueLow);
43
- if (successLow === expectedLow) {
44
- const successHigh = Atomics.compareExchange(view, highIndex, expectedHigh, valueHigh);
45
- if (successHigh === expectedHigh) {
46
- return true;
47
- }
48
- // Rollback low if high failed
49
- Atomics.compareExchange(view, lowIndex, valueLow, expectedLow);
50
- }
51
- }
52
-
53
- // Exponential backoff
54
- this.backoff();
55
- return false;
56
- }
57
- }
58
-
59
- /**
24
+ */ static compareAndSwap64(buffer, offset, expectedLow, expectedHigh, valueLow, valueHigh) {
25
+ const view = new Uint32Array(buffer);
26
+ const lowIndex = offset >> 2;
27
+ const highIndex = lowIndex + 1;
28
+ // Atomic 64-bit CAS requires platform-specific implementation
29
+ // This is a simplified version for demonstration
30
+ while(true){
31
+ const currentLow = Atomics.load(view, lowIndex);
32
+ const currentHigh = Atomics.load(view, highIndex);
33
+ if (currentLow === expectedLow && currentHigh === expectedHigh) {
34
+ const successLow = Atomics.compareExchange(view, lowIndex, expectedLow, valueLow);
35
+ if (successLow === expectedLow) {
36
+ const successHigh = Atomics.compareExchange(view, highIndex, expectedHigh, valueHigh);
37
+ if (successHigh === expectedHigh) {
38
+ return true;
39
+ }
40
+ // Rollback low if high failed
41
+ Atomics.compareExchange(view, lowIndex, valueLow, expectedLow);
42
+ }
43
+ }
44
+ // Exponential backoff
45
+ this.backoff();
46
+ return false;
47
+ }
48
+ }
49
+ /**
60
50
  * Atomic increment with overflow protection
61
- */
62
- static atomicIncrement(buffer, offset) {
63
- const view = new Uint32Array(buffer);
64
- return Atomics.add(view, offset >> 2, 1);
65
- }
66
-
67
- /**
51
+ */ static atomicIncrement(buffer, offset) {
52
+ const view = new Uint32Array(buffer);
53
+ return Atomics.add(view, offset >> 2, 1);
54
+ }
55
+ /**
68
56
  * Atomic decrement with underflow protection
69
- */
70
- static atomicDecrement(buffer, offset) {
71
- const view = new Uint32Array(buffer);
72
- return Atomics.sub(view, offset >> 2, 1);
73
- }
74
-
75
- /**
57
+ */ static atomicDecrement(buffer, offset) {
58
+ const view = new Uint32Array(buffer);
59
+ return Atomics.sub(view, offset >> 2, 1);
60
+ }
61
+ /**
76
62
  * Load with acquire memory ordering
77
- */
78
- static loadAcquire(buffer, offset) {
79
- const view = new Uint32Array(buffer);
80
- return Atomics.load(view, offset >> 2);
81
- }
82
-
83
- /**
63
+ */ static loadAcquire(buffer, offset) {
64
+ const view = new Uint32Array(buffer);
65
+ return Atomics.load(view, offset >> 2);
66
+ }
67
+ /**
84
68
  * Store with release memory ordering
85
- */
86
- static storeRelease(buffer, offset, value) {
87
- const view = new Uint32Array(buffer);
88
- return Atomics.store(view, offset >> 2, value);
89
- }
90
-
91
- /**
69
+ */ static storeRelease(buffer, offset, value) {
70
+ const view = new Uint32Array(buffer);
71
+ return Atomics.store(view, offset >> 2, value);
72
+ }
73
+ /**
92
74
  * Exponential backoff for contention management
93
- */
94
- static backoff(attempt = 1) {
95
- const maxBackoff = Math.min(64, Math.pow(2, attempt));
96
- for (let i = 0; i < maxBackoff; i++) {
97
- // CPU-friendly spin without yielding
98
- }
99
- }
100
-
101
- /**
75
+ */ static backoff(attempt = 1) {
76
+ const maxBackoff = Math.min(64, Math.pow(2, attempt));
77
+ for(let i = 0; i < maxBackoff; i++){
78
+ // CPU-friendly spin without yielding
79
+ }
80
+ }
81
+ /**
102
82
  * Memory fence for ordering guarantees
103
- */
104
- static memoryFence() {
105
- // Use Atomics.notify/wait for memory synchronization
106
- const dummy = new Int32Array(new SharedArrayBuffer(4));
107
- Atomics.store(dummy, 0, 0);
108
- }
109
- }
110
-
83
+ */ static memoryFence() {
84
+ // Use Atomics.notify/wait for memory synchronization
85
+ const dummy = new Int32Array(new SharedArrayBuffer(4));
86
+ Atomics.store(dummy, 0, 0);
87
+ }
88
+ }
111
89
  /**
112
90
  * Lock-free hash table with linear probing and optimistic concurrency
113
- */
114
- export class LockFreeHashTable {
115
- constructor(sharedBuffer, bucketCount = 16384, bucketsOffset = 4096) {
116
- this.buffer = sharedBuffer;
117
- this.bucketCount = bucketCount;
118
- this.bucketSize = 32; // bytes per bucket
119
- this.bucketsOffset = bucketsOffset;
120
- this.loadFactor = 0.75; // Resize threshold
121
-
122
- this.initializeBuckets();
123
- }
124
-
125
- /**
91
+ */ export class LockFreeHashTable {
92
+ /**
126
93
  * Initialize bucket structure in shared memory
127
- */
128
- initializeBuckets() {
129
- const view = new Uint32Array(this.buffer);
130
- const bucketView = view.subarray(this.bucketsOffset >> 2);
131
-
132
- for (let i = 0; i < this.bucketCount; i++) {
133
- const bucketBase = i * (this.bucketSize >> 2);
134
- bucketView[bucketBase] = 0; // head = null
135
- bucketView[bucketBase + 1] = 0; // count = 0
136
- bucketView[bucketBase + 2] = 0; // lock version = 0
137
- // Reserved space for future use
138
- }
139
- }
140
-
141
- /**
94
+ */ initializeBuckets() {
95
+ const view = new Uint32Array(this.buffer);
96
+ const bucketView = view.subarray(this.bucketsOffset >> 2);
97
+ for(let i = 0; i < this.bucketCount; i++){
98
+ const bucketBase = i * (this.bucketSize >> 2);
99
+ bucketView[bucketBase] = 0; // head = null
100
+ bucketView[bucketBase + 1] = 0; // count = 0
101
+ bucketView[bucketBase + 2] = 0; // lock version = 0
102
+ // Reserved space for future use
103
+ }
104
+ }
105
+ /**
142
106
  * Lock-free insertion with optimistic concurrency control
143
- */
144
- insert(keyHash, entryOffset) {
145
- const bucketIndex = keyHash % this.bucketCount;
146
- const bucketOffset = this.bucketsOffset + (bucketIndex * this.bucketSize);
147
-
148
- let attempts = 0;
149
- const maxAttempts = 16;
150
-
151
- while (attempts < maxAttempts) {
152
- // Read current state
153
- const currentHead = AtomicOperations.loadAcquire(this.buffer, bucketOffset);
154
- const lockVersion = AtomicOperations.loadAcquire(this.buffer, bucketOffset + 8);
155
-
156
- // Set next pointer of new entry to current head
157
- AtomicOperations.storeRelease(this.buffer, entryOffset, currentHead);
158
-
159
- // Attempt atomic update of bucket head
160
- const success = AtomicOperations.compareAndSwap32(
161
- this.buffer, bucketOffset, currentHead, entryOffset
162
- );
163
-
164
- if (success === currentHead) {
165
- // Verify no concurrent modification (ABA problem prevention)
166
- const newLockVersion = AtomicOperations.loadAcquire(this.buffer, bucketOffset + 8);
167
- if (newLockVersion === lockVersion) {
168
- // Update count atomically
169
- AtomicOperations.atomicIncrement(this.buffer, bucketOffset + 4);
170
- return true;
171
- }
172
- }
173
-
174
- // Exponential backoff before retry
175
- AtomicOperations.backoff(attempts);
176
- attempts++;
177
- }
178
-
179
- return false; // Failed after max attempts
180
- }
181
-
182
- /**
107
+ */ insert(keyHash, entryOffset) {
108
+ const bucketIndex = keyHash % this.bucketCount;
109
+ const bucketOffset = this.bucketsOffset + bucketIndex * this.bucketSize;
110
+ let attempts = 0;
111
+ const maxAttempts = 16;
112
+ while(attempts < maxAttempts){
113
+ // Read current state
114
+ const currentHead = AtomicOperations.loadAcquire(this.buffer, bucketOffset);
115
+ const lockVersion = AtomicOperations.loadAcquire(this.buffer, bucketOffset + 8);
116
+ // Set next pointer of new entry to current head
117
+ AtomicOperations.storeRelease(this.buffer, entryOffset, currentHead);
118
+ // Attempt atomic update of bucket head
119
+ const success = AtomicOperations.compareAndSwap32(this.buffer, bucketOffset, currentHead, entryOffset);
120
+ if (success === currentHead) {
121
+ // Verify no concurrent modification (ABA problem prevention)
122
+ const newLockVersion = AtomicOperations.loadAcquire(this.buffer, bucketOffset + 8);
123
+ if (newLockVersion === lockVersion) {
124
+ // Update count atomically
125
+ AtomicOperations.atomicIncrement(this.buffer, bucketOffset + 4);
126
+ return true;
127
+ }
128
+ }
129
+ // Exponential backoff before retry
130
+ AtomicOperations.backoff(attempts);
131
+ attempts++;
132
+ }
133
+ return false; // Failed after max attempts
134
+ }
135
+ /**
183
136
  * Lock-free lookup with minimal memory barriers
184
- */
185
- lookup(keyHash, keyComparator) {
186
- const bucketIndex = keyHash % this.bucketCount;
187
- const bucketOffset = this.bucketsOffset + (bucketIndex * this.bucketSize);
188
-
189
- let entryOffset = AtomicOperations.loadAcquire(this.buffer, bucketOffset);
190
-
191
- while (entryOffset !== 0) {
192
- const entry = this.getEntryView(entryOffset);
193
-
194
- // Fast hash comparison first
195
- const entryHash = AtomicOperations.loadAcquire(this.buffer, entryOffset + 4);
196
- if (entryHash === keyHash && keyComparator(entry)) {
197
- return entryOffset;
198
- }
199
-
200
- // Follow chain
201
- entryOffset = AtomicOperations.loadAcquire(this.buffer, entryOffset);
202
- }
203
-
204
- return 0; // Not found
205
- }
206
-
207
- /**
137
+ */ lookup(keyHash, keyComparator) {
138
+ const bucketIndex = keyHash % this.bucketCount;
139
+ const bucketOffset = this.bucketsOffset + bucketIndex * this.bucketSize;
140
+ let entryOffset = AtomicOperations.loadAcquire(this.buffer, bucketOffset);
141
+ while(entryOffset !== 0){
142
+ const entry = this.getEntryView(entryOffset);
143
+ // Fast hash comparison first
144
+ const entryHash = AtomicOperations.loadAcquire(this.buffer, entryOffset + 4);
145
+ if (entryHash === keyHash && keyComparator(entry)) {
146
+ return entryOffset;
147
+ }
148
+ // Follow chain
149
+ entryOffset = AtomicOperations.loadAcquire(this.buffer, entryOffset);
150
+ }
151
+ return 0; // Not found
152
+ }
153
+ /**
208
154
  * Lock-free removal with lazy deletion
209
- */
210
- remove(keyHash, keyComparator) {
211
- const bucketIndex = keyHash % this.bucketCount;
212
- const bucketOffset = this.bucketsOffset + (bucketIndex * this.bucketSize);
213
-
214
- while (true) {
215
- let prevOffset = bucketOffset;
216
- let currentOffset = AtomicOperations.loadAcquire(this.buffer, bucketOffset);
217
-
218
- while (currentOffset !== 0) {
219
- const entry = this.getEntryView(currentOffset);
220
- const entryHash = AtomicOperations.loadAcquire(this.buffer, currentOffset + 4);
221
-
222
- if (entryHash === keyHash && keyComparator(entry)) {
223
- // Mark as deleted (lazy deletion)
224
- const flags = AtomicOperations.loadAcquire(this.buffer, currentOffset + 24);
225
- const newFlags = flags | 0x80000000; // Set deleted bit
226
-
227
- const success = AtomicOperations.compareAndSwap32(
228
- this.buffer, currentOffset + 24, flags, newFlags
229
- );
230
-
231
- if (success === flags) {
232
- // Decrement bucket count
233
- AtomicOperations.atomicDecrement(this.buffer, bucketOffset + 4);
234
- return true;
235
- }
236
- }
237
-
238
- prevOffset = currentOffset;
239
- currentOffset = AtomicOperations.loadAcquire(this.buffer, currentOffset);
240
- }
241
-
242
- return false; // Not found
243
- }
244
- }
245
-
246
- /**
155
+ */ remove(keyHash, keyComparator) {
156
+ const bucketIndex = keyHash % this.bucketCount;
157
+ const bucketOffset = this.bucketsOffset + bucketIndex * this.bucketSize;
158
+ while(true){
159
+ let prevOffset = bucketOffset;
160
+ let currentOffset = AtomicOperations.loadAcquire(this.buffer, bucketOffset);
161
+ while(currentOffset !== 0){
162
+ const entry = this.getEntryView(currentOffset);
163
+ const entryHash = AtomicOperations.loadAcquire(this.buffer, currentOffset + 4);
164
+ if (entryHash === keyHash && keyComparator(entry)) {
165
+ // Mark as deleted (lazy deletion)
166
+ const flags = AtomicOperations.loadAcquire(this.buffer, currentOffset + 24);
167
+ const newFlags = flags | 0x80000000; // Set deleted bit
168
+ const success = AtomicOperations.compareAndSwap32(this.buffer, currentOffset + 24, flags, newFlags);
169
+ if (success === flags) {
170
+ // Decrement bucket count
171
+ AtomicOperations.atomicDecrement(this.buffer, bucketOffset + 4);
172
+ return true;
173
+ }
174
+ }
175
+ prevOffset = currentOffset;
176
+ currentOffset = AtomicOperations.loadAcquire(this.buffer, currentOffset);
177
+ }
178
+ return false; // Not found
179
+ }
180
+ }
181
+ /**
247
182
  * Get entry view for fast access
248
- */
249
- getEntryView(offset) {
250
- return {
251
- offset,
252
- next: () => AtomicOperations.loadAcquire(this.buffer, offset),
253
- keyHash: () => AtomicOperations.loadAcquire(this.buffer, offset + 4),
254
- keyLength: () => new Uint16Array(this.buffer, offset + 8, 1)[0],
255
- valueLength: () => new Uint16Array(this.buffer, offset + 10, 1)[0],
256
- namespace: () => AtomicOperations.loadAcquire(this.buffer, offset + 12),
257
- timestamp: () => AtomicOperations.loadAcquire(this.buffer, offset + 16),
258
- flags: () => AtomicOperations.loadAcquire(this.buffer, offset + 24)
259
- };
260
- }
261
-
262
- /**
183
+ */ getEntryView(offset) {
184
+ return {
185
+ offset,
186
+ next: ()=>AtomicOperations.loadAcquire(this.buffer, offset),
187
+ keyHash: ()=>AtomicOperations.loadAcquire(this.buffer, offset + 4),
188
+ keyLength: ()=>new Uint16Array(this.buffer, offset + 8, 1)[0],
189
+ valueLength: ()=>new Uint16Array(this.buffer, offset + 10, 1)[0],
190
+ namespace: ()=>AtomicOperations.loadAcquire(this.buffer, offset + 12),
191
+ timestamp: ()=>AtomicOperations.loadAcquire(this.buffer, offset + 16),
192
+ flags: ()=>AtomicOperations.loadAcquire(this.buffer, offset + 24)
193
+ };
194
+ }
195
+ /**
263
196
  * Get bucket statistics for load balancing
264
- */
265
- getBucketStats() {
266
- const stats = {
267
- totalEntries: 0,
268
- maxChainLength: 0,
269
- emptyBuckets: 0,
270
- averageChainLength: 0
271
- };
272
-
273
- for (let i = 0; i < this.bucketCount; i++) {
274
- const bucketOffset = this.bucketsOffset + (i * this.bucketSize);
275
- const count = AtomicOperations.loadAcquire(this.buffer, bucketOffset + 4);
276
-
277
- stats.totalEntries += count;
278
- stats.maxChainLength = Math.max(stats.maxChainLength, count);
279
- if (count === 0) stats.emptyBuckets++;
280
- }
281
-
282
- stats.averageChainLength = stats.totalEntries / (this.bucketCount - stats.emptyBuckets);
283
- return stats;
284
- }
285
- }
286
-
197
+ */ getBucketStats() {
198
+ const stats = {
199
+ totalEntries: 0,
200
+ maxChainLength: 0,
201
+ emptyBuckets: 0,
202
+ averageChainLength: 0
203
+ };
204
+ for(let i = 0; i < this.bucketCount; i++){
205
+ const bucketOffset = this.bucketsOffset + i * this.bucketSize;
206
+ const count = AtomicOperations.loadAcquire(this.buffer, bucketOffset + 4);
207
+ stats.totalEntries += count;
208
+ stats.maxChainLength = Math.max(stats.maxChainLength, count);
209
+ if (count === 0) stats.emptyBuckets++;
210
+ }
211
+ stats.averageChainLength = stats.totalEntries / (this.bucketCount - stats.emptyBuckets);
212
+ return stats;
213
+ }
214
+ constructor(sharedBuffer, bucketCount = 16384, bucketsOffset = 4096){
215
+ this.buffer = sharedBuffer;
216
+ this.bucketCount = bucketCount;
217
+ this.bucketSize = 32; // bytes per bucket
218
+ this.bucketsOffset = bucketsOffset;
219
+ this.loadFactor = 0.75; // Resize threshold
220
+ this.initializeBuckets();
221
+ }
222
+ }
287
223
  /**
288
224
  * Lock-free memory pool with segregated free lists
289
- */
290
- export class LockFreeMemoryPool {
291
- constructor(sharedBuffer, poolOffset, poolSize) {
292
- this.buffer = sharedBuffer;
293
- this.poolOffset = poolOffset;
294
- this.poolSize = poolSize;
295
- this.chunkSize = 64; // Minimum allocation unit (cache line aligned)
296
- this.sizeBuckets = 16; // Number of different size classes
297
-
298
- this.initializeFreeLists();
299
- }
300
-
301
- /**
225
+ */ export class LockFreeMemoryPool {
226
+ /**
302
227
  * Initialize segregated free lists for different allocation sizes
303
- */
304
- initializeFreeList() {
305
- const headerSize = this.sizeBuckets * 8; // 8 bytes per size class (head pointer + count)
306
- let currentOffset = this.poolOffset + headerSize;
307
-
308
- // Initialize free lists for different size classes
309
- for (let sizeClass = 0; sizeClass < this.sizeBuckets; sizeClass++) {
310
- const chunkSize = this.chunkSize * (1 << sizeClass); // Power of 2 sizes
311
- const headerOffset = this.poolOffset + (sizeClass * 8);
312
-
313
- // Initialize first chunk as head of free list
314
- AtomicOperations.storeRelease(this.buffer, headerOffset, currentOffset);
315
- AtomicOperations.storeRelease(this.buffer, headerOffset + 4, 0); // count
316
-
317
- // Chain all chunks of this size class
318
- let chunkOffset = currentOffset;
319
- const chunksInClass = Math.floor(this.poolSize / (this.sizeBuckets * chunkSize));
320
-
321
- for (let i = 0; i < chunksInClass - 1; i++) {
322
- const nextChunk = chunkOffset + chunkSize;
323
- AtomicOperations.storeRelease(this.buffer, chunkOffset, nextChunk);
324
- chunkOffset = nextChunk;
325
- }
326
-
327
- // Last chunk points to null
328
- AtomicOperations.storeRelease(this.buffer, chunkOffset, 0);
329
- currentOffset = chunkOffset + chunkSize;
330
- }
331
- }
332
-
333
- /**
228
+ */ initializeFreeList() {
229
+ const headerSize = this.sizeBuckets * 8; // 8 bytes per size class (head pointer + count)
230
+ let currentOffset = this.poolOffset + headerSize;
231
+ // Initialize free lists for different size classes
232
+ for(let sizeClass = 0; sizeClass < this.sizeBuckets; sizeClass++){
233
+ const chunkSize = this.chunkSize * (1 << sizeClass); // Power of 2 sizes
234
+ const headerOffset = this.poolOffset + sizeClass * 8;
235
+ // Initialize first chunk as head of free list
236
+ AtomicOperations.storeRelease(this.buffer, headerOffset, currentOffset);
237
+ AtomicOperations.storeRelease(this.buffer, headerOffset + 4, 0); // count
238
+ // Chain all chunks of this size class
239
+ let chunkOffset = currentOffset;
240
+ const chunksInClass = Math.floor(this.poolSize / (this.sizeBuckets * chunkSize));
241
+ for(let i = 0; i < chunksInClass - 1; i++){
242
+ const nextChunk = chunkOffset + chunkSize;
243
+ AtomicOperations.storeRelease(this.buffer, chunkOffset, nextChunk);
244
+ chunkOffset = nextChunk;
245
+ }
246
+ // Last chunk points to null
247
+ AtomicOperations.storeRelease(this.buffer, chunkOffset, 0);
248
+ currentOffset = chunkOffset + chunkSize;
249
+ }
250
+ }
251
+ /**
334
252
  * Lock-free allocation using compare-and-swap
335
- */
336
- allocate(requestedSize) {
337
- const alignedSize = this.alignSize(requestedSize);
338
- const sizeClass = this.getSizeClass(alignedSize);
339
-
340
- if (sizeClass >= this.sizeBuckets) {
341
- return this.allocateLarge(alignedSize);
342
- }
343
-
344
- const freeListOffset = this.poolOffset + (sizeClass * 8);
345
- let attempts = 0;
346
- const maxAttempts = 16;
347
-
348
- while (attempts < maxAttempts) {
349
- const currentHead = AtomicOperations.loadAcquire(this.buffer, freeListOffset);
350
-
351
- if (currentHead === 0) {
352
- // No free chunks in this size class, try larger size class
353
- return this.allocateFromLargerClass(sizeClass + 1, alignedSize);
354
- }
355
-
356
- // Read next pointer before attempting CAS
357
- const nextChunk = AtomicOperations.loadAcquire(this.buffer, currentHead);
358
-
359
- // Attempt to update free list head
360
- const success = AtomicOperations.compareAndSwap32(
361
- this.buffer, freeListOffset, currentHead, nextChunk
362
- );
363
-
364
- if (success === currentHead) {
365
- // Update allocation count
366
- AtomicOperations.atomicDecrement(this.buffer, freeListOffset + 4);
367
-
368
- // Initialize allocated chunk header
369
- this.initializeAllocatedChunk(currentHead, alignedSize, sizeClass);
370
- return currentHead;
371
- }
372
-
373
- AtomicOperations.backoff(attempts);
374
- attempts++;
375
- }
376
-
377
- return 0; // Allocation failed
378
- }
379
-
380
- /**
253
+ */ allocate(requestedSize) {
254
+ const alignedSize = this.alignSize(requestedSize);
255
+ const sizeClass = this.getSizeClass(alignedSize);
256
+ if (sizeClass >= this.sizeBuckets) {
257
+ return this.allocateLarge(alignedSize);
258
+ }
259
+ const freeListOffset = this.poolOffset + sizeClass * 8;
260
+ let attempts = 0;
261
+ const maxAttempts = 16;
262
+ while(attempts < maxAttempts){
263
+ const currentHead = AtomicOperations.loadAcquire(this.buffer, freeListOffset);
264
+ if (currentHead === 0) {
265
+ // No free chunks in this size class, try larger size class
266
+ return this.allocateFromLargerClass(sizeClass + 1, alignedSize);
267
+ }
268
+ // Read next pointer before attempting CAS
269
+ const nextChunk = AtomicOperations.loadAcquire(this.buffer, currentHead);
270
+ // Attempt to update free list head
271
+ const success = AtomicOperations.compareAndSwap32(this.buffer, freeListOffset, currentHead, nextChunk);
272
+ if (success === currentHead) {
273
+ // Update allocation count
274
+ AtomicOperations.atomicDecrement(this.buffer, freeListOffset + 4);
275
+ // Initialize allocated chunk header
276
+ this.initializeAllocatedChunk(currentHead, alignedSize, sizeClass);
277
+ return currentHead;
278
+ }
279
+ AtomicOperations.backoff(attempts);
280
+ attempts++;
281
+ }
282
+ return 0; // Allocation failed
283
+ }
284
+ /**
381
285
  * Lock-free deallocation returning chunk to appropriate free list
382
- */
383
- deallocate(chunkOffset) {
384
- if (chunkOffset === 0) return;
385
-
386
- // Read chunk header to determine size class
387
- const sizeClass = this.getChunkSizeClass(chunkOffset);
388
- const freeListOffset = this.poolOffset + (sizeClass * 8);
389
-
390
- let attempts = 0;
391
- const maxAttempts = 16;
392
-
393
- while (attempts < maxAttempts) {
394
- const currentHead = AtomicOperations.loadAcquire(this.buffer, freeListOffset);
395
-
396
- // Set next pointer of chunk being freed
397
- AtomicOperations.storeRelease(this.buffer, chunkOffset, currentHead);
398
-
399
- // Attempt to update free list head
400
- const success = AtomicOperations.compareAndSwap32(
401
- this.buffer, freeListOffset, currentHead, chunkOffset
402
- );
403
-
404
- if (success === currentHead) {
405
- // Update free count
406
- AtomicOperations.atomicIncrement(this.buffer, freeListOffset + 4);
407
-
408
- // Clear chunk header for security
409
- this.clearChunkHeader(chunkOffset);
410
- return;
411
- }
412
-
413
- AtomicOperations.backoff(attempts);
414
- attempts++;
415
- }
416
- }
417
-
418
- /**
286
+ */ deallocate(chunkOffset) {
287
+ if (chunkOffset === 0) return;
288
+ // Read chunk header to determine size class
289
+ const sizeClass = this.getChunkSizeClass(chunkOffset);
290
+ const freeListOffset = this.poolOffset + sizeClass * 8;
291
+ let attempts = 0;
292
+ const maxAttempts = 16;
293
+ while(attempts < maxAttempts){
294
+ const currentHead = AtomicOperations.loadAcquire(this.buffer, freeListOffset);
295
+ // Set next pointer of chunk being freed
296
+ AtomicOperations.storeRelease(this.buffer, chunkOffset, currentHead);
297
+ // Attempt to update free list head
298
+ const success = AtomicOperations.compareAndSwap32(this.buffer, freeListOffset, currentHead, chunkOffset);
299
+ if (success === currentHead) {
300
+ // Update free count
301
+ AtomicOperations.atomicIncrement(this.buffer, freeListOffset + 4);
302
+ // Clear chunk header for security
303
+ this.clearChunkHeader(chunkOffset);
304
+ return;
305
+ }
306
+ AtomicOperations.backoff(attempts);
307
+ attempts++;
308
+ }
309
+ }
310
+ /**
419
311
  * Align size to chunk boundaries
420
- */
421
- alignSize(size) {
422
- return Math.ceil(size / this.chunkSize) * this.chunkSize;
423
- }
424
-
425
- /**
312
+ */ alignSize(size) {
313
+ return Math.ceil(size / this.chunkSize) * this.chunkSize;
314
+ }
315
+ /**
426
316
  * Determine size class for allocation size
427
- */
428
- getSizeClass(alignedSize) {
429
- const chunks = alignedSize / this.chunkSize;
430
- return Math.floor(Math.log2(chunks));
431
- }
432
-
433
- /**
317
+ */ getSizeClass(alignedSize) {
318
+ const chunks = alignedSize / this.chunkSize;
319
+ return Math.floor(Math.log2(chunks));
320
+ }
321
+ /**
434
322
  * Allocate from larger size class when smaller classes are exhausted
435
- */
436
- allocateFromLargerClass(sizeClass, requestedSize) {
437
- if (sizeClass >= this.sizeBuckets) {
438
- return 0; // No larger classes available
439
- }
440
-
441
- const chunk = this.allocate(this.chunkSize * (1 << sizeClass));
442
- if (chunk === 0) {
443
- return this.allocateFromLargerClass(sizeClass + 1, requestedSize);
444
- }
445
-
446
- // Split chunk if it's significantly larger than requested
447
- const chunkSize = this.chunkSize * (1 << sizeClass);
448
- if (chunkSize > requestedSize * 2) {
449
- this.splitChunk(chunk, requestedSize, chunkSize);
450
- }
451
-
452
- return chunk;
453
- }
454
-
455
- /**
323
+ */ allocateFromLargerClass(sizeClass, requestedSize) {
324
+ if (sizeClass >= this.sizeBuckets) {
325
+ return 0; // No larger classes available
326
+ }
327
+ const chunk = this.allocate(this.chunkSize * (1 << sizeClass));
328
+ if (chunk === 0) {
329
+ return this.allocateFromLargerClass(sizeClass + 1, requestedSize);
330
+ }
331
+ // Split chunk if it's significantly larger than requested
332
+ const chunkSize = this.chunkSize * (1 << sizeClass);
333
+ if (chunkSize > requestedSize * 2) {
334
+ this.splitChunk(chunk, requestedSize, chunkSize);
335
+ }
336
+ return chunk;
337
+ }
338
+ /**
456
339
  * Split large chunk into smaller pieces
457
- */
458
- splitChunk(chunkOffset, requestedSize, chunkSize) {
459
- const remainderOffset = chunkOffset + requestedSize;
460
- const remainderSize = chunkSize - requestedSize;
461
-
462
- if (remainderSize >= this.chunkSize) {
463
- // Return remainder to appropriate free list
464
- const remainderSizeClass = this.getSizeClass(remainderSize);
465
- this.initializeAllocatedChunk(remainderOffset, remainderSize, remainderSizeClass);
466
- this.deallocate(remainderOffset);
467
- }
468
- }
469
-
470
- /**
340
+ */ splitChunk(chunkOffset, requestedSize, chunkSize) {
341
+ const remainderOffset = chunkOffset + requestedSize;
342
+ const remainderSize = chunkSize - requestedSize;
343
+ if (remainderSize >= this.chunkSize) {
344
+ // Return remainder to appropriate free list
345
+ const remainderSizeClass = this.getSizeClass(remainderSize);
346
+ this.initializeAllocatedChunk(remainderOffset, remainderSize, remainderSizeClass);
347
+ this.deallocate(remainderOffset);
348
+ }
349
+ }
350
+ /**
471
351
  * Initialize allocated chunk header with metadata
472
- */
473
- initializeAllocatedChunk(chunkOffset, size, sizeClass) {
474
- // Chunk header format: [size: 4 bytes][sizeClass: 4 bytes][reserved: 8 bytes]
475
- AtomicOperations.storeRelease(this.buffer, chunkOffset - 16, size);
476
- AtomicOperations.storeRelease(this.buffer, chunkOffset - 12, sizeClass);
477
- AtomicOperations.storeRelease(this.buffer, chunkOffset - 8, 0); // Reserved
478
- AtomicOperations.storeRelease(this.buffer, chunkOffset - 4, 0); // Reserved
479
- }
480
-
481
- /**
352
+ */ initializeAllocatedChunk(chunkOffset, size, sizeClass) {
353
+ // Chunk header format: [size: 4 bytes][sizeClass: 4 bytes][reserved: 8 bytes]
354
+ AtomicOperations.storeRelease(this.buffer, chunkOffset - 16, size);
355
+ AtomicOperations.storeRelease(this.buffer, chunkOffset - 12, sizeClass);
356
+ AtomicOperations.storeRelease(this.buffer, chunkOffset - 8, 0); // Reserved
357
+ AtomicOperations.storeRelease(this.buffer, chunkOffset - 4, 0); // Reserved
358
+ }
359
+ /**
482
360
  * Get size class from chunk header
483
- */
484
- getChunkSizeClass(chunkOffset) {
485
- return AtomicOperations.loadAcquire(this.buffer, chunkOffset - 12);
486
- }
487
-
488
- /**
361
+ */ getChunkSizeClass(chunkOffset) {
362
+ return AtomicOperations.loadAcquire(this.buffer, chunkOffset - 12);
363
+ }
364
+ /**
489
365
  * Clear chunk header for security
490
- */
491
- clearChunkHeader(chunkOffset) {
492
- // Clear sensitive data
493
- AtomicOperations.storeRelease(this.buffer, chunkOffset - 16, 0);
494
- AtomicOperations.storeRelease(this.buffer, chunkOffset - 12, 0);
495
- }
496
-
497
- /**
366
+ */ clearChunkHeader(chunkOffset) {
367
+ // Clear sensitive data
368
+ AtomicOperations.storeRelease(this.buffer, chunkOffset - 16, 0);
369
+ AtomicOperations.storeRelease(this.buffer, chunkOffset - 12, 0);
370
+ }
371
+ /**
498
372
  * Get memory pool statistics
499
- */
500
- getPoolStats() {
501
- const stats = {
502
- totalSize: this.poolSize,
503
- allocatedBytes: 0,
504
- freeBytes: 0,
505
- fragmentationRatio: 0,
506
- sizeClassStats: []
507
- };
508
-
509
- for (let sizeClass = 0; sizeClass < this.sizeBuckets; sizeClass++) {
510
- const freeListOffset = this.poolOffset + (sizeClass * 8);
511
- const freeCount = AtomicOperations.loadAcquire(this.buffer, freeListOffset + 4);
512
- const chunkSize = this.chunkSize * (1 << sizeClass);
513
-
514
- stats.sizeClassStats[sizeClass] = {
515
- chunkSize,
516
- freeChunks: freeCount,
517
- freeBytes: freeCount * chunkSize
518
- };
519
-
520
- stats.freeBytes += freeCount * chunkSize;
521
- }
522
-
523
- stats.allocatedBytes = stats.totalSize - stats.freeBytes;
524
- stats.fragmentationRatio = stats.freeBytes / stats.totalSize;
525
-
526
- return stats;
527
- }
528
- }
529
-
373
+ */ getPoolStats() {
374
+ const stats = {
375
+ totalSize: this.poolSize,
376
+ allocatedBytes: 0,
377
+ freeBytes: 0,
378
+ fragmentationRatio: 0,
379
+ sizeClassStats: []
380
+ };
381
+ for(let sizeClass = 0; sizeClass < this.sizeBuckets; sizeClass++){
382
+ const freeListOffset = this.poolOffset + sizeClass * 8;
383
+ const freeCount = AtomicOperations.loadAcquire(this.buffer, freeListOffset + 4);
384
+ const chunkSize = this.chunkSize * (1 << sizeClass);
385
+ stats.sizeClassStats[sizeClass] = {
386
+ chunkSize,
387
+ freeChunks: freeCount,
388
+ freeBytes: freeCount * chunkSize
389
+ };
390
+ stats.freeBytes += freeCount * chunkSize;
391
+ }
392
+ stats.allocatedBytes = stats.totalSize - stats.freeBytes;
393
+ stats.fragmentationRatio = stats.freeBytes / stats.totalSize;
394
+ return stats;
395
+ }
396
+ constructor(sharedBuffer, poolOffset, poolSize){
397
+ this.buffer = sharedBuffer;
398
+ this.poolOffset = poolOffset;
399
+ this.poolSize = poolSize;
400
+ this.chunkSize = 64; // Minimum allocation unit (cache line aligned)
401
+ this.sizeBuckets = 16; // Number of different size classes
402
+ this.initializeFreeLists();
403
+ }
404
+ }
530
405
  /**
531
406
  * Lock-free ring buffer for high-throughput message passing
532
- */
533
- export class LockFreeRingBuffer {
534
- constructor(sharedBuffer, ringOffset, ringSize) {
535
- this.buffer = sharedBuffer;
536
- this.ringOffset = ringOffset;
537
- this.ringSize = ringSize;
538
- this.slotSize = 64; // Each message slot size
539
- this.slotCount = Math.floor(ringSize / this.slotSize);
540
-
541
- // Ring buffer control structure
542
- this.headOffset = ringOffset - 16; // Producer position
543
- this.tailOffset = ringOffset - 12; // Consumer position
544
- this.countOffset = ringOffset - 8; // Current count
545
- this.flagsOffset = ringOffset - 4; // Control flags
546
-
547
- this.initialize();
548
- }
549
-
550
- /**
407
+ */ export class LockFreeRingBuffer {
408
+ /**
551
409
  * Initialize ring buffer control structure
552
- */
553
- initialize() {
554
- AtomicOperations.storeRelease(this.buffer, this.headOffset, 0);
555
- AtomicOperations.storeRelease(this.buffer, this.tailOffset, 0);
556
- AtomicOperations.storeRelease(this.buffer, this.countOffset, 0);
557
- AtomicOperations.storeRelease(this.buffer, this.flagsOffset, 0);
558
- }
559
-
560
- /**
410
+ */ initialize() {
411
+ AtomicOperations.storeRelease(this.buffer, this.headOffset, 0);
412
+ AtomicOperations.storeRelease(this.buffer, this.tailOffset, 0);
413
+ AtomicOperations.storeRelease(this.buffer, this.countOffset, 0);
414
+ AtomicOperations.storeRelease(this.buffer, this.flagsOffset, 0);
415
+ }
416
+ /**
561
417
  * Lock-free enqueue operation
562
- */
563
- enqueue(messageData) {
564
- if (messageData.length > this.slotSize - 8) {
565
- return false; // Message too large
566
- }
567
-
568
- let attempts = 0;
569
- const maxAttempts = 100;
570
-
571
- while (attempts < maxAttempts) {
572
- const currentHead = AtomicOperations.loadAcquire(this.buffer, this.headOffset);
573
- const currentTail = AtomicOperations.loadAcquire(this.buffer, this.tailOffset);
574
- const currentCount = AtomicOperations.loadAcquire(this.buffer, this.countOffset);
575
-
576
- // Check if buffer is full
577
- if (currentCount >= this.slotCount) {
578
- return false; // Buffer full
579
- }
580
-
581
- const newHead = (currentHead + 1) % this.slotCount;
582
- const slotOffset = this.ringOffset + (currentHead * this.slotSize);
583
-
584
- // Reserve slot by advancing head
585
- const success = AtomicOperations.compareAndSwap32(
586
- this.buffer, this.headOffset, currentHead, newHead
587
- );
588
-
589
- if (success === currentHead) {
590
- // Write message to reserved slot
591
- this.writeMessageToSlot(slotOffset, messageData);
592
-
593
- // Update count atomically
594
- AtomicOperations.atomicIncrement(this.buffer, this.countOffset);
595
- return true;
596
- }
597
-
598
- AtomicOperations.backoff(attempts);
599
- attempts++;
600
- }
601
-
602
- return false; // Failed after max attempts
603
- }
604
-
605
- /**
418
+ */ enqueue(messageData) {
419
+ if (messageData.length > this.slotSize - 8) {
420
+ return false; // Message too large
421
+ }
422
+ let attempts = 0;
423
+ const maxAttempts = 100;
424
+ while(attempts < maxAttempts){
425
+ const currentHead = AtomicOperations.loadAcquire(this.buffer, this.headOffset);
426
+ const currentTail = AtomicOperations.loadAcquire(this.buffer, this.tailOffset);
427
+ const currentCount = AtomicOperations.loadAcquire(this.buffer, this.countOffset);
428
+ // Check if buffer is full
429
+ if (currentCount >= this.slotCount) {
430
+ return false; // Buffer full
431
+ }
432
+ const newHead = (currentHead + 1) % this.slotCount;
433
+ const slotOffset = this.ringOffset + currentHead * this.slotSize;
434
+ // Reserve slot by advancing head
435
+ const success = AtomicOperations.compareAndSwap32(this.buffer, this.headOffset, currentHead, newHead);
436
+ if (success === currentHead) {
437
+ // Write message to reserved slot
438
+ this.writeMessageToSlot(slotOffset, messageData);
439
+ // Update count atomically
440
+ AtomicOperations.atomicIncrement(this.buffer, this.countOffset);
441
+ return true;
442
+ }
443
+ AtomicOperations.backoff(attempts);
444
+ attempts++;
445
+ }
446
+ return false; // Failed after max attempts
447
+ }
448
+ /**
606
449
  * Lock-free dequeue operation
607
- */
608
- dequeue() {
609
- let attempts = 0;
610
- const maxAttempts = 100;
611
-
612
- while (attempts < maxAttempts) {
613
- const currentTail = AtomicOperations.loadAcquire(this.buffer, this.tailOffset);
614
- const currentHead = AtomicOperations.loadAcquire(this.buffer, this.headOffset);
615
- const currentCount = AtomicOperations.loadAcquire(this.buffer, this.countOffset);
616
-
617
- // Check if buffer is empty
618
- if (currentCount === 0) {
619
- return null; // Buffer empty
620
- }
621
-
622
- const newTail = (currentTail + 1) % this.slotCount;
623
- const slotOffset = this.ringOffset + (currentTail * this.slotSize);
624
-
625
- // Reserve slot by advancing tail
626
- const success = AtomicOperations.compareAndSwap32(
627
- this.buffer, this.tailOffset, currentTail, newTail
628
- );
629
-
630
- if (success === currentTail) {
631
- // Read message from reserved slot
632
- const messageData = this.readMessageFromSlot(slotOffset);
633
-
634
- // Update count atomically
635
- AtomicOperations.atomicDecrement(this.buffer, this.countOffset);
636
- return messageData;
637
- }
638
-
639
- AtomicOperations.backoff(attempts);
640
- attempts++;
641
- }
642
-
643
- return null; // Failed after max attempts
644
- }
645
-
646
- /**
450
+ */ dequeue() {
451
+ let attempts = 0;
452
+ const maxAttempts = 100;
453
+ while(attempts < maxAttempts){
454
+ const currentTail = AtomicOperations.loadAcquire(this.buffer, this.tailOffset);
455
+ const currentHead = AtomicOperations.loadAcquire(this.buffer, this.headOffset);
456
+ const currentCount = AtomicOperations.loadAcquire(this.buffer, this.countOffset);
457
+ // Check if buffer is empty
458
+ if (currentCount === 0) {
459
+ return null; // Buffer empty
460
+ }
461
+ const newTail = (currentTail + 1) % this.slotCount;
462
+ const slotOffset = this.ringOffset + currentTail * this.slotSize;
463
+ // Reserve slot by advancing tail
464
+ const success = AtomicOperations.compareAndSwap32(this.buffer, this.tailOffset, currentTail, newTail);
465
+ if (success === currentTail) {
466
+ // Read message from reserved slot
467
+ const messageData = this.readMessageFromSlot(slotOffset);
468
+ // Update count atomically
469
+ AtomicOperations.atomicDecrement(this.buffer, this.countOffset);
470
+ return messageData;
471
+ }
472
+ AtomicOperations.backoff(attempts);
473
+ attempts++;
474
+ }
475
+ return null; // Failed after max attempts
476
+ }
477
+ /**
647
478
  * Write message data to ring buffer slot
648
- */
649
- writeMessageToSlot(slotOffset, messageData) {
650
- // Slot format: [length: 4 bytes][timestamp: 4 bytes][data: variable]
651
- AtomicOperations.storeRelease(this.buffer, slotOffset, messageData.length);
652
- AtomicOperations.storeRelease(this.buffer, slotOffset + 4,
653
- Math.floor(performance.now() * 1000000) & 0xFFFFFFFF);
654
-
655
- // Copy message data
656
- const dataView = new Uint8Array(this.buffer, slotOffset + 8, messageData.length);
657
- dataView.set(messageData);
658
- }
659
-
660
- /**
479
+ */ writeMessageToSlot(slotOffset, messageData) {
480
+ // Slot format: [length: 4 bytes][timestamp: 4 bytes][data: variable]
481
+ AtomicOperations.storeRelease(this.buffer, slotOffset, messageData.length);
482
+ AtomicOperations.storeRelease(this.buffer, slotOffset + 4, Math.floor(performance.now() * 1000000) & 0xFFFFFFFF);
483
+ // Copy message data
484
+ const dataView = new Uint8Array(this.buffer, slotOffset + 8, messageData.length);
485
+ dataView.set(messageData);
486
+ }
487
+ /**
661
488
  * Read message data from ring buffer slot
662
- */
663
- readMessageFromSlot(slotOffset) {
664
- const length = AtomicOperations.loadAcquire(this.buffer, slotOffset);
665
- const timestamp = AtomicOperations.loadAcquire(this.buffer, slotOffset + 4);
666
-
667
- const messageData = new Uint8Array(length);
668
- const dataView = new Uint8Array(this.buffer, slotOffset + 8, length);
669
- messageData.set(dataView);
670
-
671
- return {
672
- data: messageData,
673
- timestamp,
674
- length
675
- };
676
- }
677
-
678
- /**
489
+ */ readMessageFromSlot(slotOffset) {
490
+ const length = AtomicOperations.loadAcquire(this.buffer, slotOffset);
491
+ const timestamp = AtomicOperations.loadAcquire(this.buffer, slotOffset + 4);
492
+ const messageData = new Uint8Array(length);
493
+ const dataView = new Uint8Array(this.buffer, slotOffset + 8, length);
494
+ messageData.set(dataView);
495
+ return {
496
+ data: messageData,
497
+ timestamp,
498
+ length
499
+ };
500
+ }
501
+ /**
679
502
  * Get ring buffer statistics
680
- */
681
- getStats() {
682
- return {
683
- size: this.slotCount,
684
- count: AtomicOperations.loadAcquire(this.buffer, this.countOffset),
685
- head: AtomicOperations.loadAcquire(this.buffer, this.headOffset),
686
- tail: AtomicOperations.loadAcquire(this.buffer, this.tailOffset),
687
- utilization: AtomicOperations.loadAcquire(this.buffer, this.countOffset) / this.slotCount
688
- };
689
- }
690
- }
691
-
503
+ */ getStats() {
504
+ return {
505
+ size: this.slotCount,
506
+ count: AtomicOperations.loadAcquire(this.buffer, this.countOffset),
507
+ head: AtomicOperations.loadAcquire(this.buffer, this.headOffset),
508
+ tail: AtomicOperations.loadAcquire(this.buffer, this.tailOffset),
509
+ utilization: AtomicOperations.loadAcquire(this.buffer, this.countOffset) / this.slotCount
510
+ };
511
+ }
512
+ constructor(sharedBuffer, ringOffset, ringSize){
513
+ this.buffer = sharedBuffer;
514
+ this.ringOffset = ringOffset;
515
+ this.ringSize = ringSize;
516
+ this.slotSize = 64; // Each message slot size
517
+ this.slotCount = Math.floor(ringSize / this.slotSize);
518
+ // Ring buffer control structure
519
+ this.headOffset = ringOffset - 16; // Producer position
520
+ this.tailOffset = ringOffset - 12; // Consumer position
521
+ this.countOffset = ringOffset - 8; // Current count
522
+ this.flagsOffset = ringOffset - 4; // Control flags
523
+ this.initialize();
524
+ }
525
+ }
692
526
  /**
693
527
  * Performance benchmarking utilities for lock-free structures
694
- */
695
- export class LockFreePerformanceBenchmark {
696
- constructor() {
697
- this.samples = new Array(100000);
698
- this.sampleIndex = 0;
699
- this.operationCounts = new Map();
700
- }
701
-
702
- /**
528
+ */ export class LockFreePerformanceBenchmark {
529
+ /**
703
530
  * Measure operation with nanosecond precision
704
- */
705
- measureOperation(operationName, operation) {
706
- const start = performance.now() * 1000000; // Convert to nanoseconds
707
- const result = operation();
708
- const end = performance.now() * 1000000;
709
-
710
- const duration = end - start;
711
- this.recordSample(operationName, duration);
712
-
713
- return { result, duration };
714
- }
715
-
716
- /**
531
+ */ measureOperation(operationName, operation) {
532
+ const start = performance.now() * 1000000; // Convert to nanoseconds
533
+ const result = operation();
534
+ const end = performance.now() * 1000000;
535
+ const duration = end - start;
536
+ this.recordSample(operationName, duration);
537
+ return {
538
+ result,
539
+ duration
540
+ };
541
+ }
542
+ /**
717
543
  * Concurrent benchmark with multiple threads
718
- */
719
- async concurrentBenchmark(operationName, operation, threadCount = 4, operationsPerThread = 10000) {
720
- const workers = [];
721
- const results = [];
722
-
723
- for (let i = 0; i < threadCount; i++) {
724
- const worker = new Promise((resolve) => {
725
- const threadResults = [];
726
- const startTime = performance.now() * 1000000;
727
-
728
- for (let j = 0; j < operationsPerThread; j++) {
729
- const { duration } = this.measureOperation(operationName, operation);
730
- threadResults.push(duration);
731
- }
732
-
733
- const endTime = performance.now() * 1000000;
734
- resolve({
735
- threadId: i,
736
- results: threadResults,
737
- totalTime: endTime - startTime,
738
- throughput: operationsPerThread / ((endTime - startTime) / 1000000000)
739
- });
740
- });
741
-
742
- workers.push(worker);
743
- }
744
-
745
- const threadResults = await Promise.all(workers);
746
- return this.analyzeConcurrentResults(threadResults);
747
- }
748
-
749
- /**
544
+ */ async concurrentBenchmark(operationName, operation, threadCount = 4, operationsPerThread = 10000) {
545
+ const workers = [];
546
+ const results = [];
547
+ for(let i = 0; i < threadCount; i++){
548
+ const worker = new Promise((resolve)=>{
549
+ const threadResults = [];
550
+ const startTime = performance.now() * 1000000;
551
+ for(let j = 0; j < operationsPerThread; j++){
552
+ const { duration } = this.measureOperation(operationName, operation);
553
+ threadResults.push(duration);
554
+ }
555
+ const endTime = performance.now() * 1000000;
556
+ resolve({
557
+ threadId: i,
558
+ results: threadResults,
559
+ totalTime: endTime - startTime,
560
+ throughput: operationsPerThread / ((endTime - startTime) / 1000000000)
561
+ });
562
+ });
563
+ workers.push(worker);
564
+ }
565
+ const threadResults = await Promise.all(workers);
566
+ return this.analyzeConcurrentResults(threadResults);
567
+ }
568
+ /**
750
569
  * Record performance sample
751
- */
752
- recordSample(operationName, duration) {
753
- if (!this.operationCounts.has(operationName)) {
754
- this.operationCounts.set(operationName, []);
755
- }
756
-
757
- const samples = this.operationCounts.get(operationName);
758
- samples.push(duration);
759
-
760
- if (samples.length > 10000) {
761
- samples.shift(); // Keep only recent samples
762
- }
763
- }
764
-
765
- /**
570
+ */ recordSample(operationName, duration) {
571
+ if (!this.operationCounts.has(operationName)) {
572
+ this.operationCounts.set(operationName, []);
573
+ }
574
+ const samples = this.operationCounts.get(operationName);
575
+ samples.push(duration);
576
+ if (samples.length > 10000) {
577
+ samples.shift(); // Keep only recent samples
578
+ }
579
+ }
580
+ /**
766
581
  * Analyze concurrent benchmark results
767
- */
768
- analyzeConcurrentResults(threadResults) {
769
- const allDurations = threadResults.flatMap(r => r.results);
770
- allDurations.sort((a, b) => a - b);
771
-
772
- const totalThroughput = threadResults.reduce((sum, r) => sum + r.throughput, 0);
773
-
774
- return {
775
- totalOperations: allDurations.length,
776
- totalThroughput,
777
- avgThroughputPerThread: totalThroughput / threadResults.length,
778
- latencyStats: {
779
- min: allDurations[0],
780
- max: allDurations[allDurations.length - 1],
781
- median: allDurations[Math.floor(allDurations.length / 2)],
782
- p95: allDurations[Math.floor(allDurations.length * 0.95)],
783
- p99: allDurations[Math.floor(allDurations.length * 0.99)],
784
- p999: allDurations[Math.floor(allDurations.length * 0.999)],
785
- mean: allDurations.reduce((a, b) => a + b, 0) / allDurations.length
786
- },
787
- threadResults
788
- };
789
- }
790
-
791
- /**
582
+ */ analyzeConcurrentResults(threadResults) {
583
+ const allDurations = threadResults.flatMap((r)=>r.results);
584
+ allDurations.sort((a, b)=>a - b);
585
+ const totalThroughput = threadResults.reduce((sum, r)=>sum + r.throughput, 0);
586
+ return {
587
+ totalOperations: allDurations.length,
588
+ totalThroughput,
589
+ avgThroughputPerThread: totalThroughput / threadResults.length,
590
+ latencyStats: {
591
+ min: allDurations[0],
592
+ max: allDurations[allDurations.length - 1],
593
+ median: allDurations[Math.floor(allDurations.length / 2)],
594
+ p95: allDurations[Math.floor(allDurations.length * 0.95)],
595
+ p99: allDurations[Math.floor(allDurations.length * 0.99)],
596
+ p999: allDurations[Math.floor(allDurations.length * 0.999)],
597
+ mean: allDurations.reduce((a, b)=>a + b, 0) / allDurations.length
598
+ },
599
+ threadResults
600
+ };
601
+ }
602
+ /**
792
603
  * Generate performance report
793
- */
794
- generateReport() {
795
- const report = {
796
- timestamp: Date.now(),
797
- operations: {}
798
- };
799
-
800
- for (const [operationName, samples] of this.operationCounts) {
801
- const sortedSamples = [...samples].sort((a, b) => a - b);
802
-
803
- report.operations[operationName] = {
804
- sampleCount: samples.length,
805
- min: sortedSamples[0],
806
- max: sortedSamples[sortedSamples.length - 1],
807
- median: sortedSamples[Math.floor(sortedSamples.length / 2)],
808
- p95: sortedSamples[Math.floor(sortedSamples.length * 0.95)],
809
- p99: sortedSamples[Math.floor(sortedSamples.length * 0.99)],
810
- mean: samples.reduce((a, b) => a + b, 0) / samples.length,
811
- targetMet: {
812
- read: sortedSamples[Math.floor(sortedSamples.length * 0.95)] < 100, // <100ns p95
813
- write: sortedSamples[Math.floor(sortedSamples.length * 0.95)] < 500 // <500ns p95
814
- }
815
- };
816
- }
817
-
818
- return report;
819
- }
820
- }
604
+ */ generateReport() {
605
+ const report = {
606
+ timestamp: Date.now(),
607
+ operations: {}
608
+ };
609
+ for (const [operationName, samples] of this.operationCounts){
610
+ const sortedSamples = [
611
+ ...samples
612
+ ].sort((a, b)=>a - b);
613
+ report.operations[operationName] = {
614
+ sampleCount: samples.length,
615
+ min: sortedSamples[0],
616
+ max: sortedSamples[sortedSamples.length - 1],
617
+ median: sortedSamples[Math.floor(sortedSamples.length / 2)],
618
+ p95: sortedSamples[Math.floor(sortedSamples.length * 0.95)],
619
+ p99: sortedSamples[Math.floor(sortedSamples.length * 0.99)],
620
+ mean: samples.reduce((a, b)=>a + b, 0) / samples.length,
621
+ targetMet: {
622
+ read: sortedSamples[Math.floor(sortedSamples.length * 0.95)] < 100,
623
+ write: sortedSamples[Math.floor(sortedSamples.length * 0.95)] < 500 // <500ns p95
624
+ }
625
+ };
626
+ }
627
+ return report;
628
+ }
629
+ constructor(){
630
+ this.samples = new Array(100000);
631
+ this.sampleIndex = 0;
632
+ this.operationCounts = new Map();
633
+ }
634
+ }