mvcc-api 1.2.10 → 1.3.0
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.
package/dist/cjs/index.cjs
CHANGED
|
@@ -163,6 +163,47 @@ var MVCCTransaction = class {
|
|
|
163
163
|
}
|
|
164
164
|
return { success: true, created, updated, deleted };
|
|
165
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* Cleans up both deletedCache and versionIndex based on minActiveVersion.
|
|
168
|
+
* Root transactions call this after commit to reclaim memory.
|
|
169
|
+
*/
|
|
170
|
+
_cleanupDeletedCache() {
|
|
171
|
+
if (this.deletedCache.size === 0 && this.versionIndex.size === 0) return;
|
|
172
|
+
let minActiveVersion = this.version;
|
|
173
|
+
if (this.activeTransactions.size > 0) {
|
|
174
|
+
for (const tx of this.activeTransactions) {
|
|
175
|
+
if (!tx.committed && tx.snapshotVersion < minActiveVersion) {
|
|
176
|
+
minActiveVersion = tx.snapshotVersion;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (this.deletedCache.size > 0) {
|
|
181
|
+
for (const [key, cachedList] of this.deletedCache) {
|
|
182
|
+
const remaining = cachedList.filter((item) => item.deletedAtVersion > minActiveVersion);
|
|
183
|
+
if (remaining.length === 0) {
|
|
184
|
+
this.deletedCache.delete(key);
|
|
185
|
+
} else {
|
|
186
|
+
this.deletedCache.set(key, remaining);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (this.versionIndex.size > 0) {
|
|
191
|
+
for (const [key, versions] of this.versionIndex) {
|
|
192
|
+
let latestInSnapshotIdx = -1;
|
|
193
|
+
for (let i = versions.length - 1; i >= 0; i--) {
|
|
194
|
+
if (versions[i].version <= minActiveVersion) {
|
|
195
|
+
latestInSnapshotIdx = i;
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (latestInSnapshotIdx === versions.length - 1) {
|
|
200
|
+
this.versionIndex.delete(key);
|
|
201
|
+
} else if (latestInSnapshotIdx > 0) {
|
|
202
|
+
versions.splice(0, latestInSnapshotIdx);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
166
207
|
};
|
|
167
208
|
|
|
168
209
|
// src/core/sync/Strategy.ts
|
|
@@ -226,6 +267,25 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
226
267
|
if (this.writeBuffer.has(key)) return true;
|
|
227
268
|
return this.root._diskExists(key, this.snapshotVersion);
|
|
228
269
|
}
|
|
270
|
+
_existsSnapshot(key, snapshotVersion, snapshotLocalVersion) {
|
|
271
|
+
if (this.writeBuffer.has(key)) {
|
|
272
|
+
const keyModVersion = this.keyVersions.get(key);
|
|
273
|
+
if (snapshotLocalVersion === void 0 || keyModVersion === void 0 || keyModVersion <= snapshotLocalVersion) {
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (this.deleteBuffer.has(key)) {
|
|
278
|
+
const keyModVersion = this.keyVersions.get(key);
|
|
279
|
+
if (snapshotLocalVersion === void 0 || keyModVersion === void 0 || keyModVersion <= snapshotLocalVersion) {
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
if (this.parent) {
|
|
284
|
+
return this.parent._existsSnapshot(key, snapshotVersion, this.snapshotLocalVersion);
|
|
285
|
+
} else {
|
|
286
|
+
return this._diskExists(key, snapshotVersion);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
229
289
|
_readSnapshot(key, snapshotVersion, snapshotLocalVersion) {
|
|
230
290
|
if (this.writeBuffer.has(key)) {
|
|
231
291
|
const keyModVersion = this.keyVersions.get(key);
|
|
@@ -368,7 +428,6 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
368
428
|
this.localVersion = newLocalVersion;
|
|
369
429
|
this.root.activeTransactions.delete(child);
|
|
370
430
|
} else {
|
|
371
|
-
const newVersion = this.version + 1;
|
|
372
431
|
if (child !== this) {
|
|
373
432
|
const modifiedKeys = /* @__PURE__ */ new Set([...child.writeBuffer.keys(), ...child.deleteBuffer]);
|
|
374
433
|
for (const key of modifiedKeys) {
|
|
@@ -387,35 +446,70 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
387
446
|
}
|
|
388
447
|
}
|
|
389
448
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
449
|
+
const newVersion = this.version + 1;
|
|
450
|
+
for (const [key, value] of child.writeBuffer) {
|
|
451
|
+
if (this.writeBuffer.has(key)) {
|
|
452
|
+
if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
|
|
453
|
+
this.deletedCache.get(key).push({
|
|
454
|
+
value: this.writeBuffer.get(key),
|
|
455
|
+
deletedAtVersion: newVersion
|
|
456
|
+
});
|
|
457
|
+
} else if (this.strategy.exists(key)) {
|
|
458
|
+
if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
|
|
459
|
+
this.deletedCache.get(key).push({
|
|
460
|
+
value: this.strategy.read(key),
|
|
461
|
+
deletedAtVersion: newVersion
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
this.writeBuffer.set(key, value);
|
|
465
|
+
this.deleteBuffer.delete(key);
|
|
466
|
+
if (child.createdKeys.has(key)) {
|
|
467
|
+
this.createdKeys.add(key);
|
|
468
|
+
}
|
|
469
|
+
if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
|
|
470
|
+
this.versionIndex.get(key).push({ version: newVersion, exists: true });
|
|
396
471
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
this.
|
|
472
|
+
for (const key of child.deleteBuffer) {
|
|
473
|
+
if (this.writeBuffer.has(key)) {
|
|
474
|
+
if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
|
|
475
|
+
this.deletedCache.get(key).push({
|
|
476
|
+
value: this.writeBuffer.get(key),
|
|
477
|
+
deletedAtVersion: newVersion
|
|
478
|
+
});
|
|
479
|
+
} else if (this.strategy.exists(key)) {
|
|
480
|
+
if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
|
|
481
|
+
this.deletedCache.get(key).push({
|
|
482
|
+
value: this.strategy.read(key),
|
|
483
|
+
deletedAtVersion: newVersion
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
this.deleteBuffer.add(key);
|
|
487
|
+
this.writeBuffer.delete(key);
|
|
488
|
+
this.createdKeys.delete(key);
|
|
489
|
+
const deletedValue = child.deletedValues.get(key);
|
|
490
|
+
if (deletedValue !== void 0) {
|
|
491
|
+
this.deletedValues.set(key, deletedValue);
|
|
492
|
+
}
|
|
493
|
+
if (child.originallyExisted.has(key)) {
|
|
494
|
+
this.originallyExisted.add(key);
|
|
495
|
+
}
|
|
496
|
+
if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
|
|
497
|
+
this.versionIndex.get(key).push({ version: newVersion, exists: false });
|
|
405
498
|
}
|
|
406
|
-
|
|
407
|
-
|
|
499
|
+
this.version = newVersion;
|
|
500
|
+
this.root.activeTransactions.delete(child);
|
|
501
|
+
this._cleanupDeletedCache();
|
|
502
|
+
} else {
|
|
503
|
+
const newVersion = this.version + 1;
|
|
504
|
+
for (const [key, value] of this.writeBuffer) {
|
|
505
|
+
this._diskWrite(key, value, newVersion);
|
|
408
506
|
}
|
|
507
|
+
for (const key of this.deleteBuffer) {
|
|
508
|
+
this._diskDelete(key, newVersion);
|
|
509
|
+
}
|
|
510
|
+
this.version = newVersion;
|
|
511
|
+
this._cleanupDeletedCache();
|
|
409
512
|
}
|
|
410
|
-
for (const [key, value] of child.writeBuffer) {
|
|
411
|
-
this._diskWrite(key, value, newVersion);
|
|
412
|
-
}
|
|
413
|
-
for (const key of child.deleteBuffer) {
|
|
414
|
-
this._diskDelete(key, newVersion);
|
|
415
|
-
}
|
|
416
|
-
this.version = newVersion;
|
|
417
|
-
this.root.activeTransactions.delete(child);
|
|
418
|
-
this._cleanupDeletedCache();
|
|
419
513
|
}
|
|
420
514
|
return null;
|
|
421
515
|
}
|
|
@@ -440,6 +534,8 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
440
534
|
if (!strategy) throw new Error("Root Transaction missing strategy");
|
|
441
535
|
const versions = this.versionIndex.get(key);
|
|
442
536
|
if (!versions) {
|
|
537
|
+
if (this.writeBuffer.has(key)) return this.writeBuffer.get(key);
|
|
538
|
+
if (this.deleteBuffer.has(key)) return null;
|
|
443
539
|
return strategy.exists(key) ? strategy.read(key) : null;
|
|
444
540
|
}
|
|
445
541
|
let targetVerObj = null;
|
|
@@ -460,10 +556,11 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
460
556
|
if (match) return match.value;
|
|
461
557
|
}
|
|
462
558
|
}
|
|
463
|
-
return null;
|
|
559
|
+
return strategy.exists(key) ? strategy.read(key) : null;
|
|
464
560
|
}
|
|
465
561
|
if (!targetVerObj.exists) return null;
|
|
466
562
|
if (!nextVerObj) {
|
|
563
|
+
if (this.writeBuffer.has(key)) return this.writeBuffer.get(key);
|
|
467
564
|
return strategy.read(key);
|
|
468
565
|
}
|
|
469
566
|
const cached = this.deletedCache.get(key);
|
|
@@ -478,6 +575,8 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
478
575
|
if (!strategy) throw new Error("Root Transaction missing strategy");
|
|
479
576
|
const versions = this.versionIndex.get(key);
|
|
480
577
|
if (!versions) {
|
|
578
|
+
if (this.writeBuffer.has(key)) return true;
|
|
579
|
+
if (this.deleteBuffer.has(key)) return false;
|
|
481
580
|
return strategy.exists(key);
|
|
482
581
|
}
|
|
483
582
|
let targetVerObj = null;
|
|
@@ -501,30 +600,11 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
501
600
|
value: currentVal,
|
|
502
601
|
deletedAtVersion: snapshotVersion
|
|
503
602
|
});
|
|
603
|
+
strategy.delete(key);
|
|
504
604
|
}
|
|
505
|
-
strategy.delete(key);
|
|
506
605
|
if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
|
|
507
606
|
this.versionIndex.get(key).push({ version: snapshotVersion, exists: false });
|
|
508
607
|
}
|
|
509
|
-
_cleanupDeletedCache() {
|
|
510
|
-
if (this.deletedCache.size === 0) return;
|
|
511
|
-
let minActiveVersion = this.version;
|
|
512
|
-
if (this.activeTransactions.size > 0) {
|
|
513
|
-
for (const tx of this.activeTransactions) {
|
|
514
|
-
if (!tx.committed && tx.snapshotVersion < minActiveVersion) {
|
|
515
|
-
minActiveVersion = tx.snapshotVersion;
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
for (const [key, cachedList] of this.deletedCache) {
|
|
520
|
-
const remaining = cachedList.filter((item) => item.deletedAtVersion > minActiveVersion);
|
|
521
|
-
if (remaining.length === 0) {
|
|
522
|
-
this.deletedCache.delete(key);
|
|
523
|
-
} else {
|
|
524
|
-
this.deletedCache.set(key, remaining);
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
608
|
};
|
|
529
609
|
|
|
530
610
|
// src/core/async/Strategy.ts
|
|
@@ -856,6 +936,25 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
856
936
|
if (this.writeBuffer.has(key)) return true;
|
|
857
937
|
return this.root._diskExists(key, this.snapshotVersion);
|
|
858
938
|
}
|
|
939
|
+
async _existsSnapshot(key, snapshotVersion, snapshotLocalVersion) {
|
|
940
|
+
if (this.writeBuffer.has(key)) {
|
|
941
|
+
const keyModVersion = this.keyVersions.get(key);
|
|
942
|
+
if (snapshotLocalVersion === void 0 || keyModVersion === void 0 || keyModVersion <= snapshotLocalVersion) {
|
|
943
|
+
return true;
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
if (this.deleteBuffer.has(key)) {
|
|
947
|
+
const keyModVersion = this.keyVersions.get(key);
|
|
948
|
+
if (snapshotLocalVersion === void 0 || keyModVersion === void 0 || keyModVersion <= snapshotLocalVersion) {
|
|
949
|
+
return false;
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
if (this.parent) {
|
|
953
|
+
return this.parent._existsSnapshot(key, snapshotVersion, this.snapshotLocalVersion);
|
|
954
|
+
} else {
|
|
955
|
+
return this._diskExists(key, snapshotVersion);
|
|
956
|
+
}
|
|
957
|
+
}
|
|
859
958
|
async _readSnapshot(key, snapshotVersion, snapshotLocalVersion) {
|
|
860
959
|
if (this.writeBuffer.has(key)) {
|
|
861
960
|
const keyModVersion = this.keyVersions.get(key);
|
|
@@ -1000,7 +1099,6 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
1000
1099
|
this.root.activeTransactions.delete(child);
|
|
1001
1100
|
return null;
|
|
1002
1101
|
} else {
|
|
1003
|
-
const newVersion = this.version + 1;
|
|
1004
1102
|
if (child !== this) {
|
|
1005
1103
|
const modifiedKeys = /* @__PURE__ */ new Set([...child.writeBuffer.keys(), ...child.deleteBuffer]);
|
|
1006
1104
|
for (const key of modifiedKeys) {
|
|
@@ -1019,35 +1117,70 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
1019
1117
|
}
|
|
1020
1118
|
}
|
|
1021
1119
|
}
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1120
|
+
const newVersion = this.version + 1;
|
|
1121
|
+
for (const [key, value] of child.writeBuffer) {
|
|
1122
|
+
if (this.writeBuffer.has(key)) {
|
|
1123
|
+
if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
|
|
1124
|
+
this.deletedCache.get(key).push({
|
|
1125
|
+
value: this.writeBuffer.get(key),
|
|
1126
|
+
deletedAtVersion: newVersion
|
|
1127
|
+
});
|
|
1128
|
+
} else if (await this.strategy.exists(key)) {
|
|
1129
|
+
if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
|
|
1130
|
+
this.deletedCache.get(key).push({
|
|
1131
|
+
value: await this.strategy.read(key),
|
|
1132
|
+
deletedAtVersion: newVersion
|
|
1133
|
+
});
|
|
1134
|
+
}
|
|
1135
|
+
this.writeBuffer.set(key, value);
|
|
1136
|
+
this.deleteBuffer.delete(key);
|
|
1137
|
+
if (child.createdKeys.has(key)) {
|
|
1138
|
+
this.createdKeys.add(key);
|
|
1139
|
+
}
|
|
1140
|
+
if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
|
|
1141
|
+
this.versionIndex.get(key).push({ version: newVersion, exists: true });
|
|
1028
1142
|
}
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
this.
|
|
1143
|
+
for (const key of child.deleteBuffer) {
|
|
1144
|
+
if (this.writeBuffer.has(key)) {
|
|
1145
|
+
if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
|
|
1146
|
+
this.deletedCache.get(key).push({
|
|
1147
|
+
value: this.writeBuffer.get(key),
|
|
1148
|
+
deletedAtVersion: newVersion
|
|
1149
|
+
});
|
|
1150
|
+
} else if (await this.strategy.exists(key)) {
|
|
1151
|
+
if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
|
|
1152
|
+
this.deletedCache.get(key).push({
|
|
1153
|
+
value: await this.strategy.read(key),
|
|
1154
|
+
deletedAtVersion: newVersion
|
|
1155
|
+
});
|
|
1156
|
+
}
|
|
1157
|
+
this.deleteBuffer.add(key);
|
|
1158
|
+
this.writeBuffer.delete(key);
|
|
1159
|
+
this.createdKeys.delete(key);
|
|
1160
|
+
const deletedValue = child.deletedValues.get(key);
|
|
1161
|
+
if (deletedValue !== void 0) {
|
|
1162
|
+
this.deletedValues.set(key, deletedValue);
|
|
1163
|
+
}
|
|
1164
|
+
if (child.originallyExisted.has(key)) {
|
|
1165
|
+
this.originallyExisted.add(key);
|
|
1166
|
+
}
|
|
1167
|
+
if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
|
|
1168
|
+
this.versionIndex.get(key).push({ version: newVersion, exists: false });
|
|
1037
1169
|
}
|
|
1038
|
-
|
|
1039
|
-
|
|
1170
|
+
this.version = newVersion;
|
|
1171
|
+
this.root.activeTransactions.delete(child);
|
|
1172
|
+
this._cleanupDeletedCache();
|
|
1173
|
+
} else {
|
|
1174
|
+
const newVersion = this.version + 1;
|
|
1175
|
+
for (const [key, value] of this.writeBuffer) {
|
|
1176
|
+
await this._diskWrite(key, value, newVersion);
|
|
1040
1177
|
}
|
|
1178
|
+
for (const key of this.deleteBuffer) {
|
|
1179
|
+
await this._diskDelete(key, newVersion);
|
|
1180
|
+
}
|
|
1181
|
+
this.version = newVersion;
|
|
1182
|
+
this._cleanupDeletedCache();
|
|
1041
1183
|
}
|
|
1042
|
-
for (const [key, value] of child.writeBuffer) {
|
|
1043
|
-
await this._diskWrite(key, value, newVersion);
|
|
1044
|
-
}
|
|
1045
|
-
for (const key of child.deleteBuffer) {
|
|
1046
|
-
await this._diskDelete(key, newVersion);
|
|
1047
|
-
}
|
|
1048
|
-
this.version = newVersion;
|
|
1049
|
-
this.root.activeTransactions.delete(child);
|
|
1050
|
-
this._cleanupDeletedCache();
|
|
1051
1184
|
return null;
|
|
1052
1185
|
}
|
|
1053
1186
|
});
|
|
@@ -1073,6 +1206,8 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
1073
1206
|
if (!strategy) throw new Error("Root Transaction missing strategy");
|
|
1074
1207
|
const versions = this.versionIndex.get(key);
|
|
1075
1208
|
if (!versions) {
|
|
1209
|
+
if (this.writeBuffer.has(key)) return this.writeBuffer.get(key);
|
|
1210
|
+
if (this.deleteBuffer.has(key)) return null;
|
|
1076
1211
|
return await strategy.exists(key) ? strategy.read(key) : null;
|
|
1077
1212
|
}
|
|
1078
1213
|
let targetVerObj = null;
|
|
@@ -1093,10 +1228,11 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
1093
1228
|
if (match) return match.value;
|
|
1094
1229
|
}
|
|
1095
1230
|
}
|
|
1096
|
-
return null;
|
|
1231
|
+
return await strategy.exists(key) ? strategy.read(key) : null;
|
|
1097
1232
|
}
|
|
1098
1233
|
if (!targetVerObj.exists) return null;
|
|
1099
1234
|
if (!nextVerObj) {
|
|
1235
|
+
if (this.writeBuffer.has(key)) return this.writeBuffer.get(key);
|
|
1100
1236
|
return strategy.read(key);
|
|
1101
1237
|
}
|
|
1102
1238
|
const cached = this.deletedCache.get(key);
|
|
@@ -1111,6 +1247,8 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
1111
1247
|
if (!strategy) throw new Error("Root Transaction missing strategy");
|
|
1112
1248
|
const versions = this.versionIndex.get(key);
|
|
1113
1249
|
if (!versions) {
|
|
1250
|
+
if (this.writeBuffer.has(key)) return true;
|
|
1251
|
+
if (this.deleteBuffer.has(key)) return false;
|
|
1114
1252
|
return strategy.exists(key);
|
|
1115
1253
|
}
|
|
1116
1254
|
let targetVerObj = null;
|
|
@@ -1134,28 +1272,9 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
1134
1272
|
value: currentVal,
|
|
1135
1273
|
deletedAtVersion: snapshotVersion
|
|
1136
1274
|
});
|
|
1275
|
+
await strategy.delete(key);
|
|
1137
1276
|
}
|
|
1138
|
-
await strategy.delete(key);
|
|
1139
1277
|
if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
|
|
1140
1278
|
this.versionIndex.get(key).push({ version: snapshotVersion, exists: false });
|
|
1141
1279
|
}
|
|
1142
|
-
_cleanupDeletedCache() {
|
|
1143
|
-
if (this.deletedCache.size === 0) return;
|
|
1144
|
-
let minActiveVersion = this.version;
|
|
1145
|
-
if (this.activeTransactions.size > 0) {
|
|
1146
|
-
for (const tx of this.activeTransactions) {
|
|
1147
|
-
if (!tx.committed && tx.snapshotVersion < minActiveVersion) {
|
|
1148
|
-
minActiveVersion = tx.snapshotVersion;
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1152
|
-
for (const [key, cachedList] of this.deletedCache) {
|
|
1153
|
-
const remaining = cachedList.filter((item) => item.deletedAtVersion > minActiveVersion);
|
|
1154
|
-
if (remaining.length === 0) {
|
|
1155
|
-
this.deletedCache.delete(key);
|
|
1156
|
-
} else {
|
|
1157
|
-
this.deletedCache.set(key, remaining);
|
|
1158
|
-
}
|
|
1159
|
-
}
|
|
1160
|
-
}
|
|
1161
1280
|
};
|
package/dist/esm/index.mjs
CHANGED
|
@@ -132,6 +132,47 @@ var MVCCTransaction = class {
|
|
|
132
132
|
}
|
|
133
133
|
return { success: true, created, updated, deleted };
|
|
134
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Cleans up both deletedCache and versionIndex based on minActiveVersion.
|
|
137
|
+
* Root transactions call this after commit to reclaim memory.
|
|
138
|
+
*/
|
|
139
|
+
_cleanupDeletedCache() {
|
|
140
|
+
if (this.deletedCache.size === 0 && this.versionIndex.size === 0) return;
|
|
141
|
+
let minActiveVersion = this.version;
|
|
142
|
+
if (this.activeTransactions.size > 0) {
|
|
143
|
+
for (const tx of this.activeTransactions) {
|
|
144
|
+
if (!tx.committed && tx.snapshotVersion < minActiveVersion) {
|
|
145
|
+
minActiveVersion = tx.snapshotVersion;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (this.deletedCache.size > 0) {
|
|
150
|
+
for (const [key, cachedList] of this.deletedCache) {
|
|
151
|
+
const remaining = cachedList.filter((item) => item.deletedAtVersion > minActiveVersion);
|
|
152
|
+
if (remaining.length === 0) {
|
|
153
|
+
this.deletedCache.delete(key);
|
|
154
|
+
} else {
|
|
155
|
+
this.deletedCache.set(key, remaining);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (this.versionIndex.size > 0) {
|
|
160
|
+
for (const [key, versions] of this.versionIndex) {
|
|
161
|
+
let latestInSnapshotIdx = -1;
|
|
162
|
+
for (let i = versions.length - 1; i >= 0; i--) {
|
|
163
|
+
if (versions[i].version <= minActiveVersion) {
|
|
164
|
+
latestInSnapshotIdx = i;
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (latestInSnapshotIdx === versions.length - 1) {
|
|
169
|
+
this.versionIndex.delete(key);
|
|
170
|
+
} else if (latestInSnapshotIdx > 0) {
|
|
171
|
+
versions.splice(0, latestInSnapshotIdx);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
135
176
|
};
|
|
136
177
|
|
|
137
178
|
// src/core/sync/Strategy.ts
|
|
@@ -195,6 +236,25 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
195
236
|
if (this.writeBuffer.has(key)) return true;
|
|
196
237
|
return this.root._diskExists(key, this.snapshotVersion);
|
|
197
238
|
}
|
|
239
|
+
_existsSnapshot(key, snapshotVersion, snapshotLocalVersion) {
|
|
240
|
+
if (this.writeBuffer.has(key)) {
|
|
241
|
+
const keyModVersion = this.keyVersions.get(key);
|
|
242
|
+
if (snapshotLocalVersion === void 0 || keyModVersion === void 0 || keyModVersion <= snapshotLocalVersion) {
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (this.deleteBuffer.has(key)) {
|
|
247
|
+
const keyModVersion = this.keyVersions.get(key);
|
|
248
|
+
if (snapshotLocalVersion === void 0 || keyModVersion === void 0 || keyModVersion <= snapshotLocalVersion) {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (this.parent) {
|
|
253
|
+
return this.parent._existsSnapshot(key, snapshotVersion, this.snapshotLocalVersion);
|
|
254
|
+
} else {
|
|
255
|
+
return this._diskExists(key, snapshotVersion);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
198
258
|
_readSnapshot(key, snapshotVersion, snapshotLocalVersion) {
|
|
199
259
|
if (this.writeBuffer.has(key)) {
|
|
200
260
|
const keyModVersion = this.keyVersions.get(key);
|
|
@@ -337,7 +397,6 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
337
397
|
this.localVersion = newLocalVersion;
|
|
338
398
|
this.root.activeTransactions.delete(child);
|
|
339
399
|
} else {
|
|
340
|
-
const newVersion = this.version + 1;
|
|
341
400
|
if (child !== this) {
|
|
342
401
|
const modifiedKeys = /* @__PURE__ */ new Set([...child.writeBuffer.keys(), ...child.deleteBuffer]);
|
|
343
402
|
for (const key of modifiedKeys) {
|
|
@@ -356,35 +415,70 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
356
415
|
}
|
|
357
416
|
}
|
|
358
417
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
418
|
+
const newVersion = this.version + 1;
|
|
419
|
+
for (const [key, value] of child.writeBuffer) {
|
|
420
|
+
if (this.writeBuffer.has(key)) {
|
|
421
|
+
if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
|
|
422
|
+
this.deletedCache.get(key).push({
|
|
423
|
+
value: this.writeBuffer.get(key),
|
|
424
|
+
deletedAtVersion: newVersion
|
|
425
|
+
});
|
|
426
|
+
} else if (this.strategy.exists(key)) {
|
|
427
|
+
if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
|
|
428
|
+
this.deletedCache.get(key).push({
|
|
429
|
+
value: this.strategy.read(key),
|
|
430
|
+
deletedAtVersion: newVersion
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
this.writeBuffer.set(key, value);
|
|
434
|
+
this.deleteBuffer.delete(key);
|
|
435
|
+
if (child.createdKeys.has(key)) {
|
|
436
|
+
this.createdKeys.add(key);
|
|
437
|
+
}
|
|
438
|
+
if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
|
|
439
|
+
this.versionIndex.get(key).push({ version: newVersion, exists: true });
|
|
365
440
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
this.
|
|
441
|
+
for (const key of child.deleteBuffer) {
|
|
442
|
+
if (this.writeBuffer.has(key)) {
|
|
443
|
+
if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
|
|
444
|
+
this.deletedCache.get(key).push({
|
|
445
|
+
value: this.writeBuffer.get(key),
|
|
446
|
+
deletedAtVersion: newVersion
|
|
447
|
+
});
|
|
448
|
+
} else if (this.strategy.exists(key)) {
|
|
449
|
+
if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
|
|
450
|
+
this.deletedCache.get(key).push({
|
|
451
|
+
value: this.strategy.read(key),
|
|
452
|
+
deletedAtVersion: newVersion
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
this.deleteBuffer.add(key);
|
|
456
|
+
this.writeBuffer.delete(key);
|
|
457
|
+
this.createdKeys.delete(key);
|
|
458
|
+
const deletedValue = child.deletedValues.get(key);
|
|
459
|
+
if (deletedValue !== void 0) {
|
|
460
|
+
this.deletedValues.set(key, deletedValue);
|
|
461
|
+
}
|
|
462
|
+
if (child.originallyExisted.has(key)) {
|
|
463
|
+
this.originallyExisted.add(key);
|
|
464
|
+
}
|
|
465
|
+
if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
|
|
466
|
+
this.versionIndex.get(key).push({ version: newVersion, exists: false });
|
|
374
467
|
}
|
|
375
|
-
|
|
376
|
-
|
|
468
|
+
this.version = newVersion;
|
|
469
|
+
this.root.activeTransactions.delete(child);
|
|
470
|
+
this._cleanupDeletedCache();
|
|
471
|
+
} else {
|
|
472
|
+
const newVersion = this.version + 1;
|
|
473
|
+
for (const [key, value] of this.writeBuffer) {
|
|
474
|
+
this._diskWrite(key, value, newVersion);
|
|
377
475
|
}
|
|
476
|
+
for (const key of this.deleteBuffer) {
|
|
477
|
+
this._diskDelete(key, newVersion);
|
|
478
|
+
}
|
|
479
|
+
this.version = newVersion;
|
|
480
|
+
this._cleanupDeletedCache();
|
|
378
481
|
}
|
|
379
|
-
for (const [key, value] of child.writeBuffer) {
|
|
380
|
-
this._diskWrite(key, value, newVersion);
|
|
381
|
-
}
|
|
382
|
-
for (const key of child.deleteBuffer) {
|
|
383
|
-
this._diskDelete(key, newVersion);
|
|
384
|
-
}
|
|
385
|
-
this.version = newVersion;
|
|
386
|
-
this.root.activeTransactions.delete(child);
|
|
387
|
-
this._cleanupDeletedCache();
|
|
388
482
|
}
|
|
389
483
|
return null;
|
|
390
484
|
}
|
|
@@ -409,6 +503,8 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
409
503
|
if (!strategy) throw new Error("Root Transaction missing strategy");
|
|
410
504
|
const versions = this.versionIndex.get(key);
|
|
411
505
|
if (!versions) {
|
|
506
|
+
if (this.writeBuffer.has(key)) return this.writeBuffer.get(key);
|
|
507
|
+
if (this.deleteBuffer.has(key)) return null;
|
|
412
508
|
return strategy.exists(key) ? strategy.read(key) : null;
|
|
413
509
|
}
|
|
414
510
|
let targetVerObj = null;
|
|
@@ -429,10 +525,11 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
429
525
|
if (match) return match.value;
|
|
430
526
|
}
|
|
431
527
|
}
|
|
432
|
-
return null;
|
|
528
|
+
return strategy.exists(key) ? strategy.read(key) : null;
|
|
433
529
|
}
|
|
434
530
|
if (!targetVerObj.exists) return null;
|
|
435
531
|
if (!nextVerObj) {
|
|
532
|
+
if (this.writeBuffer.has(key)) return this.writeBuffer.get(key);
|
|
436
533
|
return strategy.read(key);
|
|
437
534
|
}
|
|
438
535
|
const cached = this.deletedCache.get(key);
|
|
@@ -447,6 +544,8 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
447
544
|
if (!strategy) throw new Error("Root Transaction missing strategy");
|
|
448
545
|
const versions = this.versionIndex.get(key);
|
|
449
546
|
if (!versions) {
|
|
547
|
+
if (this.writeBuffer.has(key)) return true;
|
|
548
|
+
if (this.deleteBuffer.has(key)) return false;
|
|
450
549
|
return strategy.exists(key);
|
|
451
550
|
}
|
|
452
551
|
let targetVerObj = null;
|
|
@@ -470,30 +569,11 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
|
|
|
470
569
|
value: currentVal,
|
|
471
570
|
deletedAtVersion: snapshotVersion
|
|
472
571
|
});
|
|
572
|
+
strategy.delete(key);
|
|
473
573
|
}
|
|
474
|
-
strategy.delete(key);
|
|
475
574
|
if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
|
|
476
575
|
this.versionIndex.get(key).push({ version: snapshotVersion, exists: false });
|
|
477
576
|
}
|
|
478
|
-
_cleanupDeletedCache() {
|
|
479
|
-
if (this.deletedCache.size === 0) return;
|
|
480
|
-
let minActiveVersion = this.version;
|
|
481
|
-
if (this.activeTransactions.size > 0) {
|
|
482
|
-
for (const tx of this.activeTransactions) {
|
|
483
|
-
if (!tx.committed && tx.snapshotVersion < minActiveVersion) {
|
|
484
|
-
minActiveVersion = tx.snapshotVersion;
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
for (const [key, cachedList] of this.deletedCache) {
|
|
489
|
-
const remaining = cachedList.filter((item) => item.deletedAtVersion > minActiveVersion);
|
|
490
|
-
if (remaining.length === 0) {
|
|
491
|
-
this.deletedCache.delete(key);
|
|
492
|
-
} else {
|
|
493
|
-
this.deletedCache.set(key, remaining);
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
577
|
};
|
|
498
578
|
|
|
499
579
|
// src/core/async/Strategy.ts
|
|
@@ -825,6 +905,25 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
825
905
|
if (this.writeBuffer.has(key)) return true;
|
|
826
906
|
return this.root._diskExists(key, this.snapshotVersion);
|
|
827
907
|
}
|
|
908
|
+
async _existsSnapshot(key, snapshotVersion, snapshotLocalVersion) {
|
|
909
|
+
if (this.writeBuffer.has(key)) {
|
|
910
|
+
const keyModVersion = this.keyVersions.get(key);
|
|
911
|
+
if (snapshotLocalVersion === void 0 || keyModVersion === void 0 || keyModVersion <= snapshotLocalVersion) {
|
|
912
|
+
return true;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
if (this.deleteBuffer.has(key)) {
|
|
916
|
+
const keyModVersion = this.keyVersions.get(key);
|
|
917
|
+
if (snapshotLocalVersion === void 0 || keyModVersion === void 0 || keyModVersion <= snapshotLocalVersion) {
|
|
918
|
+
return false;
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
if (this.parent) {
|
|
922
|
+
return this.parent._existsSnapshot(key, snapshotVersion, this.snapshotLocalVersion);
|
|
923
|
+
} else {
|
|
924
|
+
return this._diskExists(key, snapshotVersion);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
828
927
|
async _readSnapshot(key, snapshotVersion, snapshotLocalVersion) {
|
|
829
928
|
if (this.writeBuffer.has(key)) {
|
|
830
929
|
const keyModVersion = this.keyVersions.get(key);
|
|
@@ -969,7 +1068,6 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
969
1068
|
this.root.activeTransactions.delete(child);
|
|
970
1069
|
return null;
|
|
971
1070
|
} else {
|
|
972
|
-
const newVersion = this.version + 1;
|
|
973
1071
|
if (child !== this) {
|
|
974
1072
|
const modifiedKeys = /* @__PURE__ */ new Set([...child.writeBuffer.keys(), ...child.deleteBuffer]);
|
|
975
1073
|
for (const key of modifiedKeys) {
|
|
@@ -988,35 +1086,70 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
988
1086
|
}
|
|
989
1087
|
}
|
|
990
1088
|
}
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
1089
|
+
const newVersion = this.version + 1;
|
|
1090
|
+
for (const [key, value] of child.writeBuffer) {
|
|
1091
|
+
if (this.writeBuffer.has(key)) {
|
|
1092
|
+
if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
|
|
1093
|
+
this.deletedCache.get(key).push({
|
|
1094
|
+
value: this.writeBuffer.get(key),
|
|
1095
|
+
deletedAtVersion: newVersion
|
|
1096
|
+
});
|
|
1097
|
+
} else if (await this.strategy.exists(key)) {
|
|
1098
|
+
if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
|
|
1099
|
+
this.deletedCache.get(key).push({
|
|
1100
|
+
value: await this.strategy.read(key),
|
|
1101
|
+
deletedAtVersion: newVersion
|
|
1102
|
+
});
|
|
1103
|
+
}
|
|
1104
|
+
this.writeBuffer.set(key, value);
|
|
1105
|
+
this.deleteBuffer.delete(key);
|
|
1106
|
+
if (child.createdKeys.has(key)) {
|
|
1107
|
+
this.createdKeys.add(key);
|
|
1108
|
+
}
|
|
1109
|
+
if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
|
|
1110
|
+
this.versionIndex.get(key).push({ version: newVersion, exists: true });
|
|
997
1111
|
}
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
this.
|
|
1112
|
+
for (const key of child.deleteBuffer) {
|
|
1113
|
+
if (this.writeBuffer.has(key)) {
|
|
1114
|
+
if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
|
|
1115
|
+
this.deletedCache.get(key).push({
|
|
1116
|
+
value: this.writeBuffer.get(key),
|
|
1117
|
+
deletedAtVersion: newVersion
|
|
1118
|
+
});
|
|
1119
|
+
} else if (await this.strategy.exists(key)) {
|
|
1120
|
+
if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
|
|
1121
|
+
this.deletedCache.get(key).push({
|
|
1122
|
+
value: await this.strategy.read(key),
|
|
1123
|
+
deletedAtVersion: newVersion
|
|
1124
|
+
});
|
|
1125
|
+
}
|
|
1126
|
+
this.deleteBuffer.add(key);
|
|
1127
|
+
this.writeBuffer.delete(key);
|
|
1128
|
+
this.createdKeys.delete(key);
|
|
1129
|
+
const deletedValue = child.deletedValues.get(key);
|
|
1130
|
+
if (deletedValue !== void 0) {
|
|
1131
|
+
this.deletedValues.set(key, deletedValue);
|
|
1132
|
+
}
|
|
1133
|
+
if (child.originallyExisted.has(key)) {
|
|
1134
|
+
this.originallyExisted.add(key);
|
|
1135
|
+
}
|
|
1136
|
+
if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
|
|
1137
|
+
this.versionIndex.get(key).push({ version: newVersion, exists: false });
|
|
1006
1138
|
}
|
|
1007
|
-
|
|
1008
|
-
|
|
1139
|
+
this.version = newVersion;
|
|
1140
|
+
this.root.activeTransactions.delete(child);
|
|
1141
|
+
this._cleanupDeletedCache();
|
|
1142
|
+
} else {
|
|
1143
|
+
const newVersion = this.version + 1;
|
|
1144
|
+
for (const [key, value] of this.writeBuffer) {
|
|
1145
|
+
await this._diskWrite(key, value, newVersion);
|
|
1009
1146
|
}
|
|
1147
|
+
for (const key of this.deleteBuffer) {
|
|
1148
|
+
await this._diskDelete(key, newVersion);
|
|
1149
|
+
}
|
|
1150
|
+
this.version = newVersion;
|
|
1151
|
+
this._cleanupDeletedCache();
|
|
1010
1152
|
}
|
|
1011
|
-
for (const [key, value] of child.writeBuffer) {
|
|
1012
|
-
await this._diskWrite(key, value, newVersion);
|
|
1013
|
-
}
|
|
1014
|
-
for (const key of child.deleteBuffer) {
|
|
1015
|
-
await this._diskDelete(key, newVersion);
|
|
1016
|
-
}
|
|
1017
|
-
this.version = newVersion;
|
|
1018
|
-
this.root.activeTransactions.delete(child);
|
|
1019
|
-
this._cleanupDeletedCache();
|
|
1020
1153
|
return null;
|
|
1021
1154
|
}
|
|
1022
1155
|
});
|
|
@@ -1042,6 +1175,8 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
1042
1175
|
if (!strategy) throw new Error("Root Transaction missing strategy");
|
|
1043
1176
|
const versions = this.versionIndex.get(key);
|
|
1044
1177
|
if (!versions) {
|
|
1178
|
+
if (this.writeBuffer.has(key)) return this.writeBuffer.get(key);
|
|
1179
|
+
if (this.deleteBuffer.has(key)) return null;
|
|
1045
1180
|
return await strategy.exists(key) ? strategy.read(key) : null;
|
|
1046
1181
|
}
|
|
1047
1182
|
let targetVerObj = null;
|
|
@@ -1062,10 +1197,11 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
1062
1197
|
if (match) return match.value;
|
|
1063
1198
|
}
|
|
1064
1199
|
}
|
|
1065
|
-
return null;
|
|
1200
|
+
return await strategy.exists(key) ? strategy.read(key) : null;
|
|
1066
1201
|
}
|
|
1067
1202
|
if (!targetVerObj.exists) return null;
|
|
1068
1203
|
if (!nextVerObj) {
|
|
1204
|
+
if (this.writeBuffer.has(key)) return this.writeBuffer.get(key);
|
|
1069
1205
|
return strategy.read(key);
|
|
1070
1206
|
}
|
|
1071
1207
|
const cached = this.deletedCache.get(key);
|
|
@@ -1080,6 +1216,8 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
1080
1216
|
if (!strategy) throw new Error("Root Transaction missing strategy");
|
|
1081
1217
|
const versions = this.versionIndex.get(key);
|
|
1082
1218
|
if (!versions) {
|
|
1219
|
+
if (this.writeBuffer.has(key)) return true;
|
|
1220
|
+
if (this.deleteBuffer.has(key)) return false;
|
|
1083
1221
|
return strategy.exists(key);
|
|
1084
1222
|
}
|
|
1085
1223
|
let targetVerObj = null;
|
|
@@ -1103,30 +1241,11 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
|
|
|
1103
1241
|
value: currentVal,
|
|
1104
1242
|
deletedAtVersion: snapshotVersion
|
|
1105
1243
|
});
|
|
1244
|
+
await strategy.delete(key);
|
|
1106
1245
|
}
|
|
1107
|
-
await strategy.delete(key);
|
|
1108
1246
|
if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
|
|
1109
1247
|
this.versionIndex.get(key).push({ version: snapshotVersion, exists: false });
|
|
1110
1248
|
}
|
|
1111
|
-
_cleanupDeletedCache() {
|
|
1112
|
-
if (this.deletedCache.size === 0) return;
|
|
1113
|
-
let minActiveVersion = this.version;
|
|
1114
|
-
if (this.activeTransactions.size > 0) {
|
|
1115
|
-
for (const tx of this.activeTransactions) {
|
|
1116
|
-
if (!tx.committed && tx.snapshotVersion < minActiveVersion) {
|
|
1117
|
-
minActiveVersion = tx.snapshotVersion;
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
}
|
|
1121
|
-
for (const [key, cachedList] of this.deletedCache) {
|
|
1122
|
-
const remaining = cachedList.filter((item) => item.deletedAtVersion > minActiveVersion);
|
|
1123
|
-
if (remaining.length === 0) {
|
|
1124
|
-
this.deletedCache.delete(key);
|
|
1125
|
-
} else {
|
|
1126
|
-
this.deletedCache.set(key, remaining);
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
|
-
}
|
|
1130
1249
|
};
|
|
1131
1250
|
export {
|
|
1132
1251
|
AsyncMVCCStrategy,
|
|
@@ -10,6 +10,7 @@ export declare class AsyncMVCCTransaction<S extends AsyncMVCCStrategy<K, T>, K,
|
|
|
10
10
|
createNested(): this;
|
|
11
11
|
read(key: K): Promise<T | null>;
|
|
12
12
|
exists(key: K): Promise<boolean>;
|
|
13
|
+
_existsSnapshot(key: K, snapshotVersion: number, snapshotLocalVersion?: number): Promise<boolean>;
|
|
13
14
|
_readSnapshot(key: K, snapshotVersion: number, snapshotLocalVersion?: number): Promise<T | null>;
|
|
14
15
|
commit(label?: string): Promise<TransactionResult<K, T>>;
|
|
15
16
|
_merge(child: AsyncMVCCTransaction<S, K, T>): Promise<TransactionMergeFailure<K, T> | null>;
|
|
@@ -17,5 +18,4 @@ export declare class AsyncMVCCTransaction<S extends AsyncMVCCStrategy<K, T>, K,
|
|
|
17
18
|
_diskRead(key: K, snapshotVersion: number): Promise<T | null>;
|
|
18
19
|
_diskExists(key: K, snapshotVersion: number): Promise<boolean>;
|
|
19
20
|
_diskDelete(key: K, snapshotVersion: number): Promise<void>;
|
|
20
|
-
_cleanupDeletedCache(): void;
|
|
21
21
|
}
|
|
@@ -120,4 +120,17 @@ export declare abstract class MVCCTransaction<S extends MVCCStrategy<K, T>, K, T
|
|
|
120
120
|
* @param snapshotLocalVersion The local version within the parent's buffer to read at.
|
|
121
121
|
*/
|
|
122
122
|
abstract _readSnapshot(key: K, snapshotVersion: number, snapshotLocalVersion?: number): Deferred<T | null>;
|
|
123
|
+
/**
|
|
124
|
+
* Checks if a key exists at a specific snapshot version.
|
|
125
|
+
* Used by child transactions to check existence from parent respecting the child's snapshot.
|
|
126
|
+
* @param key The key to check.
|
|
127
|
+
* @param snapshotVersion The global version to check at.
|
|
128
|
+
* @param snapshotLocalVersion The local version within the parent's buffer to check at.
|
|
129
|
+
*/
|
|
130
|
+
abstract _existsSnapshot(key: K, snapshotVersion: number, snapshotLocalVersion?: number): Deferred<boolean>;
|
|
131
|
+
/**
|
|
132
|
+
* Cleans up both deletedCache and versionIndex based on minActiveVersion.
|
|
133
|
+
* Root transactions call this after commit to reclaim memory.
|
|
134
|
+
*/
|
|
135
|
+
protected _cleanupDeletedCache(): void;
|
|
123
136
|
}
|
|
@@ -8,6 +8,7 @@ export declare class SyncMVCCTransaction<S extends SyncMVCCStrategy<K, T>, K, T>
|
|
|
8
8
|
createNested(): this;
|
|
9
9
|
read(key: K): T | null;
|
|
10
10
|
exists(key: K): boolean;
|
|
11
|
+
_existsSnapshot(key: K, snapshotVersion: number, snapshotLocalVersion?: number): boolean;
|
|
11
12
|
_readSnapshot(key: K, snapshotVersion: number, snapshotLocalVersion?: number): T | null;
|
|
12
13
|
commit(label?: string): TransactionResult<K, T>;
|
|
13
14
|
_merge(child: SyncMVCCTransaction<S, K, T>): TransactionMergeFailure<K, T> | null;
|
|
@@ -15,5 +16,4 @@ export declare class SyncMVCCTransaction<S extends SyncMVCCStrategy<K, T>, K, T>
|
|
|
15
16
|
_diskRead(key: K, snapshotVersion: number): T | null;
|
|
16
17
|
_diskExists(key: K, snapshotVersion: number): boolean;
|
|
17
18
|
_diskDelete(key: K, snapshotVersion: number): void;
|
|
18
|
-
_cleanupDeletedCache(): void;
|
|
19
19
|
}
|