serializable-bptree 3.3.0 → 3.4.0-alpha.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/README.md +5 -5
- package/dist/cjs/index.cjs +47 -16
- package/dist/esm/index.mjs +47 -16
- package/dist/typings/BPTreeAsync.d.ts +3 -2
- package/dist/typings/BPTreeSync.d.ts +3 -2
- package/dist/typings/SerializeStrategyAsync.d.ts +4 -2
- package/dist/typings/SerializeStrategySync.d.ts +4 -2
- package/dist/typings/base/BPTree.d.ts +6 -4
- package/dist/typings/base/SerializeStrategy.d.ts +8 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -187,12 +187,12 @@ class MyFileIOStrategySync extends SerializeStrategySync {
|
|
|
187
187
|
|
|
188
188
|
What does this method mean? And why do we need to construct such a method?
|
|
189
189
|
|
|
190
|
-
#### id(): `number`
|
|
190
|
+
#### id(isLeaf: `boolean`): `number`
|
|
191
191
|
|
|
192
192
|
When a node is created in the B+tree, the node needs a unique value to represent itself. This is the **node.id** attribute, and you can specify this attribute yourself. For example, it could be implemented like this.
|
|
193
193
|
|
|
194
194
|
```typescript
|
|
195
|
-
id(): number {
|
|
195
|
+
id(isLeaf: boolean): number {
|
|
196
196
|
const current = before + 1
|
|
197
197
|
before = current
|
|
198
198
|
return current
|
|
@@ -204,7 +204,7 @@ Or, you could use file input/output to save and load the value of the **before**
|
|
|
204
204
|
Typically, such an **id** value increases sequentially, and it would be beneficial to store such a value separately within the tree. For that purpose, the **setHeadData** and **getHeadData** methods are available. These methods are responsible for storing arbitrary data in the tree's header or retrieving stored data. Below is an example of usage:
|
|
205
205
|
|
|
206
206
|
```typescript
|
|
207
|
-
id(): number {
|
|
207
|
+
id(isLeaf: boolean): number {
|
|
208
208
|
const current = this.getHeadData('index', 1) as number
|
|
209
209
|
this.setHeadData('index', current+1)
|
|
210
210
|
return current
|
|
@@ -214,7 +214,7 @@ id(): number {
|
|
|
214
214
|
Additionally, there is a more user-friendly usage of this code.
|
|
215
215
|
|
|
216
216
|
```typescript
|
|
217
|
-
id(): number {
|
|
217
|
+
id(isLeaf: boolean): number {
|
|
218
218
|
return this.autoIncrement('index', 1)
|
|
219
219
|
}
|
|
220
220
|
```
|
|
@@ -366,7 +366,7 @@ import {
|
|
|
366
366
|
} from 'serializable-bptree'
|
|
367
367
|
|
|
368
368
|
class FileStoreStrategyAsync extends SerializeStrategyAsync<K, V> {
|
|
369
|
-
async id(): Promise<number> {
|
|
369
|
+
async id(isLeaf: boolean): Promise<number> {
|
|
370
370
|
return await this.autoIncrement('index', 1)
|
|
371
371
|
}
|
|
372
372
|
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -436,6 +436,7 @@ var BPTree = class {
|
|
|
436
436
|
root;
|
|
437
437
|
_nodeCreateBuffer;
|
|
438
438
|
_nodeUpdateBuffer;
|
|
439
|
+
_nodeDeleteBuffer;
|
|
439
440
|
verifierMap = {
|
|
440
441
|
gt: (nv, v) => this.comparator.isHigher(nv, v),
|
|
441
442
|
gte: (nv, v) => this.comparator.isHigher(nv, v) || this.comparator.isSame(nv, v),
|
|
@@ -484,6 +485,7 @@ var BPTree = class {
|
|
|
484
485
|
this._cachedRegexp = new CacheBranchSync();
|
|
485
486
|
this._nodeCreateBuffer = /* @__PURE__ */ new Map();
|
|
486
487
|
this._nodeUpdateBuffer = /* @__PURE__ */ new Map();
|
|
488
|
+
this._nodeDeleteBuffer = /* @__PURE__ */ new Map();
|
|
487
489
|
this.nodes = /* @__PURE__ */ new Map();
|
|
488
490
|
this.strategy = strategy;
|
|
489
491
|
this.comparator = comparator;
|
|
@@ -521,6 +523,9 @@ var BPTree = class {
|
|
|
521
523
|
bufferForNodeUpdate(node) {
|
|
522
524
|
this._nodeUpdateBuffer.set(node.id, node);
|
|
523
525
|
}
|
|
526
|
+
bufferForNodeDelete(node) {
|
|
527
|
+
this._nodeDeleteBuffer.set(node.id, node);
|
|
528
|
+
}
|
|
524
529
|
/**
|
|
525
530
|
* Returns the user-defined data stored in the head of the tree.
|
|
526
531
|
* This value can be set using the `setHeadData` method. If no data has been previously inserted, the default value is returned, and the default value is `{}`.
|
|
@@ -602,15 +607,15 @@ var BPTreeSync = class extends BPTree {
|
|
|
602
607
|
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
603
608
|
}
|
|
604
609
|
}
|
|
605
|
-
_createNodeId() {
|
|
606
|
-
const id = this.strategy.id();
|
|
610
|
+
_createNodeId(isLeaf) {
|
|
611
|
+
const id = this.strategy.id(isLeaf);
|
|
607
612
|
if (id === 0) {
|
|
608
613
|
throw new Error(`The node's id should never be 0.`);
|
|
609
614
|
}
|
|
610
615
|
return id;
|
|
611
616
|
}
|
|
612
|
-
_createNode(keys2, values, leaf = false, parent = 0, next = 0, prev = 0) {
|
|
613
|
-
const id = this._createNodeId();
|
|
617
|
+
_createNode(isLeaf, keys2, values, leaf = false, parent = 0, next = 0, prev = 0) {
|
|
618
|
+
const id = this._createNodeId(isLeaf);
|
|
614
619
|
const node = {
|
|
615
620
|
id,
|
|
616
621
|
keys: keys2,
|
|
@@ -644,6 +649,7 @@ var BPTreeSync = class extends BPTree {
|
|
|
644
649
|
}
|
|
645
650
|
if (this.root === node && node.keys.length === 1) {
|
|
646
651
|
const keys2 = node.keys;
|
|
652
|
+
this.bufferForNodeDelete(this.root);
|
|
647
653
|
this.root = this.getNode(keys2[0]);
|
|
648
654
|
this.root.parent = 0;
|
|
649
655
|
this.strategy.head.root = this.root.id;
|
|
@@ -727,6 +733,7 @@ var BPTreeSync = class extends BPTree {
|
|
|
727
733
|
}
|
|
728
734
|
this._deleteEntry(this.getNode(node.parent), node.id, guess);
|
|
729
735
|
this.bufferForNodeUpdate(pointer);
|
|
736
|
+
this.bufferForNodeDelete(node);
|
|
730
737
|
} else {
|
|
731
738
|
if (isPredecessor) {
|
|
732
739
|
let pointerPm;
|
|
@@ -823,7 +830,7 @@ var BPTreeSync = class extends BPTree {
|
|
|
823
830
|
}
|
|
824
831
|
_insertInParent(node, value, pointer) {
|
|
825
832
|
if (this.root === node) {
|
|
826
|
-
const root = this._createNode([node.id, pointer.id], [value]);
|
|
833
|
+
const root = this._createNode(false, [node.id, pointer.id], [value]);
|
|
827
834
|
this.root = root;
|
|
828
835
|
this.strategy.head.root = root.id;
|
|
829
836
|
node.parent = root.id;
|
|
@@ -841,7 +848,7 @@ var BPTreeSync = class extends BPTree {
|
|
|
841
848
|
parentNode.keys.splice(i + 1, 0, pointer.id);
|
|
842
849
|
this.bufferForNodeUpdate(parentNode);
|
|
843
850
|
if (parentNode.keys.length > this.order) {
|
|
844
|
-
const parentPointer = this._createNode([], []);
|
|
851
|
+
const parentPointer = this._createNode(false, [], []);
|
|
845
852
|
parentPointer.parent = parentNode.parent;
|
|
846
853
|
const mid = Math.ceil(this.order / 2) - 1;
|
|
847
854
|
parentPointer.values = parentNode.values.slice(mid + 1);
|
|
@@ -874,7 +881,7 @@ var BPTreeSync = class extends BPTree {
|
|
|
874
881
|
const head = this.strategy.readHead();
|
|
875
882
|
if (head === null) {
|
|
876
883
|
this.order = this.strategy.order;
|
|
877
|
-
this.root = this._createNode([], [], true);
|
|
884
|
+
this.root = this._createNode(true, [], [], true);
|
|
878
885
|
this.strategy.head.root = this.root.id;
|
|
879
886
|
this.bufferForNodeCreate(this.root);
|
|
880
887
|
this.commitHeadBuffer();
|
|
@@ -938,6 +945,12 @@ var BPTreeSync = class extends BPTree {
|
|
|
938
945
|
}
|
|
939
946
|
this._nodeUpdateBuffer.clear();
|
|
940
947
|
}
|
|
948
|
+
commitNodeDeleteBuffer() {
|
|
949
|
+
for (const node of this._nodeDeleteBuffer.values()) {
|
|
950
|
+
this.strategy.delete(node.id);
|
|
951
|
+
}
|
|
952
|
+
this._nodeDeleteBuffer.clear();
|
|
953
|
+
}
|
|
941
954
|
keys(condition, filterValues) {
|
|
942
955
|
for (const k in condition) {
|
|
943
956
|
const key = k;
|
|
@@ -990,6 +1003,7 @@ var BPTreeSync = class extends BPTree {
|
|
|
990
1003
|
this._insertAtLeaf(before, key, value);
|
|
991
1004
|
if (before.values.length === this.order) {
|
|
992
1005
|
const after = this._createNode(
|
|
1006
|
+
true,
|
|
993
1007
|
[],
|
|
994
1008
|
[],
|
|
995
1009
|
true,
|
|
@@ -1045,6 +1059,7 @@ var BPTreeSync = class extends BPTree {
|
|
|
1045
1059
|
this.commitHeadBuffer();
|
|
1046
1060
|
this.commitNodeCreateBuffer();
|
|
1047
1061
|
this.commitNodeUpdateBuffer();
|
|
1062
|
+
this.commitNodeDeleteBuffer();
|
|
1048
1063
|
}
|
|
1049
1064
|
exists(key, value) {
|
|
1050
1065
|
const node = this.insertableNode(value);
|
|
@@ -1143,15 +1158,15 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1143
1158
|
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
1144
1159
|
}
|
|
1145
1160
|
}
|
|
1146
|
-
async _createNodeId() {
|
|
1147
|
-
const id = await this.strategy.id();
|
|
1161
|
+
async _createNodeId(isLeaf) {
|
|
1162
|
+
const id = await this.strategy.id(isLeaf);
|
|
1148
1163
|
if (id === 0) {
|
|
1149
1164
|
throw new Error(`The node's id should never be 0.`);
|
|
1150
1165
|
}
|
|
1151
1166
|
return id;
|
|
1152
1167
|
}
|
|
1153
|
-
async _createNode(keys2, values, leaf = false, parent = 0, next = 0, prev = 0) {
|
|
1154
|
-
const id = await this._createNodeId();
|
|
1168
|
+
async _createNode(isLeaf, keys2, values, leaf = false, parent = 0, next = 0, prev = 0) {
|
|
1169
|
+
const id = await this._createNodeId(isLeaf);
|
|
1155
1170
|
const node = {
|
|
1156
1171
|
id,
|
|
1157
1172
|
keys: keys2,
|
|
@@ -1185,6 +1200,7 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1185
1200
|
}
|
|
1186
1201
|
if (this.root === node && node.keys.length === 1) {
|
|
1187
1202
|
const keys2 = node.keys;
|
|
1203
|
+
this.bufferForNodeDelete(this.root);
|
|
1188
1204
|
this.root = await this.getNode(keys2[0]);
|
|
1189
1205
|
this.root.parent = 0;
|
|
1190
1206
|
this.strategy.head.root = this.root.id;
|
|
@@ -1268,6 +1284,7 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1268
1284
|
}
|
|
1269
1285
|
await this._deleteEntry(await this.getNode(node.parent), node.id, guess);
|
|
1270
1286
|
this.bufferForNodeUpdate(pointer);
|
|
1287
|
+
this.bufferForNodeDelete(node);
|
|
1271
1288
|
} else {
|
|
1272
1289
|
if (isPredecessor) {
|
|
1273
1290
|
let pointerPm;
|
|
@@ -1364,7 +1381,7 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1364
1381
|
}
|
|
1365
1382
|
async _insertInParent(node, value, pointer) {
|
|
1366
1383
|
if (this.root === node) {
|
|
1367
|
-
const root = await this._createNode([node.id, pointer.id], [value]);
|
|
1384
|
+
const root = await this._createNode(false, [node.id, pointer.id], [value]);
|
|
1368
1385
|
this.root = root;
|
|
1369
1386
|
this.strategy.head.root = root.id;
|
|
1370
1387
|
node.parent = root.id;
|
|
@@ -1382,7 +1399,7 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1382
1399
|
parentNode.keys.splice(i + 1, 0, pointer.id);
|
|
1383
1400
|
this.bufferForNodeUpdate(parentNode);
|
|
1384
1401
|
if (parentNode.keys.length > this.order) {
|
|
1385
|
-
const parentPointer = await this._createNode([], []);
|
|
1402
|
+
const parentPointer = await this._createNode(false, [], []);
|
|
1386
1403
|
parentPointer.parent = parentNode.parent;
|
|
1387
1404
|
const mid = Math.ceil(this.order / 2) - 1;
|
|
1388
1405
|
parentPointer.values = parentNode.values.slice(mid + 1);
|
|
@@ -1415,7 +1432,7 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1415
1432
|
const head = await this.strategy.readHead();
|
|
1416
1433
|
if (head === null) {
|
|
1417
1434
|
this.order = this.strategy.order;
|
|
1418
|
-
this.root = await this._createNode([], [], true);
|
|
1435
|
+
this.root = await this._createNode(true, [], [], true);
|
|
1419
1436
|
this.strategy.head.root = this.root.id;
|
|
1420
1437
|
this.bufferForNodeCreate(this.root);
|
|
1421
1438
|
this.commitHeadBuffer();
|
|
@@ -1479,6 +1496,12 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1479
1496
|
}
|
|
1480
1497
|
this._nodeUpdateBuffer.clear();
|
|
1481
1498
|
}
|
|
1499
|
+
async commitNodeDeleteBuffer() {
|
|
1500
|
+
for (const node of this._nodeDeleteBuffer.values()) {
|
|
1501
|
+
await this.strategy.delete(node.id);
|
|
1502
|
+
}
|
|
1503
|
+
this._nodeDeleteBuffer.clear();
|
|
1504
|
+
}
|
|
1482
1505
|
async keys(condition, filterValues) {
|
|
1483
1506
|
for (const k in condition) {
|
|
1484
1507
|
const key = k;
|
|
@@ -1531,6 +1554,7 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1531
1554
|
this._insertAtLeaf(before, key, value);
|
|
1532
1555
|
if (before.values.length === this.order) {
|
|
1533
1556
|
const after = await this._createNode(
|
|
1557
|
+
true,
|
|
1534
1558
|
[],
|
|
1535
1559
|
[],
|
|
1536
1560
|
true,
|
|
@@ -1586,6 +1610,7 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1586
1610
|
await this.commitHeadBuffer();
|
|
1587
1611
|
await this.commitNodeCreateBuffer();
|
|
1588
1612
|
await this.commitNodeUpdateBuffer();
|
|
1613
|
+
await this.commitNodeDeleteBuffer();
|
|
1589
1614
|
}
|
|
1590
1615
|
async exists(key, value) {
|
|
1591
1616
|
const node = await this.insertableNode(value);
|
|
@@ -1652,7 +1677,7 @@ var InMemoryStoreStrategySync = class extends SerializeStrategySync {
|
|
|
1652
1677
|
super(order);
|
|
1653
1678
|
this.node = {};
|
|
1654
1679
|
}
|
|
1655
|
-
id() {
|
|
1680
|
+
id(isLeaf) {
|
|
1656
1681
|
return this.autoIncrement("index", 1);
|
|
1657
1682
|
}
|
|
1658
1683
|
read(id) {
|
|
@@ -1664,6 +1689,9 @@ var InMemoryStoreStrategySync = class extends SerializeStrategySync {
|
|
|
1664
1689
|
write(id, node) {
|
|
1665
1690
|
this.node[id] = node;
|
|
1666
1691
|
}
|
|
1692
|
+
delete(id) {
|
|
1693
|
+
delete this.node[id];
|
|
1694
|
+
}
|
|
1667
1695
|
readHead() {
|
|
1668
1696
|
if (this.head.root === 0) {
|
|
1669
1697
|
return null;
|
|
@@ -1700,7 +1728,7 @@ var InMemoryStoreStrategyAsync = class extends SerializeStrategyAsync {
|
|
|
1700
1728
|
super(order);
|
|
1701
1729
|
this.node = {};
|
|
1702
1730
|
}
|
|
1703
|
-
async id() {
|
|
1731
|
+
async id(isLeaf) {
|
|
1704
1732
|
return await this.autoIncrement("index", 1);
|
|
1705
1733
|
}
|
|
1706
1734
|
async read(id) {
|
|
@@ -1712,6 +1740,9 @@ var InMemoryStoreStrategyAsync = class extends SerializeStrategyAsync {
|
|
|
1712
1740
|
async write(id, node) {
|
|
1713
1741
|
this.node[id] = node;
|
|
1714
1742
|
}
|
|
1743
|
+
async delete(id) {
|
|
1744
|
+
delete this.node[id];
|
|
1745
|
+
}
|
|
1715
1746
|
async readHead() {
|
|
1716
1747
|
if (this.head.root === 0) {
|
|
1717
1748
|
return null;
|
package/dist/esm/index.mjs
CHANGED
|
@@ -402,6 +402,7 @@ var BPTree = class {
|
|
|
402
402
|
root;
|
|
403
403
|
_nodeCreateBuffer;
|
|
404
404
|
_nodeUpdateBuffer;
|
|
405
|
+
_nodeDeleteBuffer;
|
|
405
406
|
verifierMap = {
|
|
406
407
|
gt: (nv, v) => this.comparator.isHigher(nv, v),
|
|
407
408
|
gte: (nv, v) => this.comparator.isHigher(nv, v) || this.comparator.isSame(nv, v),
|
|
@@ -450,6 +451,7 @@ var BPTree = class {
|
|
|
450
451
|
this._cachedRegexp = new CacheBranchSync();
|
|
451
452
|
this._nodeCreateBuffer = /* @__PURE__ */ new Map();
|
|
452
453
|
this._nodeUpdateBuffer = /* @__PURE__ */ new Map();
|
|
454
|
+
this._nodeDeleteBuffer = /* @__PURE__ */ new Map();
|
|
453
455
|
this.nodes = /* @__PURE__ */ new Map();
|
|
454
456
|
this.strategy = strategy;
|
|
455
457
|
this.comparator = comparator;
|
|
@@ -487,6 +489,9 @@ var BPTree = class {
|
|
|
487
489
|
bufferForNodeUpdate(node) {
|
|
488
490
|
this._nodeUpdateBuffer.set(node.id, node);
|
|
489
491
|
}
|
|
492
|
+
bufferForNodeDelete(node) {
|
|
493
|
+
this._nodeDeleteBuffer.set(node.id, node);
|
|
494
|
+
}
|
|
490
495
|
/**
|
|
491
496
|
* Returns the user-defined data stored in the head of the tree.
|
|
492
497
|
* This value can be set using the `setHeadData` method. If no data has been previously inserted, the default value is returned, and the default value is `{}`.
|
|
@@ -568,15 +573,15 @@ var BPTreeSync = class extends BPTree {
|
|
|
568
573
|
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
569
574
|
}
|
|
570
575
|
}
|
|
571
|
-
_createNodeId() {
|
|
572
|
-
const id = this.strategy.id();
|
|
576
|
+
_createNodeId(isLeaf) {
|
|
577
|
+
const id = this.strategy.id(isLeaf);
|
|
573
578
|
if (id === 0) {
|
|
574
579
|
throw new Error(`The node's id should never be 0.`);
|
|
575
580
|
}
|
|
576
581
|
return id;
|
|
577
582
|
}
|
|
578
|
-
_createNode(keys2, values, leaf = false, parent = 0, next = 0, prev = 0) {
|
|
579
|
-
const id = this._createNodeId();
|
|
583
|
+
_createNode(isLeaf, keys2, values, leaf = false, parent = 0, next = 0, prev = 0) {
|
|
584
|
+
const id = this._createNodeId(isLeaf);
|
|
580
585
|
const node = {
|
|
581
586
|
id,
|
|
582
587
|
keys: keys2,
|
|
@@ -610,6 +615,7 @@ var BPTreeSync = class extends BPTree {
|
|
|
610
615
|
}
|
|
611
616
|
if (this.root === node && node.keys.length === 1) {
|
|
612
617
|
const keys2 = node.keys;
|
|
618
|
+
this.bufferForNodeDelete(this.root);
|
|
613
619
|
this.root = this.getNode(keys2[0]);
|
|
614
620
|
this.root.parent = 0;
|
|
615
621
|
this.strategy.head.root = this.root.id;
|
|
@@ -693,6 +699,7 @@ var BPTreeSync = class extends BPTree {
|
|
|
693
699
|
}
|
|
694
700
|
this._deleteEntry(this.getNode(node.parent), node.id, guess);
|
|
695
701
|
this.bufferForNodeUpdate(pointer);
|
|
702
|
+
this.bufferForNodeDelete(node);
|
|
696
703
|
} else {
|
|
697
704
|
if (isPredecessor) {
|
|
698
705
|
let pointerPm;
|
|
@@ -789,7 +796,7 @@ var BPTreeSync = class extends BPTree {
|
|
|
789
796
|
}
|
|
790
797
|
_insertInParent(node, value, pointer) {
|
|
791
798
|
if (this.root === node) {
|
|
792
|
-
const root = this._createNode([node.id, pointer.id], [value]);
|
|
799
|
+
const root = this._createNode(false, [node.id, pointer.id], [value]);
|
|
793
800
|
this.root = root;
|
|
794
801
|
this.strategy.head.root = root.id;
|
|
795
802
|
node.parent = root.id;
|
|
@@ -807,7 +814,7 @@ var BPTreeSync = class extends BPTree {
|
|
|
807
814
|
parentNode.keys.splice(i + 1, 0, pointer.id);
|
|
808
815
|
this.bufferForNodeUpdate(parentNode);
|
|
809
816
|
if (parentNode.keys.length > this.order) {
|
|
810
|
-
const parentPointer = this._createNode([], []);
|
|
817
|
+
const parentPointer = this._createNode(false, [], []);
|
|
811
818
|
parentPointer.parent = parentNode.parent;
|
|
812
819
|
const mid = Math.ceil(this.order / 2) - 1;
|
|
813
820
|
parentPointer.values = parentNode.values.slice(mid + 1);
|
|
@@ -840,7 +847,7 @@ var BPTreeSync = class extends BPTree {
|
|
|
840
847
|
const head = this.strategy.readHead();
|
|
841
848
|
if (head === null) {
|
|
842
849
|
this.order = this.strategy.order;
|
|
843
|
-
this.root = this._createNode([], [], true);
|
|
850
|
+
this.root = this._createNode(true, [], [], true);
|
|
844
851
|
this.strategy.head.root = this.root.id;
|
|
845
852
|
this.bufferForNodeCreate(this.root);
|
|
846
853
|
this.commitHeadBuffer();
|
|
@@ -904,6 +911,12 @@ var BPTreeSync = class extends BPTree {
|
|
|
904
911
|
}
|
|
905
912
|
this._nodeUpdateBuffer.clear();
|
|
906
913
|
}
|
|
914
|
+
commitNodeDeleteBuffer() {
|
|
915
|
+
for (const node of this._nodeDeleteBuffer.values()) {
|
|
916
|
+
this.strategy.delete(node.id);
|
|
917
|
+
}
|
|
918
|
+
this._nodeDeleteBuffer.clear();
|
|
919
|
+
}
|
|
907
920
|
keys(condition, filterValues) {
|
|
908
921
|
for (const k in condition) {
|
|
909
922
|
const key = k;
|
|
@@ -956,6 +969,7 @@ var BPTreeSync = class extends BPTree {
|
|
|
956
969
|
this._insertAtLeaf(before, key, value);
|
|
957
970
|
if (before.values.length === this.order) {
|
|
958
971
|
const after = this._createNode(
|
|
972
|
+
true,
|
|
959
973
|
[],
|
|
960
974
|
[],
|
|
961
975
|
true,
|
|
@@ -1011,6 +1025,7 @@ var BPTreeSync = class extends BPTree {
|
|
|
1011
1025
|
this.commitHeadBuffer();
|
|
1012
1026
|
this.commitNodeCreateBuffer();
|
|
1013
1027
|
this.commitNodeUpdateBuffer();
|
|
1028
|
+
this.commitNodeDeleteBuffer();
|
|
1014
1029
|
}
|
|
1015
1030
|
exists(key, value) {
|
|
1016
1031
|
const node = this.insertableNode(value);
|
|
@@ -1109,15 +1124,15 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1109
1124
|
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
1110
1125
|
}
|
|
1111
1126
|
}
|
|
1112
|
-
async _createNodeId() {
|
|
1113
|
-
const id = await this.strategy.id();
|
|
1127
|
+
async _createNodeId(isLeaf) {
|
|
1128
|
+
const id = await this.strategy.id(isLeaf);
|
|
1114
1129
|
if (id === 0) {
|
|
1115
1130
|
throw new Error(`The node's id should never be 0.`);
|
|
1116
1131
|
}
|
|
1117
1132
|
return id;
|
|
1118
1133
|
}
|
|
1119
|
-
async _createNode(keys2, values, leaf = false, parent = 0, next = 0, prev = 0) {
|
|
1120
|
-
const id = await this._createNodeId();
|
|
1134
|
+
async _createNode(isLeaf, keys2, values, leaf = false, parent = 0, next = 0, prev = 0) {
|
|
1135
|
+
const id = await this._createNodeId(isLeaf);
|
|
1121
1136
|
const node = {
|
|
1122
1137
|
id,
|
|
1123
1138
|
keys: keys2,
|
|
@@ -1151,6 +1166,7 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1151
1166
|
}
|
|
1152
1167
|
if (this.root === node && node.keys.length === 1) {
|
|
1153
1168
|
const keys2 = node.keys;
|
|
1169
|
+
this.bufferForNodeDelete(this.root);
|
|
1154
1170
|
this.root = await this.getNode(keys2[0]);
|
|
1155
1171
|
this.root.parent = 0;
|
|
1156
1172
|
this.strategy.head.root = this.root.id;
|
|
@@ -1234,6 +1250,7 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1234
1250
|
}
|
|
1235
1251
|
await this._deleteEntry(await this.getNode(node.parent), node.id, guess);
|
|
1236
1252
|
this.bufferForNodeUpdate(pointer);
|
|
1253
|
+
this.bufferForNodeDelete(node);
|
|
1237
1254
|
} else {
|
|
1238
1255
|
if (isPredecessor) {
|
|
1239
1256
|
let pointerPm;
|
|
@@ -1330,7 +1347,7 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1330
1347
|
}
|
|
1331
1348
|
async _insertInParent(node, value, pointer) {
|
|
1332
1349
|
if (this.root === node) {
|
|
1333
|
-
const root = await this._createNode([node.id, pointer.id], [value]);
|
|
1350
|
+
const root = await this._createNode(false, [node.id, pointer.id], [value]);
|
|
1334
1351
|
this.root = root;
|
|
1335
1352
|
this.strategy.head.root = root.id;
|
|
1336
1353
|
node.parent = root.id;
|
|
@@ -1348,7 +1365,7 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1348
1365
|
parentNode.keys.splice(i + 1, 0, pointer.id);
|
|
1349
1366
|
this.bufferForNodeUpdate(parentNode);
|
|
1350
1367
|
if (parentNode.keys.length > this.order) {
|
|
1351
|
-
const parentPointer = await this._createNode([], []);
|
|
1368
|
+
const parentPointer = await this._createNode(false, [], []);
|
|
1352
1369
|
parentPointer.parent = parentNode.parent;
|
|
1353
1370
|
const mid = Math.ceil(this.order / 2) - 1;
|
|
1354
1371
|
parentPointer.values = parentNode.values.slice(mid + 1);
|
|
@@ -1381,7 +1398,7 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1381
1398
|
const head = await this.strategy.readHead();
|
|
1382
1399
|
if (head === null) {
|
|
1383
1400
|
this.order = this.strategy.order;
|
|
1384
|
-
this.root = await this._createNode([], [], true);
|
|
1401
|
+
this.root = await this._createNode(true, [], [], true);
|
|
1385
1402
|
this.strategy.head.root = this.root.id;
|
|
1386
1403
|
this.bufferForNodeCreate(this.root);
|
|
1387
1404
|
this.commitHeadBuffer();
|
|
@@ -1445,6 +1462,12 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1445
1462
|
}
|
|
1446
1463
|
this._nodeUpdateBuffer.clear();
|
|
1447
1464
|
}
|
|
1465
|
+
async commitNodeDeleteBuffer() {
|
|
1466
|
+
for (const node of this._nodeDeleteBuffer.values()) {
|
|
1467
|
+
await this.strategy.delete(node.id);
|
|
1468
|
+
}
|
|
1469
|
+
this._nodeDeleteBuffer.clear();
|
|
1470
|
+
}
|
|
1448
1471
|
async keys(condition, filterValues) {
|
|
1449
1472
|
for (const k in condition) {
|
|
1450
1473
|
const key = k;
|
|
@@ -1497,6 +1520,7 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1497
1520
|
this._insertAtLeaf(before, key, value);
|
|
1498
1521
|
if (before.values.length === this.order) {
|
|
1499
1522
|
const after = await this._createNode(
|
|
1523
|
+
true,
|
|
1500
1524
|
[],
|
|
1501
1525
|
[],
|
|
1502
1526
|
true,
|
|
@@ -1552,6 +1576,7 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1552
1576
|
await this.commitHeadBuffer();
|
|
1553
1577
|
await this.commitNodeCreateBuffer();
|
|
1554
1578
|
await this.commitNodeUpdateBuffer();
|
|
1579
|
+
await this.commitNodeDeleteBuffer();
|
|
1555
1580
|
}
|
|
1556
1581
|
async exists(key, value) {
|
|
1557
1582
|
const node = await this.insertableNode(value);
|
|
@@ -1618,7 +1643,7 @@ var InMemoryStoreStrategySync = class extends SerializeStrategySync {
|
|
|
1618
1643
|
super(order);
|
|
1619
1644
|
this.node = {};
|
|
1620
1645
|
}
|
|
1621
|
-
id() {
|
|
1646
|
+
id(isLeaf) {
|
|
1622
1647
|
return this.autoIncrement("index", 1);
|
|
1623
1648
|
}
|
|
1624
1649
|
read(id) {
|
|
@@ -1630,6 +1655,9 @@ var InMemoryStoreStrategySync = class extends SerializeStrategySync {
|
|
|
1630
1655
|
write(id, node) {
|
|
1631
1656
|
this.node[id] = node;
|
|
1632
1657
|
}
|
|
1658
|
+
delete(id) {
|
|
1659
|
+
delete this.node[id];
|
|
1660
|
+
}
|
|
1633
1661
|
readHead() {
|
|
1634
1662
|
if (this.head.root === 0) {
|
|
1635
1663
|
return null;
|
|
@@ -1666,7 +1694,7 @@ var InMemoryStoreStrategyAsync = class extends SerializeStrategyAsync {
|
|
|
1666
1694
|
super(order);
|
|
1667
1695
|
this.node = {};
|
|
1668
1696
|
}
|
|
1669
|
-
async id() {
|
|
1697
|
+
async id(isLeaf) {
|
|
1670
1698
|
return await this.autoIncrement("index", 1);
|
|
1671
1699
|
}
|
|
1672
1700
|
async read(id) {
|
|
@@ -1678,6 +1706,9 @@ var InMemoryStoreStrategyAsync = class extends SerializeStrategyAsync {
|
|
|
1678
1706
|
async write(id, node) {
|
|
1679
1707
|
this.node[id] = node;
|
|
1680
1708
|
}
|
|
1709
|
+
async delete(id) {
|
|
1710
|
+
delete this.node[id];
|
|
1711
|
+
}
|
|
1681
1712
|
async readHead() {
|
|
1682
1713
|
if (this.head.root === 0) {
|
|
1683
1714
|
return null;
|
|
@@ -8,8 +8,8 @@ export declare class BPTreeAsync<K, V> extends BPTree<K, V> {
|
|
|
8
8
|
protected _getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): Promise<BPTreePair<K, V>[]>;
|
|
9
9
|
protected _getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): Promise<BPTreePair<K, V>[]>;
|
|
10
10
|
protected getPairs(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean, direction: 1 | -1): Promise<BPTreePair<K, V>[]>;
|
|
11
|
-
protected _createNodeId(): Promise<number>;
|
|
12
|
-
protected _createNode(keys: number[] | K[][], values: V[], leaf?: boolean, parent?: number, next?: number, prev?: number): Promise<BPTreeUnknownNode<K, V>>;
|
|
11
|
+
protected _createNodeId(isLeaf: boolean): Promise<number>;
|
|
12
|
+
protected _createNode(isLeaf: boolean, keys: number[] | K[][], values: V[], leaf?: boolean, parent?: number, next?: number, prev?: number): Promise<BPTreeUnknownNode<K, V>>;
|
|
13
13
|
protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>, value: V): Promise<void>;
|
|
14
14
|
protected _insertInParent(node: BPTreeUnknownNode<K, V>, value: V, pointer: BPTreeUnknownNode<K, V>): Promise<void>;
|
|
15
15
|
init(): Promise<void>;
|
|
@@ -19,6 +19,7 @@ export declare class BPTreeAsync<K, V> extends BPTree<K, V> {
|
|
|
19
19
|
protected commitHeadBuffer(): Promise<void>;
|
|
20
20
|
protected commitNodeCreateBuffer(): Promise<void>;
|
|
21
21
|
protected commitNodeUpdateBuffer(): Promise<void>;
|
|
22
|
+
protected commitNodeDeleteBuffer(): Promise<void>;
|
|
22
23
|
keys(condition: BPTreeCondition<V>, filterValues?: Set<K>): Promise<Set<K>>;
|
|
23
24
|
where(condition: BPTreeCondition<V>): Promise<BPTreePair<K, V>[]>;
|
|
24
25
|
insert(key: K, value: V): Promise<void>;
|
|
@@ -8,8 +8,8 @@ export declare class BPTreeSync<K, V> extends BPTree<K, V> {
|
|
|
8
8
|
protected _getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): BPTreePair<K, V>[];
|
|
9
9
|
protected _getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): BPTreePair<K, V>[];
|
|
10
10
|
protected getPairs(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean, direction: 1 | -1): BPTreePair<K, V>[];
|
|
11
|
-
protected _createNodeId(): number;
|
|
12
|
-
protected _createNode(keys: number[] | K[][], values: V[], leaf?: boolean, parent?: number, next?: number, prev?: number): BPTreeUnknownNode<K, V>;
|
|
11
|
+
protected _createNodeId(isLeaf: boolean): number;
|
|
12
|
+
protected _createNode(isLeaf: boolean, keys: number[] | K[][], values: V[], leaf?: boolean, parent?: number, next?: number, prev?: number): BPTreeUnknownNode<K, V>;
|
|
13
13
|
protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>, value: V): void;
|
|
14
14
|
protected _insertInParent(node: BPTreeUnknownNode<K, V>, value: V, pointer: BPTreeUnknownNode<K, V>): void;
|
|
15
15
|
init(): void;
|
|
@@ -19,6 +19,7 @@ export declare class BPTreeSync<K, V> extends BPTree<K, V> {
|
|
|
19
19
|
protected commitHeadBuffer(): void;
|
|
20
20
|
protected commitNodeCreateBuffer(): void;
|
|
21
21
|
protected commitNodeUpdateBuffer(): void;
|
|
22
|
+
protected commitNodeDeleteBuffer(): void;
|
|
22
23
|
keys(condition: BPTreeCondition<V>, filterValues?: Set<K>): Set<K>;
|
|
23
24
|
where(condition: BPTreeCondition<V>): BPTreePair<K, V>[];
|
|
24
25
|
insert(key: K, value: V): void;
|
|
@@ -2,9 +2,10 @@ import { BPTreeNode } from './base/BPTree';
|
|
|
2
2
|
import { SerializeStrategy, SerializeStrategyHead } from './base/SerializeStrategy';
|
|
3
3
|
import { Json } from './utils/types';
|
|
4
4
|
export declare abstract class SerializeStrategyAsync<K, V> extends SerializeStrategy<K, V> {
|
|
5
|
-
abstract id(): Promise<number>;
|
|
5
|
+
abstract id(isLeaf: boolean): Promise<number>;
|
|
6
6
|
abstract read(id: number): Promise<BPTreeNode<K, V>>;
|
|
7
7
|
abstract write(id: number, node: BPTreeNode<K, V>): Promise<void>;
|
|
8
|
+
abstract delete(id: number): Promise<void>;
|
|
8
9
|
abstract readHead(): Promise<SerializeStrategyHead | null>;
|
|
9
10
|
abstract writeHead(head: SerializeStrategyHead): Promise<void>;
|
|
10
11
|
getHeadData(key: string, defaultValue: Json): Promise<Json>;
|
|
@@ -14,9 +15,10 @@ export declare abstract class SerializeStrategyAsync<K, V> extends SerializeStra
|
|
|
14
15
|
export declare class InMemoryStoreStrategyAsync<K, V> extends SerializeStrategyAsync<K, V> {
|
|
15
16
|
protected readonly node: Record<number, BPTreeNode<K, V>>;
|
|
16
17
|
constructor(order: number);
|
|
17
|
-
id(): Promise<number>;
|
|
18
|
+
id(isLeaf: boolean): Promise<number>;
|
|
18
19
|
read(id: number): Promise<BPTreeNode<K, V>>;
|
|
19
20
|
write(id: number, node: BPTreeNode<K, V>): Promise<void>;
|
|
21
|
+
delete(id: number): Promise<void>;
|
|
20
22
|
readHead(): Promise<SerializeStrategyHead | null>;
|
|
21
23
|
writeHead(head: SerializeStrategyHead): Promise<void>;
|
|
22
24
|
}
|
|
@@ -2,9 +2,10 @@ import { BPTreeNode } from './base/BPTree';
|
|
|
2
2
|
import { SerializeStrategy, SerializeStrategyHead } from './base/SerializeStrategy';
|
|
3
3
|
import { Json } from './utils/types';
|
|
4
4
|
export declare abstract class SerializeStrategySync<K, V> extends SerializeStrategy<K, V> {
|
|
5
|
-
abstract id(): number;
|
|
5
|
+
abstract id(isLeaf: boolean): number;
|
|
6
6
|
abstract read(id: number): BPTreeNode<K, V>;
|
|
7
7
|
abstract write(id: number, node: BPTreeNode<K, V>): void;
|
|
8
|
+
abstract delete(id: number): void;
|
|
8
9
|
abstract readHead(): SerializeStrategyHead | null;
|
|
9
10
|
abstract writeHead(head: SerializeStrategyHead): void;
|
|
10
11
|
getHeadData(key: string, defaultValue: Json): Json;
|
|
@@ -14,9 +15,10 @@ export declare abstract class SerializeStrategySync<K, V> extends SerializeStrat
|
|
|
14
15
|
export declare class InMemoryStoreStrategySync<K, V> extends SerializeStrategySync<K, V> {
|
|
15
16
|
protected readonly node: Record<number, BPTreeNode<K, V>>;
|
|
16
17
|
constructor(order: number);
|
|
17
|
-
id(): number;
|
|
18
|
+
id(isLeaf: boolean): number;
|
|
18
19
|
read(id: number): BPTreeNode<K, V>;
|
|
19
20
|
write(id: number, node: BPTreeNode<K, V>): void;
|
|
21
|
+
delete(id: number): void;
|
|
20
22
|
readHead(): SerializeStrategyHead | null;
|
|
21
23
|
writeHead(head: SerializeStrategyHead): void;
|
|
22
24
|
}
|
|
@@ -51,6 +51,7 @@ export declare abstract class BPTree<K, V> {
|
|
|
51
51
|
protected root: BPTreeUnknownNode<K, V>;
|
|
52
52
|
protected readonly _nodeCreateBuffer: Map<number, BPTreeUnknownNode<K, V>>;
|
|
53
53
|
protected readonly _nodeUpdateBuffer: Map<number, BPTreeUnknownNode<K, V>>;
|
|
54
|
+
protected readonly _nodeDeleteBuffer: Map<number, BPTreeUnknownNode<K, V>>;
|
|
54
55
|
protected readonly verifierMap: Record<keyof BPTreeCondition<V>, (nodeValue: V, value: V) => boolean>;
|
|
55
56
|
protected readonly verifierStartNode: Record<keyof BPTreeCondition<V>, (value: V) => Deferred<BPTreeLeafNode<K, V>>>;
|
|
56
57
|
protected readonly verifierDirection: Record<keyof BPTreeCondition<V>, -1 | 1>;
|
|
@@ -59,8 +60,8 @@ export declare abstract class BPTree<K, V> {
|
|
|
59
60
|
protected abstract _getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): Deferred<BPTreePair<K, V>[]>;
|
|
60
61
|
protected abstract _getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): Deferred<BPTreePair<K, V>[]>;
|
|
61
62
|
protected abstract getPairs(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean, direction: -1 | 1): Deferred<BPTreePair<K, V>[]>;
|
|
62
|
-
protected abstract _createNodeId(): Deferred<number>;
|
|
63
|
-
protected abstract _createNode(keys: number[] | K[][], values: V[], leaf?: boolean, parent?: number, next?: number, prev?: number): Deferred<BPTreeUnknownNode<K, V>>;
|
|
63
|
+
protected abstract _createNodeId(isLeaf: boolean): Deferred<number>;
|
|
64
|
+
protected abstract _createNode(isLeaf: boolean, keys: number[] | K[][], values: V[], leaf?: boolean, parent?: number, next?: number, prev?: number): Deferred<BPTreeUnknownNode<K, V>>;
|
|
64
65
|
protected abstract _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>, value: V): Deferred<void>;
|
|
65
66
|
protected abstract _insertInParent(node: BPTreeUnknownNode<K, V>, value: V, pointer: BPTreeUnknownNode<K, V>): Deferred<void>;
|
|
66
67
|
protected abstract getNode(id: number): Deferred<BPTreeUnknownNode<K, V>>;
|
|
@@ -124,8 +125,9 @@ export declare abstract class BPTree<K, V> {
|
|
|
124
125
|
*/
|
|
125
126
|
abstract forceUpdate(): Deferred<number>;
|
|
126
127
|
protected _insertAtLeaf(node: BPTreeLeafNode<K, V>, key: K, value: V): void;
|
|
127
|
-
protected bufferForNodeCreate(node: BPTreeUnknownNode<K, V>):
|
|
128
|
-
protected bufferForNodeUpdate(node: BPTreeUnknownNode<K, V>):
|
|
128
|
+
protected bufferForNodeCreate(node: BPTreeUnknownNode<K, V>): void;
|
|
129
|
+
protected bufferForNodeUpdate(node: BPTreeUnknownNode<K, V>): void;
|
|
130
|
+
protected bufferForNodeDelete(node: BPTreeUnknownNode<K, V>): void;
|
|
129
131
|
/**
|
|
130
132
|
* Returns the user-defined data stored in the head of the tree.
|
|
131
133
|
* This value can be set using the `setHeadData` method. If no data has been previously inserted, the default value is returned, and the default value is `{}`.
|
|
@@ -15,8 +15,9 @@ export declare abstract class SerializeStrategy<K, V> {
|
|
|
15
15
|
* When a new node is created within the tree, the value returned by this method becomes the node's ID.
|
|
16
16
|
*
|
|
17
17
|
* **WARNING!** The return value should never be `0`.
|
|
18
|
+
* @param isLeaf This is a flag that indicates whether the node is a leaf node or not.
|
|
18
19
|
*/
|
|
19
|
-
abstract id(): number | Promise<number>;
|
|
20
|
+
abstract id(isLeaf: boolean): number | Promise<number>;
|
|
20
21
|
/**
|
|
21
22
|
* Read the stored node from the ID.
|
|
22
23
|
* The JSON object of the read node should be returned.
|
|
@@ -30,6 +31,12 @@ export declare abstract class SerializeStrategy<K, V> {
|
|
|
30
31
|
* @param node This is the JSON object of the node to be stored.
|
|
31
32
|
*/
|
|
32
33
|
abstract write(id: number, node: BPTreeNode<K, V>): void | Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* This method is called when previously created nodes become no longer needed due to deletion or other processes.
|
|
36
|
+
* It can be used to free up space by deleting existing stored nodes.
|
|
37
|
+
* @param id This is the ID of the node to be deleted.
|
|
38
|
+
*/
|
|
39
|
+
abstract delete(id: number): void | Promise<void>;
|
|
33
40
|
/**
|
|
34
41
|
* It is called when the `init` method of the tree instance is called.
|
|
35
42
|
* This method should return the information needed to initialize the tree. This information refers to the values stored in the `writeHead` method.
|