serializable-bptree 8.3.0 → 8.3.1
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 +87 -20
- package/dist/esm/index.mjs +87 -20
- package/dist/types/base/BPTreeTransaction.d.ts +7 -0
- package/package.json +1 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -1696,6 +1696,39 @@ var BPTreeTransaction = class _BPTreeTransaction {
|
|
|
1696
1696
|
}
|
|
1697
1697
|
return true;
|
|
1698
1698
|
}
|
|
1699
|
+
/**
|
|
1700
|
+
* Inserts a key-value pair into an already-cloned leaf node in-place.
|
|
1701
|
+
* Unlike _insertAtLeaf, this does NOT clone or update the node via MVCC.
|
|
1702
|
+
* Used by batchInsert to batch multiple insertions with a single clone/update.
|
|
1703
|
+
* @returns true if the leaf was modified, false if the key already exists.
|
|
1704
|
+
*/
|
|
1705
|
+
_insertValueIntoLeaf(leaf, key, value) {
|
|
1706
|
+
if (leaf.values.length) {
|
|
1707
|
+
for (let i = 0, len = leaf.values.length; i < len; i++) {
|
|
1708
|
+
const nValue = leaf.values[i];
|
|
1709
|
+
if (this.comparator.isSame(value, nValue)) {
|
|
1710
|
+
if (leaf.keys[i].includes(key)) {
|
|
1711
|
+
return false;
|
|
1712
|
+
}
|
|
1713
|
+
leaf.keys[i].push(key);
|
|
1714
|
+
return true;
|
|
1715
|
+
} else if (this.comparator.isLower(value, nValue)) {
|
|
1716
|
+
leaf.values.splice(i, 0, value);
|
|
1717
|
+
leaf.keys.splice(i, 0, [key]);
|
|
1718
|
+
return true;
|
|
1719
|
+
} else if (i + 1 === leaf.values.length) {
|
|
1720
|
+
leaf.values.push(value);
|
|
1721
|
+
leaf.keys.push([key]);
|
|
1722
|
+
return true;
|
|
1723
|
+
}
|
|
1724
|
+
}
|
|
1725
|
+
} else {
|
|
1726
|
+
leaf.values = [value];
|
|
1727
|
+
leaf.keys = [[key]];
|
|
1728
|
+
return true;
|
|
1729
|
+
}
|
|
1730
|
+
return false;
|
|
1731
|
+
}
|
|
1699
1732
|
_cloneNode(node) {
|
|
1700
1733
|
return JSON.parse(JSON.stringify(node));
|
|
1701
1734
|
}
|
|
@@ -2259,29 +2292,46 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2259
2292
|
batchInsert(entries) {
|
|
2260
2293
|
if (entries.length === 0) return;
|
|
2261
2294
|
const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
|
|
2295
|
+
let currentLeaf = null;
|
|
2296
|
+
let modified = false;
|
|
2262
2297
|
for (const [key, value] of sorted) {
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2298
|
+
const targetLeaf = this.insertableNode(value);
|
|
2299
|
+
if (currentLeaf !== null && currentLeaf.id === targetLeaf.id) {
|
|
2300
|
+
} else {
|
|
2301
|
+
if (currentLeaf !== null && modified) {
|
|
2302
|
+
this._updateNode(currentLeaf);
|
|
2303
|
+
}
|
|
2304
|
+
currentLeaf = this._cloneNode(targetLeaf);
|
|
2305
|
+
modified = false;
|
|
2306
|
+
}
|
|
2307
|
+
const changed = this._insertValueIntoLeaf(currentLeaf, key, value);
|
|
2308
|
+
modified = modified || changed;
|
|
2309
|
+
if (currentLeaf.values.length === this.order) {
|
|
2310
|
+
this._updateNode(currentLeaf);
|
|
2266
2311
|
let after = this._createNode(
|
|
2267
2312
|
true,
|
|
2268
2313
|
[],
|
|
2269
2314
|
[],
|
|
2270
|
-
|
|
2315
|
+
currentLeaf.parent,
|
|
2271
2316
|
null,
|
|
2272
2317
|
null
|
|
2273
2318
|
);
|
|
2274
2319
|
const mid = Math.ceil(this.order / 2) - 1;
|
|
2275
2320
|
after = this._cloneNode(after);
|
|
2276
|
-
after.values =
|
|
2277
|
-
after.keys =
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
this._updateNode(
|
|
2321
|
+
after.values = currentLeaf.values.slice(mid + 1);
|
|
2322
|
+
after.keys = currentLeaf.keys.slice(mid + 1);
|
|
2323
|
+
currentLeaf.values = currentLeaf.values.slice(0, mid + 1);
|
|
2324
|
+
currentLeaf.keys = currentLeaf.keys.slice(0, mid + 1);
|
|
2325
|
+
this._updateNode(currentLeaf);
|
|
2281
2326
|
this._updateNode(after);
|
|
2282
|
-
this._insertInParent(
|
|
2327
|
+
this._insertInParent(currentLeaf, after.values[0], after);
|
|
2328
|
+
currentLeaf = null;
|
|
2329
|
+
modified = false;
|
|
2283
2330
|
}
|
|
2284
2331
|
}
|
|
2332
|
+
if (currentLeaf !== null && modified) {
|
|
2333
|
+
this._updateNode(currentLeaf);
|
|
2334
|
+
}
|
|
2285
2335
|
}
|
|
2286
2336
|
_deleteEntry(node, key) {
|
|
2287
2337
|
if (!node.leaf) {
|
|
@@ -3383,29 +3433,46 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3383
3433
|
if (entries.length === 0) return;
|
|
3384
3434
|
return this.writeLock(0, async () => {
|
|
3385
3435
|
const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
|
|
3436
|
+
let currentLeaf = null;
|
|
3437
|
+
let modified = false;
|
|
3386
3438
|
for (const [key, value] of sorted) {
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3439
|
+
const targetLeaf = await this.insertableNode(value);
|
|
3440
|
+
if (currentLeaf !== null && currentLeaf.id === targetLeaf.id) {
|
|
3441
|
+
} else {
|
|
3442
|
+
if (currentLeaf !== null && modified) {
|
|
3443
|
+
await this._updateNode(currentLeaf);
|
|
3444
|
+
}
|
|
3445
|
+
currentLeaf = this._cloneNode(targetLeaf);
|
|
3446
|
+
modified = false;
|
|
3447
|
+
}
|
|
3448
|
+
const changed = this._insertValueIntoLeaf(currentLeaf, key, value);
|
|
3449
|
+
modified = modified || changed;
|
|
3450
|
+
if (currentLeaf.values.length === this.order) {
|
|
3451
|
+
await this._updateNode(currentLeaf);
|
|
3390
3452
|
let after = await this._createNode(
|
|
3391
3453
|
true,
|
|
3392
3454
|
[],
|
|
3393
3455
|
[],
|
|
3394
|
-
|
|
3456
|
+
currentLeaf.parent,
|
|
3395
3457
|
null,
|
|
3396
3458
|
null
|
|
3397
3459
|
);
|
|
3398
3460
|
const mid = Math.ceil(this.order / 2) - 1;
|
|
3399
3461
|
after = this._cloneNode(after);
|
|
3400
|
-
after.values =
|
|
3401
|
-
after.keys =
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
await this._updateNode(
|
|
3462
|
+
after.values = currentLeaf.values.slice(mid + 1);
|
|
3463
|
+
after.keys = currentLeaf.keys.slice(mid + 1);
|
|
3464
|
+
currentLeaf.values = currentLeaf.values.slice(0, mid + 1);
|
|
3465
|
+
currentLeaf.keys = currentLeaf.keys.slice(0, mid + 1);
|
|
3466
|
+
await this._updateNode(currentLeaf);
|
|
3405
3467
|
await this._updateNode(after);
|
|
3406
|
-
await this._insertInParent(
|
|
3468
|
+
await this._insertInParent(currentLeaf, after.values[0], after);
|
|
3469
|
+
currentLeaf = null;
|
|
3470
|
+
modified = false;
|
|
3407
3471
|
}
|
|
3408
3472
|
}
|
|
3473
|
+
if (currentLeaf !== null && modified) {
|
|
3474
|
+
await this._updateNode(currentLeaf);
|
|
3475
|
+
}
|
|
3409
3476
|
});
|
|
3410
3477
|
}
|
|
3411
3478
|
async _deleteEntry(node, key) {
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1660,6 +1660,39 @@ var BPTreeTransaction = class _BPTreeTransaction {
|
|
|
1660
1660
|
}
|
|
1661
1661
|
return true;
|
|
1662
1662
|
}
|
|
1663
|
+
/**
|
|
1664
|
+
* Inserts a key-value pair into an already-cloned leaf node in-place.
|
|
1665
|
+
* Unlike _insertAtLeaf, this does NOT clone or update the node via MVCC.
|
|
1666
|
+
* Used by batchInsert to batch multiple insertions with a single clone/update.
|
|
1667
|
+
* @returns true if the leaf was modified, false if the key already exists.
|
|
1668
|
+
*/
|
|
1669
|
+
_insertValueIntoLeaf(leaf, key, value) {
|
|
1670
|
+
if (leaf.values.length) {
|
|
1671
|
+
for (let i = 0, len = leaf.values.length; i < len; i++) {
|
|
1672
|
+
const nValue = leaf.values[i];
|
|
1673
|
+
if (this.comparator.isSame(value, nValue)) {
|
|
1674
|
+
if (leaf.keys[i].includes(key)) {
|
|
1675
|
+
return false;
|
|
1676
|
+
}
|
|
1677
|
+
leaf.keys[i].push(key);
|
|
1678
|
+
return true;
|
|
1679
|
+
} else if (this.comparator.isLower(value, nValue)) {
|
|
1680
|
+
leaf.values.splice(i, 0, value);
|
|
1681
|
+
leaf.keys.splice(i, 0, [key]);
|
|
1682
|
+
return true;
|
|
1683
|
+
} else if (i + 1 === leaf.values.length) {
|
|
1684
|
+
leaf.values.push(value);
|
|
1685
|
+
leaf.keys.push([key]);
|
|
1686
|
+
return true;
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
} else {
|
|
1690
|
+
leaf.values = [value];
|
|
1691
|
+
leaf.keys = [[key]];
|
|
1692
|
+
return true;
|
|
1693
|
+
}
|
|
1694
|
+
return false;
|
|
1695
|
+
}
|
|
1663
1696
|
_cloneNode(node) {
|
|
1664
1697
|
return JSON.parse(JSON.stringify(node));
|
|
1665
1698
|
}
|
|
@@ -2223,29 +2256,46 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2223
2256
|
batchInsert(entries) {
|
|
2224
2257
|
if (entries.length === 0) return;
|
|
2225
2258
|
const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
|
|
2259
|
+
let currentLeaf = null;
|
|
2260
|
+
let modified = false;
|
|
2226
2261
|
for (const [key, value] of sorted) {
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2262
|
+
const targetLeaf = this.insertableNode(value);
|
|
2263
|
+
if (currentLeaf !== null && currentLeaf.id === targetLeaf.id) {
|
|
2264
|
+
} else {
|
|
2265
|
+
if (currentLeaf !== null && modified) {
|
|
2266
|
+
this._updateNode(currentLeaf);
|
|
2267
|
+
}
|
|
2268
|
+
currentLeaf = this._cloneNode(targetLeaf);
|
|
2269
|
+
modified = false;
|
|
2270
|
+
}
|
|
2271
|
+
const changed = this._insertValueIntoLeaf(currentLeaf, key, value);
|
|
2272
|
+
modified = modified || changed;
|
|
2273
|
+
if (currentLeaf.values.length === this.order) {
|
|
2274
|
+
this._updateNode(currentLeaf);
|
|
2230
2275
|
let after = this._createNode(
|
|
2231
2276
|
true,
|
|
2232
2277
|
[],
|
|
2233
2278
|
[],
|
|
2234
|
-
|
|
2279
|
+
currentLeaf.parent,
|
|
2235
2280
|
null,
|
|
2236
2281
|
null
|
|
2237
2282
|
);
|
|
2238
2283
|
const mid = Math.ceil(this.order / 2) - 1;
|
|
2239
2284
|
after = this._cloneNode(after);
|
|
2240
|
-
after.values =
|
|
2241
|
-
after.keys =
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
this._updateNode(
|
|
2285
|
+
after.values = currentLeaf.values.slice(mid + 1);
|
|
2286
|
+
after.keys = currentLeaf.keys.slice(mid + 1);
|
|
2287
|
+
currentLeaf.values = currentLeaf.values.slice(0, mid + 1);
|
|
2288
|
+
currentLeaf.keys = currentLeaf.keys.slice(0, mid + 1);
|
|
2289
|
+
this._updateNode(currentLeaf);
|
|
2245
2290
|
this._updateNode(after);
|
|
2246
|
-
this._insertInParent(
|
|
2291
|
+
this._insertInParent(currentLeaf, after.values[0], after);
|
|
2292
|
+
currentLeaf = null;
|
|
2293
|
+
modified = false;
|
|
2247
2294
|
}
|
|
2248
2295
|
}
|
|
2296
|
+
if (currentLeaf !== null && modified) {
|
|
2297
|
+
this._updateNode(currentLeaf);
|
|
2298
|
+
}
|
|
2249
2299
|
}
|
|
2250
2300
|
_deleteEntry(node, key) {
|
|
2251
2301
|
if (!node.leaf) {
|
|
@@ -3347,29 +3397,46 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3347
3397
|
if (entries.length === 0) return;
|
|
3348
3398
|
return this.writeLock(0, async () => {
|
|
3349
3399
|
const sorted = [...entries].sort((a, b) => this.comparator.asc(a[1], b[1]));
|
|
3400
|
+
let currentLeaf = null;
|
|
3401
|
+
let modified = false;
|
|
3350
3402
|
for (const [key, value] of sorted) {
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3403
|
+
const targetLeaf = await this.insertableNode(value);
|
|
3404
|
+
if (currentLeaf !== null && currentLeaf.id === targetLeaf.id) {
|
|
3405
|
+
} else {
|
|
3406
|
+
if (currentLeaf !== null && modified) {
|
|
3407
|
+
await this._updateNode(currentLeaf);
|
|
3408
|
+
}
|
|
3409
|
+
currentLeaf = this._cloneNode(targetLeaf);
|
|
3410
|
+
modified = false;
|
|
3411
|
+
}
|
|
3412
|
+
const changed = this._insertValueIntoLeaf(currentLeaf, key, value);
|
|
3413
|
+
modified = modified || changed;
|
|
3414
|
+
if (currentLeaf.values.length === this.order) {
|
|
3415
|
+
await this._updateNode(currentLeaf);
|
|
3354
3416
|
let after = await this._createNode(
|
|
3355
3417
|
true,
|
|
3356
3418
|
[],
|
|
3357
3419
|
[],
|
|
3358
|
-
|
|
3420
|
+
currentLeaf.parent,
|
|
3359
3421
|
null,
|
|
3360
3422
|
null
|
|
3361
3423
|
);
|
|
3362
3424
|
const mid = Math.ceil(this.order / 2) - 1;
|
|
3363
3425
|
after = this._cloneNode(after);
|
|
3364
|
-
after.values =
|
|
3365
|
-
after.keys =
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
await this._updateNode(
|
|
3426
|
+
after.values = currentLeaf.values.slice(mid + 1);
|
|
3427
|
+
after.keys = currentLeaf.keys.slice(mid + 1);
|
|
3428
|
+
currentLeaf.values = currentLeaf.values.slice(0, mid + 1);
|
|
3429
|
+
currentLeaf.keys = currentLeaf.keys.slice(0, mid + 1);
|
|
3430
|
+
await this._updateNode(currentLeaf);
|
|
3369
3431
|
await this._updateNode(after);
|
|
3370
|
-
await this._insertInParent(
|
|
3432
|
+
await this._insertInParent(currentLeaf, after.values[0], after);
|
|
3433
|
+
currentLeaf = null;
|
|
3434
|
+
modified = false;
|
|
3371
3435
|
}
|
|
3372
3436
|
}
|
|
3437
|
+
if (currentLeaf !== null && modified) {
|
|
3438
|
+
await this._updateNode(currentLeaf);
|
|
3439
|
+
}
|
|
3373
3440
|
});
|
|
3374
3441
|
}
|
|
3375
3442
|
async _deleteEntry(node, key) {
|
|
@@ -80,6 +80,13 @@ export declare abstract class BPTreeTransaction<K, V> {
|
|
|
80
80
|
* @returns Returns true if the value satisfies the condition.
|
|
81
81
|
*/
|
|
82
82
|
verify(nodeValue: V, condition: BPTreeCondition<V>): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Inserts a key-value pair into an already-cloned leaf node in-place.
|
|
85
|
+
* Unlike _insertAtLeaf, this does NOT clone or update the node via MVCC.
|
|
86
|
+
* Used by batchInsert to batch multiple insertions with a single clone/update.
|
|
87
|
+
* @returns true if the leaf was modified, false if the key already exists.
|
|
88
|
+
*/
|
|
89
|
+
protected _insertValueIntoLeaf(leaf: BPTreeLeafNode<K, V>, key: K, value: V): boolean;
|
|
83
90
|
protected _cloneNode<T extends BPTreeUnknownNode<K, V>>(node: T): T;
|
|
84
91
|
/**
|
|
85
92
|
* Selects the best driver key from a condition object.
|