serializable-bptree 8.1.3 → 8.1.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.
@@ -57,6 +57,42 @@ var StringComparator = class extends ValueComparator {
57
57
  // node_modules/mvcc-api/dist/esm/index.mjs
58
58
  var MVCCStrategy = class {
59
59
  };
60
+ var LRUMap = class {
61
+ cache = /* @__PURE__ */ new Map();
62
+ capacity;
63
+ constructor(capacity) {
64
+ this.capacity = capacity;
65
+ }
66
+ get(key) {
67
+ if (!this.cache.has(key)) return void 0;
68
+ const value = this.cache.get(key);
69
+ this.cache.delete(key);
70
+ this.cache.set(key, value);
71
+ return value;
72
+ }
73
+ set(key, value) {
74
+ if (this.cache.has(key)) {
75
+ this.cache.delete(key);
76
+ } else if (this.cache.size >= this.capacity) {
77
+ const oldestKey = this.cache.keys().next().value;
78
+ if (oldestKey !== void 0) this.cache.delete(oldestKey);
79
+ }
80
+ this.cache.set(key, value);
81
+ return this;
82
+ }
83
+ has(key) {
84
+ return this.cache.has(key);
85
+ }
86
+ delete(key) {
87
+ return this.cache.delete(key);
88
+ }
89
+ clear() {
90
+ this.cache.clear();
91
+ }
92
+ get size() {
93
+ return this.cache.size;
94
+ }
95
+ };
60
96
  var MVCCTransaction = class {
61
97
  committed;
62
98
  snapshotVersion;
@@ -64,7 +100,6 @@ var MVCCTransaction = class {
64
100
  writeBuffer;
65
101
  deleteBuffer;
66
102
  createdKeys;
67
- // create()로 생성된 키 추적
68
103
  deletedValues;
69
104
  // delete 시 삭제 전 값 저장
70
105
  originallyExisted;
@@ -83,7 +118,8 @@ var MVCCTransaction = class {
83
118
  versionIndex = /* @__PURE__ */ new Map();
84
119
  deletedCache = /* @__PURE__ */ new Map();
85
120
  activeTransactions = /* @__PURE__ */ new Set();
86
- constructor(strategy, parent, snapshotVersion) {
121
+ diskCache;
122
+ constructor(strategy, options, parent, snapshotVersion) {
87
123
  this.snapshotVersion = snapshotVersion ?? 0;
88
124
  this.writeBuffer = /* @__PURE__ */ new Map();
89
125
  this.deleteBuffer = /* @__PURE__ */ new Set();
@@ -98,6 +134,7 @@ var MVCCTransaction = class {
98
134
  this.snapshotLocalVersion = parent.localVersion;
99
135
  this.strategy = void 0;
100
136
  this.root = parent.root;
137
+ this.diskCache = parent.diskCache;
101
138
  } else {
102
139
  if (!strategy) throw new Error("Root Transaction must get Strategy");
103
140
  this.strategy = strategy;
@@ -105,8 +142,13 @@ var MVCCTransaction = class {
105
142
  this.localVersion = 0;
106
143
  this.snapshotLocalVersion = 0;
107
144
  this.root = this;
145
+ this.diskCache = new LRUMap(options?.cacheCapacity ?? 1e3);
108
146
  }
109
147
  }
148
+ /**
149
+ * Checks if the transaction is a root transaction.
150
+ * @returns True if the transaction is a root transaction, false otherwise.
151
+ */
110
152
  isRoot() {
111
153
  return !this.parent;
112
154
  }
@@ -123,7 +165,22 @@ var MVCCTransaction = class {
123
165
  }
124
166
  return false;
125
167
  }
126
- // --- Internal buffer manipulation helpers ---
168
+ /**
169
+ * Checks if a key was written in this transaction.
170
+ * @param key The key to check.
171
+ * @returns True if the key was written in this transaction, false otherwise.
172
+ */
173
+ isWrote(key) {
174
+ return this.writeBuffer.has(key);
175
+ }
176
+ /**
177
+ * Checks if a key was deleted in this transaction.
178
+ * @param key The key to check.
179
+ * @returns True if the key was deleted in this transaction, false otherwise.
180
+ */
181
+ isDeleted(key) {
182
+ return this.deleteBuffer.has(key);
183
+ }
127
184
  _recordHistory(key) {
128
185
  const existsInWriteBuffer = this.writeBuffer.has(key);
129
186
  const existsInDeleteBuffer = this.deleteBuffer.has(key);
@@ -186,7 +243,11 @@ var MVCCTransaction = class {
186
243
  deleted.push({ key, data });
187
244
  }
188
245
  }
189
- return { created, updated, deleted };
246
+ return {
247
+ created,
248
+ updated,
249
+ deleted
250
+ };
190
251
  }
191
252
  /**
192
253
  * Rolls back the transaction.
@@ -204,7 +265,12 @@ var MVCCTransaction = class {
204
265
  if (this.root !== this) {
205
266
  this.root.activeTransactions.delete(this);
206
267
  }
207
- return { success: true, created, updated, deleted };
268
+ return {
269
+ success: true,
270
+ created,
271
+ updated,
272
+ deleted
273
+ };
208
274
  }
209
275
  /**
210
276
  * Cleans up both deletedCache and versionIndex based on minActiveVersion.
@@ -290,7 +356,7 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
290
356
  createNested() {
291
357
  if (this.committed) throw new Error("Transaction already committed");
292
358
  const childVersion = this.isRoot() ? this.version : this.snapshotVersion;
293
- const child = new _SyncMVCCTransaction(void 0, this, childVersion);
359
+ const child = new _SyncMVCCTransaction(void 0, void 0, this, childVersion);
294
360
  this.root.activeTransactions.add(child);
295
361
  return child;
296
362
  }
@@ -369,22 +435,54 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
369
435
  commit(label) {
370
436
  const { created, updated, deleted } = this.getResultEntries();
371
437
  if (this.committed) {
372
- return { label, success: false, error: "Transaction already committed", conflict: void 0, created, updated, deleted };
438
+ return {
439
+ label,
440
+ success: false,
441
+ error: "Transaction already committed",
442
+ conflict: void 0,
443
+ created,
444
+ updated,
445
+ deleted
446
+ };
373
447
  }
374
448
  if (this.hasCommittedAncestor()) {
375
- return { label, success: false, error: "Ancestor transaction already committed", conflict: void 0, created, updated, deleted };
449
+ return {
450
+ label,
451
+ success: false,
452
+ error: "Ancestor transaction already committed",
453
+ conflict: void 0,
454
+ created,
455
+ updated,
456
+ deleted
457
+ };
376
458
  }
377
459
  if (this.parent) {
378
460
  const failure = this.parent._merge(this);
379
461
  if (failure) {
380
- return { label, success: false, error: failure.error, conflict: failure.conflict, created, updated, deleted };
462
+ return {
463
+ label,
464
+ success: false,
465
+ error: failure.error,
466
+ conflict: failure.conflict,
467
+ created,
468
+ updated,
469
+ deleted
470
+ };
381
471
  }
382
472
  this.committed = true;
383
473
  } else {
384
474
  if (this.writeBuffer.size > 0 || this.deleteBuffer.size > 0) {
385
475
  const failure = this._merge(this);
386
476
  if (failure) {
387
- return { label, success: false, error: failure.error, conflict: failure.conflict, created: [], updated: [], deleted: [] };
477
+ return {
478
+ label,
479
+ success: false,
480
+ error: failure.error,
481
+ conflict: failure.conflict,
482
+ created: [],
483
+ updated: [],
484
+ deleted: []
485
+ };
388
486
  }
389
487
  this.writeBuffer.clear();
390
488
  this.deleteBuffer.clear();
@@ -397,7 +495,13 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
397
495
  this.snapshotVersion = this.version;
398
496
  }
399
497
  }
400
- return { label, success: true, created, updated, deleted };
498
+ return {
499
+ label,
500
+ success: true,
501
+ created,
502
+ updated,
503
+ deleted
504
+ };
401
505
  }
402
506
  _merge(child) {
403
507
  if (this.parent) {
@@ -406,7 +510,11 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
406
510
  if (lastModLocalVer !== void 0 && lastModLocalVer > child.snapshotLocalVersion) {
407
511
  return {
408
512
  error: `Commit conflict: Key '${key}' was modified by a newer transaction (Local v${lastModLocalVer})`,
409
- conflict: { key, parent: this.read(key), child: child.read(key) }
513
+ conflict: {
514
+ key,
515
+ parent: this.read(key),
516
+ child: child.read(key)
517
+ }
410
518
  };
411
519
  }
412
520
  }
@@ -415,7 +523,11 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
415
523
  if (lastModLocalVer !== void 0 && lastModLocalVer > child.snapshotLocalVersion) {
416
524
  return {
417
525
  error: `Commit conflict: Key '${key}' was modified by a newer transaction (Local v${lastModLocalVer})`,
418
- conflict: { key, parent: this.read(key), child: child.read(key) }
526
+ conflict: {
527
+ key,
528
+ parent: this.read(key),
529
+ child: child.read(key)
530
+ }
419
531
  };
420
532
  }
421
533
  }
@@ -444,7 +556,11 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
444
556
  if (lastVer > child.snapshotVersion) {
445
557
  return {
446
558
  error: `Commit conflict: Key '${key}' was modified by a newer transaction (v${lastVer})`,
447
- conflict: { key, parent: this.read(key), child: child.read(key) }
559
+ conflict: {
560
+ key,
561
+ parent: this.read(key),
562
+ child: child.read(key)
563
+ }
448
564
  };
449
565
  }
450
566
  }
@@ -452,7 +568,11 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
452
568
  if (lastModLocalVer !== void 0 && lastModLocalVer > child.snapshotLocalVersion) {
453
569
  return {
454
570
  error: `Commit conflict: Key '${key}' was modified by a newer transaction in the same session (Local v${lastModLocalVer})`,
455
- conflict: { key, parent: this.read(key), child: child.read(key) }
571
+ conflict: {
572
+ key,
573
+ parent: this.read(key),
574
+ child: child.read(key)
575
+ }
456
576
  };
457
577
  }
458
578
  }
@@ -487,10 +607,14 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
487
607
  _diskWrite(key, value, version) {
488
608
  const strategy = this.strategy;
489
609
  if (!strategy) throw new Error("Root Transaction missing strategy");
490
- if (strategy.exists(key)) {
491
- const currentVal = strategy.read(key);
610
+ const rootAsAny = this.root;
611
+ if (this._diskExists(key, version)) {
612
+ const currentVal = rootAsAny.diskCache.has(key) ? rootAsAny.diskCache.get(key) : strategy.read(key);
492
613
  if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
493
614
  this.deletedCache.get(key).push({ value: currentVal, deletedAtVersion: version });
615
+ rootAsAny.diskCache.set(key, value);
616
+ } else {
617
+ rootAsAny.diskCache.set(key, value);
494
618
  }
495
619
  strategy.write(key, value);
496
620
  if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
@@ -501,7 +625,13 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
501
625
  if (!strategy) throw new Error("Root Transaction missing strategy");
502
626
  const versions = this.versionIndex.get(key);
503
627
  if (!versions) {
504
- return strategy.exists(key) ? strategy.read(key) : null;
628
+ const rootAsAny = this.root;
629
+ if (this._diskExists(key, snapshotVersion)) {
630
+ const val = rootAsAny.diskCache.has(key) ? rootAsAny.diskCache.get(key) : strategy.read(key);
631
+ rootAsAny.diskCache.set(key, val);
632
+ return val;
633
+ }
634
+ return null;
505
635
  }
506
636
  let targetVerObj = null;
507
637
  let nextVerObj = null;
@@ -525,7 +655,13 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
525
655
  if (!targetVerObj.exists) return null;
526
656
  if (!nextVerObj) {
527
657
  if (this.writeBuffer.has(key)) return this.writeBuffer.get(key);
528
- return strategy.read(key);
658
+ if (this._diskExists(key, snapshotVersion)) {
659
+ const rootAsAny = this.root;
660
+ const val = rootAsAny.diskCache.has(key) ? rootAsAny.diskCache.get(key) : strategy.read(key);
661
+ rootAsAny.diskCache.set(key, val);
662
+ return val;
663
+ }
664
+ return null;
529
665
  }
530
666
  const cached = this.deletedCache.get(key);
531
667
  if (cached) {
@@ -539,7 +675,11 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
539
675
  if (!strategy) throw new Error("Root Transaction missing strategy");
540
676
  const versions = this.versionIndex.get(key);
541
677
  if (!versions) {
542
- return strategy.exists(key);
678
+ const rootAsAny = this.root;
679
+ if (rootAsAny.diskCache.has(key)) return rootAsAny.diskCache.get(key) !== null;
680
+ const exists = strategy.exists(key);
681
+ if (!exists) rootAsAny.diskCache.set(key, null);
682
+ return exists;
543
683
  }
544
684
  let targetVerObj = null;
545
685
  let nextVerObj = null;
@@ -565,11 +705,13 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
565
705
  _diskDelete(key, snapshotVersion) {
566
706
  const strategy = this.strategy;
567
707
  if (!strategy) throw new Error("Root Transaction missing strategy");
568
- if (strategy.exists(key)) {
569
- const currentVal = strategy.read(key);
708
+ const rootAsAny = this.root;
709
+ if (this._diskExists(key, snapshotVersion)) {
710
+ const currentVal = rootAsAny.diskCache.has(key) ? rootAsAny.diskCache.get(key) : strategy.read(key);
570
711
  if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
571
712
  this.deletedCache.get(key).push({ value: currentVal, deletedAtVersion: snapshotVersion });
572
713
  strategy.delete(key);
714
+ rootAsAny.diskCache.delete(key);
573
715
  }
574
716
  if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
575
717
  this.versionIndex.get(key).push({ version: snapshotVersion, exists: false });
@@ -883,7 +1025,7 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
883
1025
  createNested() {
884
1026
  if (this.committed) throw new Error("Transaction already committed");
885
1027
  const childVersion = this.isRoot() ? this.version : this.snapshotVersion;
886
- const child = new _AsyncMVCCTransaction(void 0, this, childVersion);
1028
+ const child = new _AsyncMVCCTransaction(void 0, void 0, this, childVersion);
887
1029
  this.root.activeTransactions.add(child);
888
1030
  return child;
889
1031
  }
@@ -962,22 +1104,54 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
962
1104
  async commit(label) {
963
1105
  const { created, updated, deleted } = this.getResultEntries();
964
1106
  if (this.committed) {
965
- return { label, success: false, error: "Transaction already committed", conflict: void 0, created, updated, deleted };
1107
+ return {
1108
+ label,
1109
+ success: false,
1110
+ error: "Transaction already committed",
1111
+ conflict: void 0,
1112
+ created,
1113
+ updated,
1114
+ deleted
1115
+ };
966
1116
  }
967
1117
  if (this.hasCommittedAncestor()) {
968
- return { label, success: false, error: "Ancestor transaction already committed", conflict: void 0, created, updated, deleted };
1118
+ return {
1119
+ label,
1120
+ success: false,
1121
+ error: "Ancestor transaction already committed",
1122
+ conflict: void 0,
1123
+ created,
1124
+ updated,
1125
+ deleted
1126
+ };
969
1127
  }
970
1128
  if (this.parent) {
971
1129
  const failure = await this.parent._merge(this);
972
1130
  if (failure) {
973
- return { label, success: false, error: failure.error, conflict: failure.conflict, created, updated, deleted };
1131
+ return {
1132
+ label,
1133
+ success: false,
1134
+ error: failure.error,
1135
+ conflict: failure.conflict,
1136
+ created,
1137
+ updated,
1138
+ deleted
1139
+ };
974
1140
  }
975
1141
  this.committed = true;
976
1142
  } else {
977
1143
  if (this.writeBuffer.size > 0 || this.deleteBuffer.size > 0) {
978
1144
  const failure = await this._merge(this);
979
1145
  if (failure) {
980
- return { label, success: false, error: failure.error, conflict: failure.conflict, created: [], updated: [], deleted: [] };
1146
+ return {
1147
+ label,
1148
+ success: false,
1149
+ error: failure.error,
1150
+ conflict: failure.conflict,
1151
+ created: [],
1152
+ updated: [],
1153
+ deleted: []
1154
+ };
981
1155
  }
982
1156
  this.writeBuffer.clear();
983
1157
  this.deleteBuffer.clear();
@@ -990,7 +1164,13 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
990
1164
  this.snapshotVersion = this.version;
991
1165
  }
992
1166
  }
993
- return { label, success: true, created, updated, deleted };
1167
+ return {
1168
+ label,
1169
+ success: true,
1170
+ created,
1171
+ updated,
1172
+ deleted
1173
+ };
994
1174
  }
995
1175
  async _merge(child) {
996
1176
  return this.writeLock(async () => {
@@ -1000,7 +1180,11 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1000
1180
  if (lastModLocalVer !== void 0 && lastModLocalVer > child.snapshotLocalVersion) {
1001
1181
  return {
1002
1182
  error: `Commit conflict: Key '${key}' was modified by a newer transaction (Local v${lastModLocalVer})`,
1003
- conflict: { key, parent: await this.read(key), child: await child.read(key) }
1183
+ conflict: {
1184
+ key,
1185
+ parent: await this.read(key),
1186
+ child: await child.read(key)
1187
+ }
1004
1188
  };
1005
1189
  }
1006
1190
  }
@@ -1009,7 +1193,11 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1009
1193
  if (lastModLocalVer !== void 0 && lastModLocalVer > child.snapshotLocalVersion) {
1010
1194
  return {
1011
1195
  error: `Commit conflict: Key '${key}' was modified by a newer transaction (Local v${lastModLocalVer})`,
1012
- conflict: { key, parent: await this.read(key), child: await child.read(key) }
1196
+ conflict: {
1197
+ key,
1198
+ parent: await this.read(key),
1199
+ child: await child.read(key)
1200
+ }
1013
1201
  };
1014
1202
  }
1015
1203
  }
@@ -1039,7 +1227,11 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1039
1227
  if (lastVer > child.snapshotVersion) {
1040
1228
  return {
1041
1229
  error: `Commit conflict: Key '${key}' was modified by a newer transaction (v${lastVer})`,
1042
- conflict: { key, parent: await this.read(key), child: await child.read(key) }
1230
+ conflict: {
1231
+ key,
1232
+ parent: await this.read(key),
1233
+ child: await child.read(key)
1234
+ }
1043
1235
  };
1044
1236
  }
1045
1237
  }
@@ -1047,7 +1239,11 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1047
1239
  if (lastModLocalVer !== void 0 && lastModLocalVer > child.snapshotLocalVersion) {
1048
1240
  return {
1049
1241
  error: `Commit conflict: Key '${key}' was modified by a newer transaction in the same session (Local v${lastModLocalVer})`,
1050
- conflict: { key, parent: await this.read(key), child: await child.read(key) }
1242
+ conflict: {
1243
+ key,
1244
+ parent: await this.read(key),
1245
+ child: await child.read(key)
1246
+ }
1051
1247
  };
1052
1248
  }
1053
1249
  }
@@ -1083,10 +1279,14 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1083
1279
  async _diskWrite(key, value, version) {
1084
1280
  const strategy = this.strategy;
1085
1281
  if (!strategy) throw new Error("Root Transaction missing strategy");
1086
- if (await strategy.exists(key)) {
1087
- const currentVal = await strategy.read(key);
1282
+ const rootAsAny = this.root;
1283
+ if (await this._diskExists(key, version)) {
1284
+ const currentVal = rootAsAny.diskCache.has(key) ? rootAsAny.diskCache.get(key) : await strategy.read(key);
1088
1285
  if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
1089
1286
  this.deletedCache.get(key).push({ value: currentVal, deletedAtVersion: version });
1287
+ rootAsAny.diskCache.set(key, value);
1288
+ } else {
1289
+ rootAsAny.diskCache.set(key, value);
1090
1290
  }
1091
1291
  await strategy.write(key, value);
1092
1292
  if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
@@ -1097,7 +1297,13 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1097
1297
  if (!strategy) throw new Error("Root Transaction missing strategy");
1098
1298
  const versions = this.versionIndex.get(key);
1099
1299
  if (!versions) {
1100
- return await strategy.exists(key) ? await strategy.read(key) : null;
1300
+ const rootAsAny = this.root;
1301
+ if (await this._diskExists(key, snapshotVersion)) {
1302
+ const val = rootAsAny.diskCache.has(key) ? rootAsAny.diskCache.get(key) : await strategy.read(key);
1303
+ rootAsAny.diskCache.set(key, val);
1304
+ return val;
1305
+ }
1306
+ return null;
1101
1307
  }
1102
1308
  let targetVerObj = null;
1103
1309
  let nextVerObj = null;
@@ -1121,7 +1327,13 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1121
1327
  if (!targetVerObj.exists) return null;
1122
1328
  if (!nextVerObj) {
1123
1329
  if (this.writeBuffer.has(key)) return this.writeBuffer.get(key);
1124
- return strategy.read(key);
1330
+ if (await this._diskExists(key, snapshotVersion)) {
1331
+ const rootAsAny = this.root;
1332
+ const val = rootAsAny.diskCache.has(key) ? rootAsAny.diskCache.get(key) : await strategy.read(key);
1333
+ rootAsAny.diskCache.set(key, val);
1334
+ return val;
1335
+ }
1336
+ return null;
1125
1337
  }
1126
1338
  const cached = this.deletedCache.get(key);
1127
1339
  if (cached) {
@@ -1135,7 +1347,11 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1135
1347
  if (!strategy) throw new Error("Root Transaction missing strategy");
1136
1348
  const versions = this.versionIndex.get(key);
1137
1349
  if (!versions) {
1138
- return await strategy.exists(key);
1350
+ const rootAsAny = this.root;
1351
+ if (rootAsAny.diskCache.has(key)) return rootAsAny.diskCache.get(key) !== null;
1352
+ const exists = await strategy.exists(key);
1353
+ if (!exists) rootAsAny.diskCache.set(key, null);
1354
+ return exists;
1139
1355
  }
1140
1356
  let targetVerObj = null;
1141
1357
  let nextVerObj = null;
@@ -1161,344 +1377,23 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1161
1377
  async _diskDelete(key, snapshotVersion) {
1162
1378
  const strategy = this.strategy;
1163
1379
  if (!strategy) throw new Error("Root Transaction missing strategy");
1164
- if (await strategy.exists(key)) {
1165
- const currentVal = await strategy.read(key);
1380
+ const rootAsAny = this.root;
1381
+ if (await this._diskExists(key, snapshotVersion)) {
1382
+ const currentVal = rootAsAny.diskCache.has(key) ? rootAsAny.diskCache.get(key) : await strategy.read(key);
1166
1383
  if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
1167
1384
  this.deletedCache.get(key).push({ value: currentVal, deletedAtVersion: snapshotVersion });
1168
1385
  await strategy.delete(key);
1386
+ rootAsAny.diskCache.delete(key);
1169
1387
  }
1170
1388
  if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
1171
1389
  this.versionIndex.get(key).push({ version: snapshotVersion, exists: false });
1172
1390
  }
1173
1391
  };
1174
1392
 
1175
- // node_modules/cache-entanglement/dist/esm/index.mjs
1176
- var LRUMap = class {
1177
- capacity;
1178
- map;
1179
- head = null;
1180
- tail = null;
1181
- /**
1182
- * Creates an instance of LRUMap.
1183
- * @param capacity The maximum number of items the cache can hold.
1184
- */
1185
- constructor(capacity) {
1186
- this.capacity = capacity;
1187
- this.map = /* @__PURE__ */ new Map();
1188
- }
1189
- /**
1190
- * Promotes a node to the head of the linked list (marks as most recently used).
1191
- * @param node The node to promote.
1192
- */
1193
- promote(node) {
1194
- this.extract(node);
1195
- this.prepend(node);
1196
- }
1197
- /**
1198
- * Disconnects a node from the doubly linked list.
1199
- * @param node The node to extract.
1200
- */
1201
- extract(node) {
1202
- if (node.prev) node.prev.next = node.next;
1203
- else this.head = node.next;
1204
- if (node.next) node.next.prev = node.prev;
1205
- else this.tail = node.prev;
1206
- node.prev = null;
1207
- node.next = null;
1208
- }
1209
- /**
1210
- * Inserts a node at the head of the doubly linked list.
1211
- * @param node The node to prepend.
1212
- */
1213
- prepend(node) {
1214
- node.next = this.head;
1215
- if (this.head) this.head.prev = node;
1216
- this.head = node;
1217
- if (!this.tail) this.tail = node;
1218
- }
1219
- /**
1220
- * Stores or updates a value by key.
1221
- * If the capacity is exceeded, the least recently used item (tail) is removed.
1222
- * @param key The key to store.
1223
- * @param value The value to store.
1224
- */
1225
- set(key, value) {
1226
- const existing = this.map.get(key);
1227
- if (existing) {
1228
- existing.value = value;
1229
- this.promote(existing);
1230
- return;
1231
- }
1232
- const newNode = { key, value, prev: null, next: null };
1233
- this.map.set(key, newNode);
1234
- this.prepend(newNode);
1235
- if (this.map.size > this.capacity && this.tail) {
1236
- this.map.delete(this.tail.key);
1237
- this.extract(this.tail);
1238
- }
1239
- }
1240
- /**
1241
- * Retrieves a value by key.
1242
- * Accessing the item moves it to the "most recently used" position.
1243
- * @param key The key to look for.
1244
- * @returns The value associated with the key, or undefined if not found.
1245
- */
1246
- get(key) {
1247
- const node = this.map.get(key);
1248
- if (!node) return void 0;
1249
- this.promote(node);
1250
- return node.value;
1251
- }
1252
- /**
1253
- * Checks if a key exists in the cache without changing its access order.
1254
- * @param key The key to check.
1255
- * @returns True if the key exists, false otherwise.
1256
- */
1257
- has(key) {
1258
- return this.map.has(key);
1259
- }
1260
- /**
1261
- * Removes a key and its associated value from the cache.
1262
- * @param key The key to remove.
1263
- * @returns True if the key was found and removed, false otherwise.
1264
- */
1265
- delete(key) {
1266
- const node = this.map.get(key);
1267
- if (!node) return false;
1268
- this.extract(node);
1269
- this.map.delete(key);
1270
- return true;
1271
- }
1272
- /**
1273
- * Returns an iterator of keys in the order of most recently used to least recently used.
1274
- * @returns An iterable iterator of keys.
1275
- */
1276
- *keys() {
1277
- let current = this.head;
1278
- while (current) {
1279
- yield current.key;
1280
- current = current.next;
1281
- }
1282
- }
1283
- /**
1284
- * Returns the current number of items in the cache.
1285
- */
1286
- get size() {
1287
- return this.map.size;
1288
- }
1289
- /**
1290
- * Clears all items from the cache.
1291
- */
1292
- clear() {
1293
- this.map.clear();
1294
- this.head = null;
1295
- this.tail = null;
1296
- }
1297
- };
1298
- var CacheEntanglement = class {
1299
- creation;
1300
- beforeUpdateHook;
1301
- capacity;
1302
- dependencies;
1303
- caches;
1304
- parameters;
1305
- assignments;
1306
- dependencyProperties;
1307
- updateRequirements;
1308
- constructor(creation, option) {
1309
- option = option ?? {};
1310
- const {
1311
- dependencies,
1312
- capacity,
1313
- beforeUpdateHook
1314
- } = option;
1315
- this.creation = creation;
1316
- this.beforeUpdateHook = beforeUpdateHook ?? (() => {
1317
- });
1318
- this.capacity = capacity ?? 100;
1319
- this.assignments = [];
1320
- this.caches = new LRUMap(this.capacity);
1321
- this.parameters = /* @__PURE__ */ new Map();
1322
- this.dependencies = dependencies ?? {};
1323
- this.dependencyProperties = Object.keys(this.dependencies);
1324
- this.updateRequirements = /* @__PURE__ */ new Set();
1325
- for (const name in this.dependencies) {
1326
- const dependency = this.dependencies[name];
1327
- if (!dependency.assignments.includes(this)) {
1328
- dependency.assignments.push(this);
1329
- }
1330
- }
1331
- }
1332
- bubbleUpdateSignal(key) {
1333
- this.updateRequirements.add(key);
1334
- for (let i = 0, len = this.assignments.length; i < len; i++) {
1335
- const t = this.assignments[i];
1336
- const instance = t;
1337
- for (const cacheKey of instance.caches.keys()) {
1338
- if (cacheKey === key || cacheKey.startsWith(`${key}/`)) {
1339
- instance.bubbleUpdateSignal(cacheKey);
1340
- }
1341
- }
1342
- }
1343
- }
1344
- dependencyKey(key) {
1345
- const i = key.lastIndexOf("/");
1346
- if (i === -1) {
1347
- return key;
1348
- }
1349
- return key.substring(0, i);
1350
- }
1351
- /**
1352
- * Returns all keys stored in the instance.
1353
- */
1354
- keys() {
1355
- return this.parameters.keys();
1356
- }
1357
- /**
1358
- * Deletes all cache values stored in the instance.
1359
- */
1360
- clear() {
1361
- for (const key of this.keys()) {
1362
- this.delete(key);
1363
- }
1364
- }
1365
- /**
1366
- * Checks if there is a cache value stored in the key within the instance.
1367
- * @param key The key to search.
1368
- */
1369
- exists(key) {
1370
- return this.parameters.has(key);
1371
- }
1372
- /**
1373
- * Checks if there is a cache value stored in the key within the instance.
1374
- * This method is an alias for `exists`.
1375
- * @param key The key to search.
1376
- */
1377
- has(key) {
1378
- return this.exists(key);
1379
- }
1380
- /**
1381
- * Deletes the cache value stored in the key within the instance.
1382
- * @param key The key to delete.
1383
- */
1384
- delete(key) {
1385
- this.caches.delete(key);
1386
- this.parameters.delete(key);
1387
- this.updateRequirements.delete(key);
1388
- for (let i = 0, len = this.assignments.length; i < len; i++) {
1389
- const t = this.assignments[i];
1390
- const instance = t;
1391
- for (const cacheKey of instance.keys()) {
1392
- if (cacheKey === key || cacheKey.startsWith(`${key}/`)) {
1393
- instance.delete(cacheKey);
1394
- }
1395
- }
1396
- }
1397
- }
1398
- };
1399
- var CacheData = class _CacheData {
1400
- static StructuredClone = globalThis.structuredClone.bind(globalThis);
1401
- _value;
1402
- constructor(value) {
1403
- this._value = value;
1404
- }
1405
- /**
1406
- * This is cached data.
1407
- * It was generated at the time of caching, so there is a risk of modification if it's an object due to shallow copying.
1408
- * Therefore, if it's not a primitive type, please avoid using this value directly and use the `clone` method to use a copied version of the data.
1409
- */
1410
- get raw() {
1411
- return this._value;
1412
- }
1413
- /**
1414
- * The method returns a copied value of the cached data.
1415
- * You can pass a function as a parameter to copy the value. This parameter function should return the copied value.
1416
- *
1417
- * If no parameter is passed, it defaults to using `structuredClone` function to copy the value.
1418
- * If you prefer shallow copying instead of deep copying,
1419
- * you can use the default options `array-shallow-copy`, `object-shallow-copy` and `deep-copy`,
1420
- * which are replaced with functions to shallow copy arrays and objects, respectively. This is a syntactic sugar.
1421
- * @param strategy The function that returns the copied value.
1422
- * If you want to perform a shallow copy, simply pass the strings `array-shallow-copy` or `object-shallow-copy` for easy use.
1423
- * The `array-shallow-copy` strategy performs a shallow copy of an array.
1424
- * The `object-shallow-copy` strategy performs a shallow copy of an object.
1425
- * The `deep-copy` strategy performs a deep copy of the value using `structuredClone`.
1426
- * The default is `deep-copy`.
1427
- */
1428
- clone(strategy = "deep-copy") {
1429
- if (strategy && typeof strategy !== "string") {
1430
- return strategy(this.raw);
1431
- }
1432
- switch (strategy) {
1433
- case "array-shallow-copy":
1434
- return [].concat(this.raw);
1435
- case "object-shallow-copy":
1436
- return Object.assign({}, this.raw);
1437
- case "deep-copy":
1438
- default:
1439
- return _CacheData.StructuredClone(this.raw);
1440
- }
1441
- }
1442
- };
1443
- var CacheEntanglementSync = class extends CacheEntanglement {
1444
- constructor(creation, option) {
1445
- super(creation, option);
1446
- }
1447
- recache(key) {
1448
- if (!this.parameters.has(key)) {
1449
- return;
1450
- }
1451
- if (!this.caches.has(key) || this.updateRequirements.has(key)) {
1452
- this.resolve(key, ...this.parameters.get(key));
1453
- }
1454
- return this.caches.get(key);
1455
- }
1456
- resolve(key, ...parameter) {
1457
- const resolved = {};
1458
- const dependencyKey = this.dependencyKey(key);
1459
- this.beforeUpdateHook(key, dependencyKey, ...parameter);
1460
- for (let i = 0, len = this.dependencyProperties.length; i < len; i++) {
1461
- const name = this.dependencyProperties[i];
1462
- const dependency = this.dependencies[name];
1463
- if (!dependency.exists(key) && !dependency.exists(dependencyKey)) {
1464
- throw new Error(`The key '${key}' or '${dependencyKey}' has not been assigned yet in dependency '${name.toString()}'.`, {
1465
- cause: {
1466
- from: this
1467
- }
1468
- });
1469
- }
1470
- const dependencyValue = dependency.recache(key) ?? dependency.recache(dependencyKey);
1471
- resolved[name] = dependencyValue;
1472
- }
1473
- const value = new CacheData(this.creation(key, resolved, ...parameter));
1474
- this.updateRequirements.delete(key);
1475
- this.parameters.set(key, parameter);
1476
- this.caches.set(key, value);
1477
- return value;
1478
- }
1479
- get(key) {
1480
- if (!this.parameters.has(key)) {
1481
- throw new Error(`Cache value not found: ${key}`);
1482
- }
1483
- return this.cache(key, ...this.parameters.get(key));
1484
- }
1485
- cache(key, ...parameter) {
1486
- if (!this.caches.has(key) || this.updateRequirements.has(key)) {
1487
- this.resolve(key, ...parameter);
1488
- }
1489
- return this.caches.get(key);
1490
- }
1491
- update(key, ...parameter) {
1492
- this.bubbleUpdateSignal(key);
1493
- this.resolve(key, ...parameter);
1494
- return this.caches.get(key);
1495
- }
1496
- };
1497
-
1498
1393
  // src/base/BPTreeTransaction.ts
1499
1394
  var BPTreeTransaction = class _BPTreeTransaction {
1500
- _cachedRegexp;
1501
- nodes;
1395
+ _cachedRegexp = /* @__PURE__ */ new Map();
1396
+ nodes = /* @__PURE__ */ new Map();
1502
1397
  deletedNodeBuffer = /* @__PURE__ */ new Map();
1503
1398
  rootTx;
1504
1399
  mvccRoot;
@@ -1528,8 +1423,12 @@ var BPTreeTransaction = class _BPTreeTransaction {
1528
1423
  like: (nv, v) => {
1529
1424
  const nodeValue = this.comparator.match(nv);
1530
1425
  const value = v;
1531
- const cache = this._cachedRegexp.cache(value);
1532
- const regexp = cache.raw;
1426
+ if (!this._cachedRegexp.has(value)) {
1427
+ const pattern = value.replace(/%/g, ".*").replace(/_/g, ".");
1428
+ const regexp2 = new RegExp(`^${pattern}$`, "i");
1429
+ this._cachedRegexp.set(value, regexp2);
1430
+ }
1431
+ const regexp = this._cachedRegexp.get(value);
1533
1432
  return regexp.test(nodeValue);
1534
1433
  }
1535
1434
  };
@@ -1701,6 +1600,9 @@ var BPTreeTransaction = class _BPTreeTransaction {
1701
1600
  }
1702
1601
  return true;
1703
1602
  }
1603
+ _cloneNode(node) {
1604
+ return JSON.parse(JSON.stringify(node));
1605
+ }
1704
1606
  /**
1705
1607
  * Selects the best driver key from a condition object.
1706
1608
  * The driver key determines the starting point and traversal direction for queries.
@@ -1733,17 +1635,6 @@ var BPTreeTransaction = class _BPTreeTransaction {
1733
1635
  this.strategy = strategy;
1734
1636
  this.comparator = comparator;
1735
1637
  this.option = option ?? {};
1736
- this.nodes = new LRUMap(this.option.capacity ?? 1e3);
1737
- this._cachedRegexp = this._createCachedRegexp();
1738
- }
1739
- _createCachedRegexp() {
1740
- return new CacheEntanglementSync((key) => {
1741
- const pattern = key.replace(/%/g, ".*").replace(/_/g, ".");
1742
- const regexp = new RegExp(`^${pattern}$`, "i");
1743
- return regexp;
1744
- }, {
1745
- capacity: this.option.capacity ?? 1e3
1746
- });
1747
1638
  }
1748
1639
  ensureValues(v) {
1749
1640
  if (!Array.isArray(v)) {
@@ -1776,7 +1667,6 @@ var BPTreeTransaction = class _BPTreeTransaction {
1776
1667
  }
1777
1668
  _clearCache() {
1778
1669
  this._cachedRegexp.clear();
1779
- this.nodes.clear();
1780
1670
  }
1781
1671
  /**
1782
1672
  * Clears all cached nodes.
@@ -1829,9 +1719,6 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
1829
1719
  );
1830
1720
  }
1831
1721
  getNode(id) {
1832
- if (this.nodes.has(id)) {
1833
- return this.nodes.get(id);
1834
- }
1835
1722
  return this.mvcc.read(id);
1836
1723
  }
1837
1724
  /**
@@ -1849,23 +1736,22 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
1849
1736
  prev
1850
1737
  };
1851
1738
  this.mvcc.create(id, node);
1852
- this.nodes.set(id, node);
1853
1739
  return node;
1854
1740
  }
1855
1741
  _updateNode(node) {
1742
+ if (this.mvcc.isDeleted(node.id)) {
1743
+ return;
1744
+ }
1856
1745
  this.mvcc.write(node.id, node);
1857
- this.nodes.set(node.id, node);
1858
1746
  }
1859
1747
  _deleteNode(node) {
1748
+ if (this.mvcc.isDeleted(node.id)) {
1749
+ return;
1750
+ }
1860
1751
  this.mvcc.delete(node.id);
1861
- this.nodes.delete(node.id);
1862
1752
  }
1863
1753
  _readHead() {
1864
- if (this.nodes.has("__HEAD__")) {
1865
- return this.nodes.get("__HEAD__") ?? null;
1866
- }
1867
- const head = this.mvcc.read("__HEAD__");
1868
- return head ?? null;
1754
+ return this.mvcc.read("__HEAD__");
1869
1755
  }
1870
1756
  _writeHead(head) {
1871
1757
  if (!this.mvcc.exists("__HEAD__")) {
@@ -1873,41 +1759,45 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
1873
1759
  } else {
1874
1760
  this.mvcc.write("__HEAD__", head);
1875
1761
  }
1876
- this.nodes.set("__HEAD__", head);
1877
1762
  this.rootId = head.root;
1878
1763
  }
1879
1764
  _insertAtLeaf(node, key, value) {
1880
- if (node.values.length) {
1881
- for (let i = 0, len = node.values.length; i < len; i++) {
1882
- const nValue = node.values[i];
1765
+ let leaf = node;
1766
+ leaf = this._cloneNode(leaf);
1767
+ if (leaf.values.length) {
1768
+ for (let i = 0, len = leaf.values.length; i < len; i++) {
1769
+ const nValue = leaf.values[i];
1883
1770
  if (this.comparator.isSame(value, nValue)) {
1884
- const keys = node.keys[i];
1771
+ const keys = leaf.keys[i];
1885
1772
  if (keys.includes(key)) {
1886
1773
  break;
1887
1774
  }
1888
1775
  keys.push(key);
1889
- this._updateNode(node);
1890
- return;
1776
+ this._updateNode(leaf);
1777
+ return leaf;
1891
1778
  } else if (this.comparator.isLower(value, nValue)) {
1892
- node.values.splice(i, 0, value);
1893
- node.keys.splice(i, 0, [key]);
1894
- this._updateNode(node);
1895
- return;
1896
- } else if (i + 1 === node.values.length) {
1897
- node.values.push(value);
1898
- node.keys.push([key]);
1899
- this._updateNode(node);
1900
- return;
1779
+ leaf.values.splice(i, 0, value);
1780
+ leaf.keys.splice(i, 0, [key]);
1781
+ this._updateNode(leaf);
1782
+ return leaf;
1783
+ } else if (i + 1 === leaf.values.length) {
1784
+ leaf.values.push(value);
1785
+ leaf.keys.push([key]);
1786
+ this._updateNode(leaf);
1787
+ return leaf;
1901
1788
  }
1902
1789
  }
1903
1790
  } else {
1904
- node.values = [value];
1905
- node.keys = [[key]];
1906
- this._updateNode(node);
1907
- return;
1791
+ leaf.values = [value];
1792
+ leaf.keys = [[key]];
1793
+ this._updateNode(leaf);
1794
+ return leaf;
1908
1795
  }
1796
+ return leaf;
1909
1797
  }
1910
1798
  _insertInParent(node, value, pointer) {
1799
+ node = this._cloneNode(node);
1800
+ pointer = this._cloneNode(pointer);
1911
1801
  if (this.rootId === node.id) {
1912
1802
  const root = this._createNode(false, [node.id, pointer.id], [value]);
1913
1803
  this.rootId = root.id;
@@ -1926,7 +1816,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
1926
1816
  this._updateNode(pointer);
1927
1817
  return;
1928
1818
  }
1929
- const parentNode = this.getNode(node.parent);
1819
+ const parentNode = this._cloneNode(this.getNode(node.parent));
1930
1820
  const nodeIndex = parentNode.keys.indexOf(node.id);
1931
1821
  if (nodeIndex === -1) {
1932
1822
  throw new Error(`Node ${node.id} not found in parent ${parentNode.id}`);
@@ -1942,7 +1832,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
1942
1832
  leftSibling.next = pointer.id;
1943
1833
  this._updateNode(leftSibling);
1944
1834
  if (oldNextId) {
1945
- const oldNext = this.getNode(oldNextId);
1835
+ const oldNext = this._cloneNode(this.getNode(oldNextId));
1946
1836
  oldNext.prev = pointer.id;
1947
1837
  this._updateNode(oldNext);
1948
1838
  }
@@ -1959,12 +1849,12 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
1959
1849
  parentNode.values = parentNode.values.slice(0, mid);
1960
1850
  parentNode.keys = parentNode.keys.slice(0, mid + 1);
1961
1851
  for (const k of parentNode.keys) {
1962
- const n = this.getNode(k);
1852
+ const n = this._cloneNode(this.getNode(k));
1963
1853
  n.parent = parentNode.id;
1964
1854
  this._updateNode(n);
1965
1855
  }
1966
1856
  for (const k of parentPointer.keys) {
1967
- const n = this.getNode(k);
1857
+ const n = this._cloneNode(this.getNode(k));
1968
1858
  n.parent = parentPointer.id;
1969
1859
  this._updateNode(n);
1970
1860
  }
@@ -2152,21 +2042,6 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2152
2042
  }
2153
2043
  return false;
2154
2044
  }
2155
- forceUpdate(id) {
2156
- if (id) {
2157
- this.nodes.delete(id);
2158
- this.getNode(id);
2159
- return 1;
2160
- }
2161
- const keys = Array.from(this.nodes.keys());
2162
- for (const key of keys) {
2163
- this.nodes.delete(key);
2164
- }
2165
- for (const key of keys) {
2166
- this.getNode(key);
2167
- }
2168
- return keys.length;
2169
- }
2170
2045
  get(key) {
2171
2046
  let node = this.leftestNode();
2172
2047
  while (true) {
@@ -2252,10 +2127,10 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2252
2127
  return map;
2253
2128
  }
2254
2129
  insert(key, value) {
2255
- const before = this.insertableNode(value);
2256
- this._insertAtLeaf(before, key, value);
2130
+ let before = this.insertableNode(value);
2131
+ before = this._insertAtLeaf(before, key, value);
2257
2132
  if (before.values.length === this.order) {
2258
- const after = this._createNode(
2133
+ let after = this._createNode(
2259
2134
  true,
2260
2135
  [],
2261
2136
  [],
@@ -2264,14 +2139,18 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2264
2139
  null
2265
2140
  );
2266
2141
  const mid = Math.ceil(this.order / 2) - 1;
2142
+ after = this._cloneNode(after);
2267
2143
  after.values = before.values.slice(mid + 1);
2268
2144
  after.keys = before.keys.slice(mid + 1);
2269
2145
  before.values = before.values.slice(0, mid + 1);
2270
2146
  before.keys = before.keys.slice(0, mid + 1);
2147
+ this._updateNode(before);
2148
+ this._updateNode(after);
2271
2149
  this._insertInParent(before, after.values[0], after);
2272
2150
  }
2273
2151
  }
2274
2152
  _deleteEntry(node, key) {
2153
+ node = this._cloneNode(node);
2275
2154
  if (!node.leaf) {
2276
2155
  let keyIndex = -1;
2277
2156
  for (let i = 0, len = node.keys.length; i < len; i++) {
@@ -2290,7 +2169,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2290
2169
  if (this.rootId === node.id && node.keys.length === 1 && !node.leaf) {
2291
2170
  const keys = node.keys;
2292
2171
  this._deleteNode(node);
2293
- const newRoot = this.getNode(keys[0]);
2172
+ const newRoot = this._cloneNode(this.getNode(keys[0]));
2294
2173
  newRoot.parent = null;
2295
2174
  this._updateNode(newRoot);
2296
2175
  this._writeHead({
@@ -2298,17 +2177,17 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2298
2177
  order: this.order,
2299
2178
  data: this.strategy.head.data
2300
2179
  });
2301
- return;
2180
+ return node;
2302
2181
  } else if (this.rootId === node.id) {
2303
2182
  this._writeHead({
2304
2183
  root: node.id,
2305
2184
  order: this.order,
2306
2185
  data: this.strategy.head.data
2307
2186
  });
2308
- return;
2187
+ return node;
2309
2188
  } else if (node.keys.length < Math.ceil(this.order / 2) && !node.leaf || node.values.length < Math.ceil((this.order - 1) / 2) && node.leaf) {
2310
2189
  if (node.parent === null) {
2311
- return;
2190
+ return node;
2312
2191
  }
2313
2192
  let isPredecessor = false;
2314
2193
  let parentNode = this.getNode(node.parent);
@@ -2320,11 +2199,11 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2320
2199
  const nKey = parentNode.keys[i];
2321
2200
  if (nKey === node.id) {
2322
2201
  if (i > 0) {
2323
- prevNode = this.getNode(parentNode.keys[i - 1]);
2202
+ prevNode = this._cloneNode(this.getNode(parentNode.keys[i - 1]));
2324
2203
  prevValue = parentNode.values[i - 1];
2325
2204
  }
2326
2205
  if (i < parentNode.keys.length - 1) {
2327
- nextNode = this.getNode(parentNode.keys[i + 1]);
2206
+ nextNode = this._cloneNode(this.getNode(parentNode.keys[i + 1]));
2328
2207
  postValue = parentNode.values[i];
2329
2208
  }
2330
2209
  }
@@ -2349,7 +2228,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2349
2228
  }
2350
2229
  }
2351
2230
  if (!pointer) {
2352
- return;
2231
+ return node;
2353
2232
  }
2354
2233
  if (node.values.length + pointer.values.length < this.order) {
2355
2234
  if (!isPredecessor) {
@@ -2363,7 +2242,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2363
2242
  } else {
2364
2243
  pointer.next = node.next;
2365
2244
  if (pointer.next) {
2366
- const n = this.getNode(pointer.next);
2245
+ const n = this._cloneNode(this.getNode(pointer.next));
2367
2246
  n.prev = pointer.id;
2368
2247
  this._updateNode(n);
2369
2248
  }
@@ -2372,14 +2251,14 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2372
2251
  if (!pointer.leaf) {
2373
2252
  const keys = pointer.keys;
2374
2253
  for (const key2 of keys) {
2375
- const node2 = this.getNode(key2);
2254
+ const node2 = this._cloneNode(this.getNode(key2));
2376
2255
  node2.parent = pointer.id;
2377
2256
  this._updateNode(node2);
2378
2257
  }
2379
2258
  }
2380
2259
  this._deleteNode(node);
2381
2260
  this._updateNode(pointer);
2382
- this._deleteEntry(this.getNode(node.parent), node.id);
2261
+ this._deleteEntry(this._cloneNode(this.getNode(node.parent)), node.id);
2383
2262
  } else {
2384
2263
  if (isPredecessor) {
2385
2264
  let pointerPm;
@@ -2389,7 +2268,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2389
2268
  pointerKm = pointer.values.splice(-1)[0];
2390
2269
  node.keys = [pointerPm, ...node.keys];
2391
2270
  node.values = [guess, ...node.values];
2392
- parentNode = this.getNode(node.parent);
2271
+ parentNode = this._cloneNode(this.getNode(node.parent));
2393
2272
  const nodeIndex = parentNode.keys.indexOf(node.id);
2394
2273
  if (nodeIndex > 0) {
2395
2274
  parentNode.values[nodeIndex - 1] = pointerKm;
@@ -2400,7 +2279,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2400
2279
  pointerKm = pointer.values.splice(-1)[0];
2401
2280
  node.keys = [pointerPm, ...node.keys];
2402
2281
  node.values = [pointerKm, ...node.values];
2403
- parentNode = this.getNode(node.parent);
2282
+ parentNode = this._cloneNode(this.getNode(node.parent));
2404
2283
  const nodeIndex = parentNode.keys.indexOf(node.id);
2405
2284
  if (nodeIndex > 0) {
2406
2285
  parentNode.values[nodeIndex - 1] = pointerKm;
@@ -2417,7 +2296,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2417
2296
  pointerK0 = pointer.values.splice(0, 1)[0];
2418
2297
  node.keys = [...node.keys, pointerP0];
2419
2298
  node.values = [...node.values, guess];
2420
- parentNode = this.getNode(node.parent);
2299
+ parentNode = this._cloneNode(this.getNode(node.parent));
2421
2300
  const pointerIndex = parentNode.keys.indexOf(pointer.id);
2422
2301
  if (pointerIndex > 0) {
2423
2302
  parentNode.values[pointerIndex - 1] = pointerK0;
@@ -2428,7 +2307,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2428
2307
  pointerK0 = pointer.values.splice(0, 1)[0];
2429
2308
  node.keys = [...node.keys, pointerP0];
2430
2309
  node.values = [...node.values, pointerK0];
2431
- parentNode = this.getNode(node.parent);
2310
+ parentNode = this._cloneNode(this.getNode(node.parent));
2432
2311
  const pointerIndex = parentNode.keys.indexOf(pointer.id);
2433
2312
  if (pointerIndex > 0) {
2434
2313
  parentNode.values[pointerIndex - 1] = pointer.values[0];
@@ -2440,21 +2319,21 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2440
2319
  }
2441
2320
  if (!pointer.leaf) {
2442
2321
  for (const key2 of pointer.keys) {
2443
- const n = this.getNode(key2);
2322
+ const n = this._cloneNode(this.getNode(key2));
2444
2323
  n.parent = pointer.id;
2445
2324
  this._updateNode(n);
2446
2325
  }
2447
2326
  }
2448
2327
  if (!node.leaf) {
2449
2328
  for (const key2 of node.keys) {
2450
- const n = this.getNode(key2);
2329
+ const n = this._cloneNode(this.getNode(key2));
2451
2330
  n.parent = node.id;
2452
2331
  this._updateNode(n);
2453
2332
  }
2454
2333
  }
2455
2334
  if (!parentNode.leaf) {
2456
2335
  for (const key2 of parentNode.keys) {
2457
- const n = this.getNode(key2);
2336
+ const n = this._cloneNode(this.getNode(key2));
2458
2337
  n.parent = parentNode.id;
2459
2338
  this._updateNode(n);
2460
2339
  }
@@ -2463,10 +2342,12 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2463
2342
  } else {
2464
2343
  this._updateNode(node);
2465
2344
  }
2345
+ return node;
2466
2346
  }
2467
2347
  delete(key, value) {
2468
2348
  let node = this.insertableNodeByPrimary(value);
2469
2349
  let found = false;
2350
+ node = this._cloneNode(node);
2470
2351
  while (true) {
2471
2352
  let i = node.values.length;
2472
2353
  while (i--) {
@@ -2481,7 +2362,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2481
2362
  node.values.splice(i, 1);
2482
2363
  }
2483
2364
  this._updateNode(node);
2484
- this._deleteEntry(node, key);
2365
+ node = this._deleteEntry(node, key);
2485
2366
  found = true;
2486
2367
  break;
2487
2368
  }
@@ -2524,15 +2405,6 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
2524
2405
  }
2525
2406
  }
2526
2407
  if (result.success) {
2527
- for (const r of result.created) {
2528
- this.nodes.set(r.key, r.data);
2529
- }
2530
- for (const r of result.updated) {
2531
- this.nodes.set(r.key, r.data);
2532
- }
2533
- for (const r of result.deleted) {
2534
- this.nodes.delete(r.key);
2535
- }
2536
2408
  }
2537
2409
  }
2538
2410
  return result;
@@ -2580,7 +2452,9 @@ var BPTreeMVCCStrategySync = class extends SyncMVCCStrategy {
2580
2452
  // src/BPTreeSync.ts
2581
2453
  var BPTreeSync = class extends BPTreeSyncTransaction {
2582
2454
  constructor(strategy, comparator, option) {
2583
- const mvccRoot = new SyncMVCCTransaction(new BPTreeMVCCStrategySync(strategy));
2455
+ const mvccRoot = new SyncMVCCTransaction(new BPTreeMVCCStrategySync(strategy), {
2456
+ cacheCapacity: option?.capacity ?? void 0
2457
+ });
2584
2458
  super(
2585
2459
  null,
2586
2460
  mvccRoot,
@@ -2907,9 +2781,6 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
2907
2781
  });
2908
2782
  }
2909
2783
  async getNode(id) {
2910
- if (this.nodes.has(id)) {
2911
- return this.nodes.get(id);
2912
- }
2913
2784
  return await this.mvcc.read(id);
2914
2785
  }
2915
2786
  /**
@@ -2926,66 +2797,77 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
2926
2797
  next,
2927
2798
  prev
2928
2799
  };
2800
+ const head = await this._readHead();
2801
+ if (head) {
2802
+ await this._writeHead({
2803
+ root: head.root,
2804
+ order: head.order,
2805
+ data: this.strategy.head.data
2806
+ });
2807
+ }
2929
2808
  await this.mvcc.create(id, node);
2930
- this.nodes.set(id, node);
2931
2809
  return node;
2932
2810
  }
2933
2811
  async _updateNode(node) {
2934
- await this.mvcc.write(node.id, node);
2935
- this.nodes.set(node.id, node);
2812
+ if (this.mvcc.isDeleted(node.id)) {
2813
+ return;
2814
+ }
2815
+ await this.mvcc.write(node.id, this._cloneNode(node));
2936
2816
  }
2937
2817
  async _deleteNode(node) {
2818
+ if (this.mvcc.isDeleted(node.id)) {
2819
+ return;
2820
+ }
2938
2821
  await this.mvcc.delete(node.id);
2939
- this.nodes.delete(node.id);
2940
2822
  }
2941
2823
  async _readHead() {
2942
- if (this.nodes.has("__HEAD__")) {
2943
- return this.nodes.get("__HEAD__") ?? null;
2944
- }
2945
- const head = await this.mvcc.read("__HEAD__");
2946
- return head ?? null;
2824
+ return await this.mvcc.read("__HEAD__");
2947
2825
  }
2948
2826
  async _writeHead(head) {
2949
2827
  if (!await this.mvcc.exists("__HEAD__")) {
2950
- await this.mvcc.create("__HEAD__", head);
2828
+ await this.mvcc.create("__HEAD__", this._cloneNode(head));
2951
2829
  } else {
2952
- await this.mvcc.write("__HEAD__", head);
2830
+ await this.mvcc.write("__HEAD__", this._cloneNode(head));
2953
2831
  }
2954
- this.nodes.set("__HEAD__", head);
2955
2832
  this.rootId = head.root;
2956
2833
  }
2957
2834
  async _insertAtLeaf(node, key, value) {
2958
- if (node.values.length) {
2959
- for (let i = 0, len = node.values.length; i < len; i++) {
2960
- const nValue = node.values[i];
2835
+ let leaf = node;
2836
+ leaf = this._cloneNode(leaf);
2837
+ if (leaf.values.length) {
2838
+ for (let i = 0, len = leaf.values.length; i < len; i++) {
2839
+ const nValue = leaf.values[i];
2961
2840
  if (this.comparator.isSame(value, nValue)) {
2962
- const keys = node.keys[i];
2841
+ const keys = leaf.keys[i];
2963
2842
  if (keys.includes(key)) {
2964
2843
  break;
2965
2844
  }
2966
2845
  keys.push(key);
2967
- await this._updateNode(node);
2968
- return;
2846
+ await this._updateNode(leaf);
2847
+ return leaf;
2969
2848
  } else if (this.comparator.isLower(value, nValue)) {
2970
- node.values.splice(i, 0, value);
2971
- node.keys.splice(i, 0, [key]);
2972
- await this._updateNode(node);
2973
- return;
2974
- } else if (i + 1 === node.values.length) {
2975
- node.values.push(value);
2976
- node.keys.push([key]);
2977
- await this._updateNode(node);
2978
- return;
2849
+ leaf.values.splice(i, 0, value);
2850
+ leaf.keys.splice(i, 0, [key]);
2851
+ await this._updateNode(leaf);
2852
+ return leaf;
2853
+ } else if (i + 1 === leaf.values.length) {
2854
+ leaf.values.push(value);
2855
+ leaf.keys.push([key]);
2856
+ await this._updateNode(leaf);
2857
+ return leaf;
2979
2858
  }
2980
2859
  }
2981
2860
  } else {
2982
- node.values = [value];
2983
- node.keys = [[key]];
2984
- await this._updateNode(node);
2985
- return;
2861
+ leaf.values = [value];
2862
+ leaf.keys = [[key]];
2863
+ await this._updateNode(leaf);
2864
+ return leaf;
2986
2865
  }
2866
+ return leaf;
2987
2867
  }
2988
2868
  async _insertInParent(node, value, pointer) {
2869
+ node = this._cloneNode(node);
2870
+ pointer = this._cloneNode(pointer);
2989
2871
  if (this.rootId === node.id) {
2990
2872
  const root = await this._createNode(false, [node.id, pointer.id], [value]);
2991
2873
  this.rootId = root.id;
@@ -3004,7 +2886,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3004
2886
  await this._updateNode(pointer);
3005
2887
  return;
3006
2888
  }
3007
- const parentNode = await this.getNode(node.parent);
2889
+ const parentNode = this._cloneNode(await this.getNode(node.parent));
3008
2890
  const nodeIndex = parentNode.keys.indexOf(node.id);
3009
2891
  if (nodeIndex === -1) {
3010
2892
  throw new Error(`Node ${node.id} not found in parent ${parentNode.id}`);
@@ -3020,7 +2902,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3020
2902
  leftSibling.next = pointer.id;
3021
2903
  await this._updateNode(leftSibling);
3022
2904
  if (oldNextId) {
3023
- const oldNext = await this.getNode(oldNextId);
2905
+ const oldNext = this._cloneNode(await this.getNode(oldNextId));
3024
2906
  oldNext.prev = pointer.id;
3025
2907
  await this._updateNode(oldNext);
3026
2908
  }
@@ -3037,12 +2919,12 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3037
2919
  parentNode.values = parentNode.values.slice(0, mid);
3038
2920
  parentNode.keys = parentNode.keys.slice(0, mid + 1);
3039
2921
  for (const k of parentNode.keys) {
3040
- const n = await this.getNode(k);
2922
+ const n = this._cloneNode(await this.getNode(k));
3041
2923
  n.parent = parentNode.id;
3042
2924
  await this._updateNode(n);
3043
2925
  }
3044
2926
  for (const k of parentPointer.keys) {
3045
- const n = await this.getNode(k);
2927
+ const n = this._cloneNode(await this.getNode(k));
3046
2928
  n.parent = parentPointer.id;
3047
2929
  await this._updateNode(n);
3048
2930
  }
@@ -3236,21 +3118,6 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3236
3118
  }
3237
3119
  return false;
3238
3120
  }
3239
- async forceUpdate(id) {
3240
- if (id) {
3241
- this.nodes.delete(id);
3242
- await this.getNode(id);
3243
- return 1;
3244
- }
3245
- const keys = Array.from(this.nodes.keys());
3246
- for (const key of keys) {
3247
- this.nodes.delete(key);
3248
- }
3249
- for (const key of keys) {
3250
- await this.getNode(key);
3251
- }
3252
- return keys.length;
3253
- }
3254
3121
  async get(key) {
3255
3122
  let node = await this.leftestNode();
3256
3123
  while (true) {
@@ -3337,10 +3204,10 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3337
3204
  }
3338
3205
  async insert(key, value) {
3339
3206
  return this.writeLock(0, async () => {
3340
- const before = await this.insertableNode(value);
3341
- await this._insertAtLeaf(before, key, value);
3207
+ let before = await this.insertableNode(value);
3208
+ before = await this._insertAtLeaf(before, key, value);
3342
3209
  if (before.values.length === this.order) {
3343
- const after = await this._createNode(
3210
+ let after = await this._createNode(
3344
3211
  true,
3345
3212
  [],
3346
3213
  [],
@@ -3349,15 +3216,19 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3349
3216
  null
3350
3217
  );
3351
3218
  const mid = Math.ceil(this.order / 2) - 1;
3219
+ after = this._cloneNode(after);
3352
3220
  after.values = before.values.slice(mid + 1);
3353
3221
  after.keys = before.keys.slice(mid + 1);
3354
3222
  before.values = before.values.slice(0, mid + 1);
3355
3223
  before.keys = before.keys.slice(0, mid + 1);
3224
+ await this._updateNode(before);
3225
+ await this._updateNode(after);
3356
3226
  await this._insertInParent(before, after.values[0], after);
3357
3227
  }
3358
3228
  });
3359
3229
  }
3360
3230
  async _deleteEntry(node, key) {
3231
+ node = this._cloneNode(node);
3361
3232
  if (!node.leaf) {
3362
3233
  let keyIndex = -1;
3363
3234
  for (let i = 0, len = node.keys.length; i < len; i++) {
@@ -3376,7 +3247,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3376
3247
  if (this.rootId === node.id && node.keys.length === 1 && !node.leaf) {
3377
3248
  const keys = node.keys;
3378
3249
  this._deleteNode(node);
3379
- const newRoot = await this.getNode(keys[0]);
3250
+ const newRoot = this._cloneNode(await this.getNode(keys[0]));
3380
3251
  newRoot.parent = null;
3381
3252
  await this._updateNode(newRoot);
3382
3253
  await this._writeHead({
@@ -3384,14 +3255,17 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3384
3255
  order: this.order,
3385
3256
  data: this.strategy.head.data
3386
3257
  });
3387
- return;
3258
+ return node;
3388
3259
  } else if (this.rootId === node.id) {
3389
- const root = await this.getNode(this.rootId);
3390
- await this._updateNode(root);
3391
- return;
3260
+ await this._writeHead({
3261
+ root: node.id,
3262
+ order: this.order,
3263
+ data: this.strategy.head.data
3264
+ });
3265
+ return node;
3392
3266
  } else if (node.keys.length < Math.ceil(this.order / 2) && !node.leaf || node.values.length < Math.ceil((this.order - 1) / 2) && node.leaf) {
3393
3267
  if (node.parent === null) {
3394
- return;
3268
+ return node;
3395
3269
  }
3396
3270
  let isPredecessor = false;
3397
3271
  let parentNode = await this.getNode(node.parent);
@@ -3403,11 +3277,11 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3403
3277
  const nKey = parentNode.keys[i];
3404
3278
  if (nKey === node.id) {
3405
3279
  if (i > 0) {
3406
- prevNode = await this.getNode(parentNode.keys[i - 1]);
3280
+ prevNode = this._cloneNode(await this.getNode(parentNode.keys[i - 1]));
3407
3281
  prevValue = parentNode.values[i - 1];
3408
3282
  }
3409
3283
  if (i < parentNode.keys.length - 1) {
3410
- nextNode = await this.getNode(parentNode.keys[i + 1]);
3284
+ nextNode = this._cloneNode(await this.getNode(parentNode.keys[i + 1]));
3411
3285
  postValue = parentNode.values[i];
3412
3286
  }
3413
3287
  }
@@ -3432,7 +3306,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3432
3306
  }
3433
3307
  }
3434
3308
  if (!pointer) {
3435
- return;
3309
+ return node;
3436
3310
  }
3437
3311
  if (node.values.length + pointer.values.length < this.order) {
3438
3312
  if (!isPredecessor) {
@@ -3446,7 +3320,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3446
3320
  } else {
3447
3321
  pointer.next = node.next;
3448
3322
  if (pointer.next) {
3449
- const n = await this.getNode(pointer.next);
3323
+ const n = this._cloneNode(await this.getNode(pointer.next));
3450
3324
  n.prev = pointer.id;
3451
3325
  await this._updateNode(n);
3452
3326
  }
@@ -3455,14 +3329,14 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3455
3329
  if (!pointer.leaf) {
3456
3330
  const keys = pointer.keys;
3457
3331
  for (const key2 of keys) {
3458
- const node2 = await this.getNode(key2);
3332
+ const node2 = this._cloneNode(await this.getNode(key2));
3459
3333
  node2.parent = pointer.id;
3460
3334
  await this._updateNode(node2);
3461
3335
  }
3462
3336
  }
3463
3337
  this._deleteNode(node);
3464
3338
  await this._updateNode(pointer);
3465
- await this._deleteEntry(await this.getNode(node.parent), node.id);
3339
+ await this._deleteEntry(this._cloneNode(await this.getNode(node.parent)), node.id);
3466
3340
  } else {
3467
3341
  if (isPredecessor) {
3468
3342
  let pointerPm;
@@ -3472,7 +3346,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3472
3346
  pointerKm = pointer.values.splice(-1)[0];
3473
3347
  node.keys = [pointerPm, ...node.keys];
3474
3348
  node.values = [guess, ...node.values];
3475
- parentNode = await this.getNode(node.parent);
3349
+ parentNode = this._cloneNode(await this.getNode(node.parent));
3476
3350
  const nodeIndex = parentNode.keys.indexOf(node.id);
3477
3351
  if (nodeIndex > 0) {
3478
3352
  parentNode.values[nodeIndex - 1] = pointerKm;
@@ -3483,7 +3357,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3483
3357
  pointerKm = pointer.values.splice(-1)[0];
3484
3358
  node.keys = [pointerPm, ...node.keys];
3485
3359
  node.values = [pointerKm, ...node.values];
3486
- parentNode = await this.getNode(node.parent);
3360
+ parentNode = this._cloneNode(await this.getNode(node.parent));
3487
3361
  const nodeIndex = parentNode.keys.indexOf(node.id);
3488
3362
  if (nodeIndex > 0) {
3489
3363
  parentNode.values[nodeIndex - 1] = pointerKm;
@@ -3500,7 +3374,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3500
3374
  pointerK0 = pointer.values.splice(0, 1)[0];
3501
3375
  node.keys = [...node.keys, pointerP0];
3502
3376
  node.values = [...node.values, guess];
3503
- parentNode = await this.getNode(node.parent);
3377
+ parentNode = this._cloneNode(await this.getNode(node.parent));
3504
3378
  const pointerIndex = parentNode.keys.indexOf(pointer.id);
3505
3379
  if (pointerIndex > 0) {
3506
3380
  parentNode.values[pointerIndex - 1] = pointerK0;
@@ -3511,7 +3385,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3511
3385
  pointerK0 = pointer.values.splice(0, 1)[0];
3512
3386
  node.keys = [...node.keys, pointerP0];
3513
3387
  node.values = [...node.values, pointerK0];
3514
- parentNode = await this.getNode(node.parent);
3388
+ parentNode = this._cloneNode(await this.getNode(node.parent));
3515
3389
  const pointerIndex = parentNode.keys.indexOf(pointer.id);
3516
3390
  if (pointerIndex > 0) {
3517
3391
  parentNode.values[pointerIndex - 1] = pointer.values[0];
@@ -3523,21 +3397,21 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3523
3397
  }
3524
3398
  if (!pointer.leaf) {
3525
3399
  for (const key2 of pointer.keys) {
3526
- const n = await this.getNode(key2);
3400
+ const n = this._cloneNode(await this.getNode(key2));
3527
3401
  n.parent = pointer.id;
3528
3402
  await this._updateNode(n);
3529
3403
  }
3530
3404
  }
3531
3405
  if (!node.leaf) {
3532
3406
  for (const key2 of node.keys) {
3533
- const n = await this.getNode(key2);
3407
+ const n = this._cloneNode(await this.getNode(key2));
3534
3408
  n.parent = node.id;
3535
3409
  await this._updateNode(n);
3536
3410
  }
3537
3411
  }
3538
3412
  if (!parentNode.leaf) {
3539
3413
  for (const key2 of parentNode.keys) {
3540
- const n = await this.getNode(key2);
3414
+ const n = this._cloneNode(await this.getNode(key2));
3541
3415
  n.parent = parentNode.id;
3542
3416
  await this._updateNode(n);
3543
3417
  }
@@ -3546,11 +3420,14 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3546
3420
  } else {
3547
3421
  await this._updateNode(node);
3548
3422
  }
3423
+ await this._updateNode(node);
3424
+ return node;
3549
3425
  }
3550
3426
  async delete(key, value) {
3551
3427
  return this.writeLock(0, async () => {
3552
3428
  let node = await this.insertableNodeByPrimary(value);
3553
3429
  let found = false;
3430
+ node = this._cloneNode(node);
3554
3431
  while (true) {
3555
3432
  let i = node.values.length;
3556
3433
  while (i--) {
@@ -3565,7 +3442,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3565
3442
  node.values.splice(i, 1);
3566
3443
  }
3567
3444
  await this._updateNode(node);
3568
- await this._deleteEntry(node, key);
3445
+ node = await this._deleteEntry(node, key);
3569
3446
  found = true;
3570
3447
  break;
3571
3448
  }
@@ -3608,21 +3485,10 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
3608
3485
  this.rootTx.rootId = this.rootId;
3609
3486
  }
3610
3487
  }
3611
- if (result.success) {
3612
- for (const r of result.created) {
3613
- this.nodes.set(r.key, r.data);
3614
- }
3615
- for (const r of result.updated) {
3616
- this.nodes.set(r.key, r.data);
3617
- }
3618
- for (const r of result.deleted) {
3619
- this.nodes.delete(r.key);
3620
- }
3621
- }
3622
3488
  }
3623
3489
  return result;
3624
3490
  }
3625
- rollback() {
3491
+ async rollback() {
3626
3492
  return this.mvcc.rollback();
3627
3493
  }
3628
3494
  };
@@ -3665,7 +3531,9 @@ var BPTreeMVCCStrategyAsync = class extends AsyncMVCCStrategy {
3665
3531
  // src/BPTreeAsync.ts
3666
3532
  var BPTreeAsync = class extends BPTreeAsyncTransaction {
3667
3533
  constructor(strategy, comparator, option) {
3668
- const mvccRoot = new AsyncMVCCTransaction(new BPTreeMVCCStrategyAsync(strategy));
3534
+ const mvccRoot = new AsyncMVCCTransaction(new BPTreeMVCCStrategyAsync(strategy), {
3535
+ cacheCapacity: option?.capacity ?? void 0
3536
+ });
3669
3537
  super(
3670
3538
  null,
3671
3539
  mvccRoot,