serializable-bptree 5.0.5 → 5.1.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 +41 -1
- package/dist/cjs/index.cjs +123 -47
- package/dist/esm/index.mjs +123 -47
- package/dist/types/BPTreeAsync.d.ts +5 -3
- package/dist/types/BPTreeSync.d.ts +5 -3
- package/dist/types/base/BPTree.d.ts +12 -5
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -63,6 +63,7 @@ tree.where({ equal: 1 }) // Map([{ key: 'a', value: 1 }])
|
|
|
63
63
|
tree.where({ gt: 1 }) // Map([{ key: 'c', value: 3 }])
|
|
64
64
|
tree.where({ lt: 2 }) // Map([{ key: 'a', value: 1 }])
|
|
65
65
|
tree.where({ gt: 0, lt: 4 }) // Map([{ key: 'a', value: 1 }, { key: 'c', value: 3 }])
|
|
66
|
+
tree.where({ or: [3, 1] }) // Map([{ key: 'a', value: 1 }, { key: 'c', value: 3 }])
|
|
66
67
|
```
|
|
67
68
|
|
|
68
69
|
## Why use a `serializable-bptree`?
|
|
@@ -320,32 +321,64 @@ import {
|
|
|
320
321
|
|
|
321
322
|
## Data Query Condition Clause
|
|
322
323
|
|
|
323
|
-
This library supports various conditional clauses. Currently, it supports **gte**, **gt**, **lte**, **lt**, **equal**, **notEqual**, and **like** conditions. Each condition is as follows:
|
|
324
|
+
This library supports various conditional clauses. Currently, it supports **gte**, **gt**, **lte**, **lt**, **equal**, **notEqual**, **or**, and **like** conditions. Each condition is as follows:
|
|
324
325
|
|
|
325
326
|
### `gte`
|
|
326
327
|
|
|
327
328
|
Queries values that are greater than or equal to the given value.
|
|
328
329
|
|
|
330
|
+
```typescript
|
|
331
|
+
tree.where({ gte: 1 })
|
|
332
|
+
```
|
|
333
|
+
|
|
329
334
|
### `gt`
|
|
330
335
|
|
|
331
336
|
Queries values that are greater than the given value.
|
|
332
337
|
|
|
338
|
+
```typescript
|
|
339
|
+
tree.where({ gt: 1 })
|
|
340
|
+
```
|
|
341
|
+
|
|
333
342
|
### `lte`
|
|
334
343
|
|
|
335
344
|
Queries values that are less than or equal to the given value.
|
|
336
345
|
|
|
346
|
+
```typescript
|
|
347
|
+
tree.where({ lte: 5 })
|
|
348
|
+
```
|
|
349
|
+
|
|
337
350
|
### `lt`
|
|
338
351
|
|
|
339
352
|
Queries values that are less than the given value.
|
|
340
353
|
|
|
354
|
+
```typescript
|
|
355
|
+
tree.where({ lt: 5 })
|
|
356
|
+
```
|
|
357
|
+
|
|
341
358
|
### `equal`
|
|
342
359
|
|
|
343
360
|
Queries values that match the given value.
|
|
344
361
|
|
|
362
|
+
```typescript
|
|
363
|
+
tree.where({ equal: 3 })
|
|
364
|
+
```
|
|
365
|
+
|
|
345
366
|
### `notEqual`
|
|
346
367
|
|
|
347
368
|
Queries values that do not match the given value.
|
|
348
369
|
|
|
370
|
+
```typescript
|
|
371
|
+
tree.where({ notEqual: 3 })
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### `or`
|
|
375
|
+
|
|
376
|
+
Queries values that satisfy at least one of the given conditions. It accepts an array of conditions, and if any of these conditions are met, the data is included in the result.
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
tree.where({ or: [1, 2, 3] })
|
|
380
|
+
```
|
|
381
|
+
|
|
349
382
|
### `like`
|
|
350
383
|
|
|
351
384
|
Queries values that contain the given value in a manner similar to regular expressions. Special characters such as % and _ can be used.
|
|
@@ -357,6 +390,13 @@ Using **p_t**, it can match any string where the underscore is replaced by any c
|
|
|
357
390
|
|
|
358
391
|
You can obtain matching data by combining these condition clauses. If there are multiple conditions, an **AND** operation is used to retrieve only the data that satisfies all conditions.
|
|
359
392
|
|
|
393
|
+
```typescript
|
|
394
|
+
tree.where({ like: 'hello%' })
|
|
395
|
+
tree.where({ like: 'he__o%' })
|
|
396
|
+
tree.where({ like: '%world!' })
|
|
397
|
+
tree.where({ like: '%lo, wor%' })
|
|
398
|
+
```
|
|
399
|
+
|
|
360
400
|
## Using Asynchronously
|
|
361
401
|
|
|
362
402
|
Support for asynchronous trees has been available since version 3.0.0. Asynchronous is useful for operations with delays, such as file input/output and remote storage. Here is an example of how to use it:
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -120,6 +120,7 @@ var BPTree = class {
|
|
|
120
120
|
lte: (nv, v) => this.comparator.isLower(nv, v) || this.comparator.isSame(nv, v),
|
|
121
121
|
equal: (nv, v) => this.comparator.isSame(nv, v),
|
|
122
122
|
notEqual: (nv, v) => this.comparator.isSame(nv, v) === false,
|
|
123
|
+
or: (nv, v) => this.ensureValues(v).some((v2) => this.comparator.isSame(nv, v2)),
|
|
123
124
|
like: (nv, v) => {
|
|
124
125
|
const nodeValue = this.comparator.match(nv);
|
|
125
126
|
const value = this.comparator.match(v);
|
|
@@ -139,8 +140,22 @@ var BPTree = class {
|
|
|
139
140
|
lte: (v) => this.insertableNode(v),
|
|
140
141
|
equal: (v) => this.insertableNode(v),
|
|
141
142
|
notEqual: (v) => this.leftestNode(),
|
|
143
|
+
or: (v) => this.insertableNode(this.lowestValue(this.ensureValues(v))),
|
|
142
144
|
like: (v) => this.leftestNode()
|
|
143
145
|
};
|
|
146
|
+
verifierEndNode = {
|
|
147
|
+
gt: (v) => null,
|
|
148
|
+
gte: (v) => null,
|
|
149
|
+
lt: (v) => null,
|
|
150
|
+
lte: (v) => null,
|
|
151
|
+
equal: (v) => this.insertableEndNode(v, this.verifierDirection.equal),
|
|
152
|
+
notEqual: (v) => null,
|
|
153
|
+
or: (v) => this.insertableEndNode(
|
|
154
|
+
this.highestValue(this.ensureValues(v)),
|
|
155
|
+
this.verifierDirection.or
|
|
156
|
+
),
|
|
157
|
+
like: (v) => null
|
|
158
|
+
};
|
|
144
159
|
verifierDirection = {
|
|
145
160
|
gt: 1,
|
|
146
161
|
gte: 1,
|
|
@@ -148,17 +163,9 @@ var BPTree = class {
|
|
|
148
163
|
lte: -1,
|
|
149
164
|
equal: 1,
|
|
150
165
|
notEqual: 1,
|
|
166
|
+
or: 1,
|
|
151
167
|
like: 1
|
|
152
168
|
};
|
|
153
|
-
verifierFullScan = {
|
|
154
|
-
gt: false,
|
|
155
|
-
gte: false,
|
|
156
|
-
lt: false,
|
|
157
|
-
lte: false,
|
|
158
|
-
equal: false,
|
|
159
|
-
notEqual: true,
|
|
160
|
-
like: true
|
|
161
|
-
};
|
|
162
169
|
constructor(strategy, comparator) {
|
|
163
170
|
this._strategyDirty = false;
|
|
164
171
|
this._cachedRegexp = new InvertedWeakMap();
|
|
@@ -169,12 +176,31 @@ var BPTree = class {
|
|
|
169
176
|
this.strategy = strategy;
|
|
170
177
|
this.comparator = comparator;
|
|
171
178
|
}
|
|
179
|
+
ensureValues(v) {
|
|
180
|
+
if (!Array.isArray(v)) {
|
|
181
|
+
v = [v];
|
|
182
|
+
}
|
|
183
|
+
return v;
|
|
184
|
+
}
|
|
185
|
+
lowestValue(v) {
|
|
186
|
+
const i = 0;
|
|
187
|
+
return [...v].sort((a, b) => this.comparator.asc(a, b))[i];
|
|
188
|
+
}
|
|
189
|
+
highestValue(v) {
|
|
190
|
+
const i = v.length - 1;
|
|
191
|
+
return [...v].sort((a, b) => this.comparator.asc(a, b))[i];
|
|
192
|
+
}
|
|
172
193
|
_insertAtLeaf(node, key, value) {
|
|
173
194
|
if (node.values.length) {
|
|
174
195
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
175
196
|
const nValue = node.values[i];
|
|
176
197
|
if (this.comparator.isSame(value, nValue)) {
|
|
177
198
|
const keys = node.keys[i];
|
|
199
|
+
if (keys.includes(key)) {
|
|
200
|
+
throw new Error("The key already exists.", {
|
|
201
|
+
cause: { key, value }
|
|
202
|
+
});
|
|
203
|
+
}
|
|
178
204
|
keys.push(key);
|
|
179
205
|
this.bufferForNodeUpdate(node);
|
|
180
206
|
break;
|
|
@@ -229,25 +255,24 @@ var BPTreeSync = class extends BPTree {
|
|
|
229
255
|
constructor(strategy, comparator) {
|
|
230
256
|
super(strategy, comparator);
|
|
231
257
|
}
|
|
232
|
-
getPairsRightToLeft(value, startNode,
|
|
258
|
+
getPairsRightToLeft(value, startNode, endNode, comparator) {
|
|
233
259
|
const pairs = [];
|
|
234
260
|
let node = startNode;
|
|
235
261
|
let done = false;
|
|
236
|
-
let found = false;
|
|
237
262
|
while (!done) {
|
|
263
|
+
if (endNode && node.id === endNode.id) {
|
|
264
|
+
done = true;
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
238
267
|
let i = node.values.length;
|
|
239
268
|
while (i--) {
|
|
240
269
|
const nValue = node.values[i];
|
|
241
270
|
const keys = node.keys[i];
|
|
242
271
|
if (comparator(nValue, value)) {
|
|
243
|
-
found = true;
|
|
244
272
|
let j = keys.length;
|
|
245
273
|
while (j--) {
|
|
246
274
|
pairs.push([keys[j], nValue]);
|
|
247
275
|
}
|
|
248
|
-
} else if (found && !fullScan) {
|
|
249
|
-
done = true;
|
|
250
|
-
break;
|
|
251
276
|
}
|
|
252
277
|
}
|
|
253
278
|
if (!node.prev) {
|
|
@@ -258,24 +283,23 @@ var BPTreeSync = class extends BPTree {
|
|
|
258
283
|
}
|
|
259
284
|
return new Map(pairs.reverse());
|
|
260
285
|
}
|
|
261
|
-
getPairsLeftToRight(value, startNode,
|
|
286
|
+
getPairsLeftToRight(value, startNode, endNode, comparator) {
|
|
262
287
|
const pairs = [];
|
|
263
288
|
let node = startNode;
|
|
264
289
|
let done = false;
|
|
265
|
-
let found = false;
|
|
266
290
|
while (!done) {
|
|
291
|
+
if (endNode && node.id === endNode.id) {
|
|
292
|
+
done = true;
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
267
295
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
268
296
|
const nValue = node.values[i];
|
|
269
297
|
const keys = node.keys[i];
|
|
270
298
|
if (comparator(nValue, value)) {
|
|
271
|
-
found = true;
|
|
272
299
|
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
273
300
|
const key = keys[j];
|
|
274
301
|
pairs.push([key, nValue]);
|
|
275
302
|
}
|
|
276
|
-
} else if (found && !fullScan) {
|
|
277
|
-
done = true;
|
|
278
|
-
break;
|
|
279
303
|
}
|
|
280
304
|
}
|
|
281
305
|
if (!node.next) {
|
|
@@ -286,12 +310,12 @@ var BPTreeSync = class extends BPTree {
|
|
|
286
310
|
}
|
|
287
311
|
return new Map(pairs);
|
|
288
312
|
}
|
|
289
|
-
getPairs(value, startNode,
|
|
313
|
+
getPairs(value, startNode, endNode, comparator, direction) {
|
|
290
314
|
switch (direction) {
|
|
291
315
|
case -1:
|
|
292
|
-
return this.getPairsRightToLeft(value, startNode,
|
|
316
|
+
return this.getPairsRightToLeft(value, startNode, endNode, comparator);
|
|
293
317
|
case 1:
|
|
294
|
-
return this.getPairsLeftToRight(value, startNode,
|
|
318
|
+
return this.getPairsLeftToRight(value, startNode, endNode, comparator);
|
|
295
319
|
default:
|
|
296
320
|
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
297
321
|
}
|
|
@@ -615,6 +639,25 @@ var BPTreeSync = class extends BPTree {
|
|
|
615
639
|
}
|
|
616
640
|
return node;
|
|
617
641
|
}
|
|
642
|
+
insertableEndNode(value, direction) {
|
|
643
|
+
const insertableNode = this.insertableNode(value);
|
|
644
|
+
let key;
|
|
645
|
+
switch (direction) {
|
|
646
|
+
case -1:
|
|
647
|
+
key = "prev";
|
|
648
|
+
break;
|
|
649
|
+
case 1:
|
|
650
|
+
key = "next";
|
|
651
|
+
break;
|
|
652
|
+
default:
|
|
653
|
+
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
654
|
+
}
|
|
655
|
+
const guessNode = insertableNode[key];
|
|
656
|
+
if (!guessNode) {
|
|
657
|
+
return null;
|
|
658
|
+
}
|
|
659
|
+
return this.getNode(guessNode);
|
|
660
|
+
}
|
|
618
661
|
leftestNode() {
|
|
619
662
|
let node = this.root;
|
|
620
663
|
while (!node.leaf) {
|
|
@@ -623,6 +666,14 @@ var BPTreeSync = class extends BPTree {
|
|
|
623
666
|
}
|
|
624
667
|
return node;
|
|
625
668
|
}
|
|
669
|
+
rightestNode() {
|
|
670
|
+
let node = this.root;
|
|
671
|
+
while (!node.leaf) {
|
|
672
|
+
const keys = node.keys;
|
|
673
|
+
node = this.getNode(keys[keys.length - 1]);
|
|
674
|
+
}
|
|
675
|
+
return node;
|
|
676
|
+
}
|
|
626
677
|
commitHeadBuffer() {
|
|
627
678
|
if (!this._strategyDirty) {
|
|
628
679
|
return;
|
|
@@ -653,10 +704,10 @@ var BPTreeSync = class extends BPTree {
|
|
|
653
704
|
const key = k;
|
|
654
705
|
const value = condition[key];
|
|
655
706
|
const startNode = this.verifierStartNode[key](value);
|
|
707
|
+
const endNode = this.verifierEndNode[key](value);
|
|
656
708
|
const direction = this.verifierDirection[key];
|
|
657
|
-
const fullScan = this.verifierFullScan[key];
|
|
658
709
|
const comparator = this.verifierMap[key];
|
|
659
|
-
const pairs = this.getPairs(value, startNode,
|
|
710
|
+
const pairs = this.getPairs(value, startNode, endNode, comparator, direction);
|
|
660
711
|
if (!filterValues) {
|
|
661
712
|
filterValues = new Set(pairs.keys());
|
|
662
713
|
} else {
|
|
@@ -678,10 +729,10 @@ var BPTreeSync = class extends BPTree {
|
|
|
678
729
|
const key = k;
|
|
679
730
|
const value = condition[key];
|
|
680
731
|
const startNode = this.verifierStartNode[key](value);
|
|
732
|
+
const endNode = this.verifierEndNode[key](value);
|
|
681
733
|
const direction = this.verifierDirection[key];
|
|
682
|
-
const fullScan = this.verifierFullScan[key];
|
|
683
734
|
const comparator = this.verifierMap[key];
|
|
684
|
-
const pairs = this.getPairs(value, startNode,
|
|
735
|
+
const pairs = this.getPairs(value, startNode, endNode, comparator, direction);
|
|
685
736
|
if (result === null) {
|
|
686
737
|
result = pairs;
|
|
687
738
|
} else {
|
|
@@ -791,25 +842,24 @@ var BPTreeAsync = class extends BPTree {
|
|
|
791
842
|
constructor(strategy, comparator) {
|
|
792
843
|
super(strategy, comparator);
|
|
793
844
|
}
|
|
794
|
-
async getPairsRightToLeft(value, startNode,
|
|
845
|
+
async getPairsRightToLeft(value, startNode, endNode, comparator) {
|
|
795
846
|
const pairs = [];
|
|
796
847
|
let node = startNode;
|
|
797
848
|
let done = false;
|
|
798
|
-
let found = false;
|
|
799
849
|
while (!done) {
|
|
850
|
+
if (endNode && node.id === endNode.id) {
|
|
851
|
+
done = true;
|
|
852
|
+
break;
|
|
853
|
+
}
|
|
800
854
|
let i = node.values.length;
|
|
801
855
|
while (i--) {
|
|
802
856
|
const nValue = node.values[i];
|
|
803
857
|
const keys = node.keys[i];
|
|
804
858
|
if (comparator(nValue, value)) {
|
|
805
|
-
found = true;
|
|
806
859
|
let j = keys.length;
|
|
807
860
|
while (j--) {
|
|
808
861
|
pairs.push([keys[j], nValue]);
|
|
809
862
|
}
|
|
810
|
-
} else if (found && !fullScan) {
|
|
811
|
-
done = true;
|
|
812
|
-
break;
|
|
813
863
|
}
|
|
814
864
|
}
|
|
815
865
|
if (!node.prev) {
|
|
@@ -820,24 +870,23 @@ var BPTreeAsync = class extends BPTree {
|
|
|
820
870
|
}
|
|
821
871
|
return new Map(pairs.reverse());
|
|
822
872
|
}
|
|
823
|
-
async getPairsLeftToRight(value, startNode,
|
|
873
|
+
async getPairsLeftToRight(value, startNode, endNode, comparator) {
|
|
824
874
|
const pairs = [];
|
|
825
875
|
let node = startNode;
|
|
826
876
|
let done = false;
|
|
827
|
-
let found = false;
|
|
828
877
|
while (!done) {
|
|
878
|
+
if (endNode && node.id === endNode.id) {
|
|
879
|
+
done = true;
|
|
880
|
+
break;
|
|
881
|
+
}
|
|
829
882
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
830
883
|
const nValue = node.values[i];
|
|
831
884
|
const keys = node.keys[i];
|
|
832
885
|
if (comparator(nValue, value)) {
|
|
833
|
-
found = true;
|
|
834
886
|
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
835
887
|
const key = keys[j];
|
|
836
888
|
pairs.push([key, nValue]);
|
|
837
889
|
}
|
|
838
|
-
} else if (found && !fullScan) {
|
|
839
|
-
done = true;
|
|
840
|
-
break;
|
|
841
890
|
}
|
|
842
891
|
}
|
|
843
892
|
if (!node.next) {
|
|
@@ -848,12 +897,12 @@ var BPTreeAsync = class extends BPTree {
|
|
|
848
897
|
}
|
|
849
898
|
return new Map(pairs);
|
|
850
899
|
}
|
|
851
|
-
async getPairs(value, startNode,
|
|
900
|
+
async getPairs(value, startNode, endNode, comparator, direction) {
|
|
852
901
|
switch (direction) {
|
|
853
902
|
case -1:
|
|
854
|
-
return await this.getPairsRightToLeft(value, startNode,
|
|
903
|
+
return await this.getPairsRightToLeft(value, startNode, endNode, comparator);
|
|
855
904
|
case 1:
|
|
856
|
-
return await this.getPairsLeftToRight(value, startNode,
|
|
905
|
+
return await this.getPairsLeftToRight(value, startNode, endNode, comparator);
|
|
857
906
|
default:
|
|
858
907
|
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
859
908
|
}
|
|
@@ -1177,6 +1226,25 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1177
1226
|
}
|
|
1178
1227
|
return node;
|
|
1179
1228
|
}
|
|
1229
|
+
async insertableEndNode(value, direction) {
|
|
1230
|
+
const insertableNode = await this.insertableNode(value);
|
|
1231
|
+
let key;
|
|
1232
|
+
switch (direction) {
|
|
1233
|
+
case -1:
|
|
1234
|
+
key = "prev";
|
|
1235
|
+
break;
|
|
1236
|
+
case 1:
|
|
1237
|
+
key = "next";
|
|
1238
|
+
break;
|
|
1239
|
+
default:
|
|
1240
|
+
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
1241
|
+
}
|
|
1242
|
+
const guessNode = insertableNode[key];
|
|
1243
|
+
if (!guessNode) {
|
|
1244
|
+
return null;
|
|
1245
|
+
}
|
|
1246
|
+
return await this.getNode(guessNode);
|
|
1247
|
+
}
|
|
1180
1248
|
async leftestNode() {
|
|
1181
1249
|
let node = this.root;
|
|
1182
1250
|
while (!node.leaf) {
|
|
@@ -1185,6 +1253,14 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1185
1253
|
}
|
|
1186
1254
|
return node;
|
|
1187
1255
|
}
|
|
1256
|
+
async rightestNode() {
|
|
1257
|
+
let node = this.root;
|
|
1258
|
+
while (!node.leaf) {
|
|
1259
|
+
const keys = node.keys;
|
|
1260
|
+
node = await this.getNode(keys[keys.length - 1]);
|
|
1261
|
+
}
|
|
1262
|
+
return node;
|
|
1263
|
+
}
|
|
1188
1264
|
async commitHeadBuffer() {
|
|
1189
1265
|
if (!this._strategyDirty) {
|
|
1190
1266
|
return;
|
|
@@ -1215,10 +1291,10 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1215
1291
|
const key = k;
|
|
1216
1292
|
const value = condition[key];
|
|
1217
1293
|
const startNode = await this.verifierStartNode[key](value);
|
|
1294
|
+
const endNode = await this.verifierEndNode[key](value);
|
|
1218
1295
|
const direction = this.verifierDirection[key];
|
|
1219
|
-
const fullScan = this.verifierFullScan[key];
|
|
1220
1296
|
const comparator = this.verifierMap[key];
|
|
1221
|
-
const pairs = await this.getPairs(value, startNode,
|
|
1297
|
+
const pairs = await this.getPairs(value, startNode, endNode, comparator, direction);
|
|
1222
1298
|
if (!filterValues) {
|
|
1223
1299
|
filterValues = new Set(pairs.keys());
|
|
1224
1300
|
} else {
|
|
@@ -1240,10 +1316,10 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1240
1316
|
const key = k;
|
|
1241
1317
|
const value = condition[key];
|
|
1242
1318
|
const startNode = await this.verifierStartNode[key](value);
|
|
1319
|
+
const endNode = await this.verifierEndNode[key](value);
|
|
1243
1320
|
const direction = this.verifierDirection[key];
|
|
1244
|
-
const fullScan = this.verifierFullScan[key];
|
|
1245
1321
|
const comparator = this.verifierMap[key];
|
|
1246
|
-
const pairs = await this.getPairs(value, startNode,
|
|
1322
|
+
const pairs = await this.getPairs(value, startNode, endNode, comparator, direction);
|
|
1247
1323
|
if (result === null) {
|
|
1248
1324
|
result = pairs;
|
|
1249
1325
|
} else {
|
package/dist/esm/index.mjs
CHANGED
|
@@ -86,6 +86,7 @@ var BPTree = class {
|
|
|
86
86
|
lte: (nv, v) => this.comparator.isLower(nv, v) || this.comparator.isSame(nv, v),
|
|
87
87
|
equal: (nv, v) => this.comparator.isSame(nv, v),
|
|
88
88
|
notEqual: (nv, v) => this.comparator.isSame(nv, v) === false,
|
|
89
|
+
or: (nv, v) => this.ensureValues(v).some((v2) => this.comparator.isSame(nv, v2)),
|
|
89
90
|
like: (nv, v) => {
|
|
90
91
|
const nodeValue = this.comparator.match(nv);
|
|
91
92
|
const value = this.comparator.match(v);
|
|
@@ -105,8 +106,22 @@ var BPTree = class {
|
|
|
105
106
|
lte: (v) => this.insertableNode(v),
|
|
106
107
|
equal: (v) => this.insertableNode(v),
|
|
107
108
|
notEqual: (v) => this.leftestNode(),
|
|
109
|
+
or: (v) => this.insertableNode(this.lowestValue(this.ensureValues(v))),
|
|
108
110
|
like: (v) => this.leftestNode()
|
|
109
111
|
};
|
|
112
|
+
verifierEndNode = {
|
|
113
|
+
gt: (v) => null,
|
|
114
|
+
gte: (v) => null,
|
|
115
|
+
lt: (v) => null,
|
|
116
|
+
lte: (v) => null,
|
|
117
|
+
equal: (v) => this.insertableEndNode(v, this.verifierDirection.equal),
|
|
118
|
+
notEqual: (v) => null,
|
|
119
|
+
or: (v) => this.insertableEndNode(
|
|
120
|
+
this.highestValue(this.ensureValues(v)),
|
|
121
|
+
this.verifierDirection.or
|
|
122
|
+
),
|
|
123
|
+
like: (v) => null
|
|
124
|
+
};
|
|
110
125
|
verifierDirection = {
|
|
111
126
|
gt: 1,
|
|
112
127
|
gte: 1,
|
|
@@ -114,17 +129,9 @@ var BPTree = class {
|
|
|
114
129
|
lte: -1,
|
|
115
130
|
equal: 1,
|
|
116
131
|
notEqual: 1,
|
|
132
|
+
or: 1,
|
|
117
133
|
like: 1
|
|
118
134
|
};
|
|
119
|
-
verifierFullScan = {
|
|
120
|
-
gt: false,
|
|
121
|
-
gte: false,
|
|
122
|
-
lt: false,
|
|
123
|
-
lte: false,
|
|
124
|
-
equal: false,
|
|
125
|
-
notEqual: true,
|
|
126
|
-
like: true
|
|
127
|
-
};
|
|
128
135
|
constructor(strategy, comparator) {
|
|
129
136
|
this._strategyDirty = false;
|
|
130
137
|
this._cachedRegexp = new InvertedWeakMap();
|
|
@@ -135,12 +142,31 @@ var BPTree = class {
|
|
|
135
142
|
this.strategy = strategy;
|
|
136
143
|
this.comparator = comparator;
|
|
137
144
|
}
|
|
145
|
+
ensureValues(v) {
|
|
146
|
+
if (!Array.isArray(v)) {
|
|
147
|
+
v = [v];
|
|
148
|
+
}
|
|
149
|
+
return v;
|
|
150
|
+
}
|
|
151
|
+
lowestValue(v) {
|
|
152
|
+
const i = 0;
|
|
153
|
+
return [...v].sort((a, b) => this.comparator.asc(a, b))[i];
|
|
154
|
+
}
|
|
155
|
+
highestValue(v) {
|
|
156
|
+
const i = v.length - 1;
|
|
157
|
+
return [...v].sort((a, b) => this.comparator.asc(a, b))[i];
|
|
158
|
+
}
|
|
138
159
|
_insertAtLeaf(node, key, value) {
|
|
139
160
|
if (node.values.length) {
|
|
140
161
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
141
162
|
const nValue = node.values[i];
|
|
142
163
|
if (this.comparator.isSame(value, nValue)) {
|
|
143
164
|
const keys = node.keys[i];
|
|
165
|
+
if (keys.includes(key)) {
|
|
166
|
+
throw new Error("The key already exists.", {
|
|
167
|
+
cause: { key, value }
|
|
168
|
+
});
|
|
169
|
+
}
|
|
144
170
|
keys.push(key);
|
|
145
171
|
this.bufferForNodeUpdate(node);
|
|
146
172
|
break;
|
|
@@ -195,25 +221,24 @@ var BPTreeSync = class extends BPTree {
|
|
|
195
221
|
constructor(strategy, comparator) {
|
|
196
222
|
super(strategy, comparator);
|
|
197
223
|
}
|
|
198
|
-
getPairsRightToLeft(value, startNode,
|
|
224
|
+
getPairsRightToLeft(value, startNode, endNode, comparator) {
|
|
199
225
|
const pairs = [];
|
|
200
226
|
let node = startNode;
|
|
201
227
|
let done = false;
|
|
202
|
-
let found = false;
|
|
203
228
|
while (!done) {
|
|
229
|
+
if (endNode && node.id === endNode.id) {
|
|
230
|
+
done = true;
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
204
233
|
let i = node.values.length;
|
|
205
234
|
while (i--) {
|
|
206
235
|
const nValue = node.values[i];
|
|
207
236
|
const keys = node.keys[i];
|
|
208
237
|
if (comparator(nValue, value)) {
|
|
209
|
-
found = true;
|
|
210
238
|
let j = keys.length;
|
|
211
239
|
while (j--) {
|
|
212
240
|
pairs.push([keys[j], nValue]);
|
|
213
241
|
}
|
|
214
|
-
} else if (found && !fullScan) {
|
|
215
|
-
done = true;
|
|
216
|
-
break;
|
|
217
242
|
}
|
|
218
243
|
}
|
|
219
244
|
if (!node.prev) {
|
|
@@ -224,24 +249,23 @@ var BPTreeSync = class extends BPTree {
|
|
|
224
249
|
}
|
|
225
250
|
return new Map(pairs.reverse());
|
|
226
251
|
}
|
|
227
|
-
getPairsLeftToRight(value, startNode,
|
|
252
|
+
getPairsLeftToRight(value, startNode, endNode, comparator) {
|
|
228
253
|
const pairs = [];
|
|
229
254
|
let node = startNode;
|
|
230
255
|
let done = false;
|
|
231
|
-
let found = false;
|
|
232
256
|
while (!done) {
|
|
257
|
+
if (endNode && node.id === endNode.id) {
|
|
258
|
+
done = true;
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
233
261
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
234
262
|
const nValue = node.values[i];
|
|
235
263
|
const keys = node.keys[i];
|
|
236
264
|
if (comparator(nValue, value)) {
|
|
237
|
-
found = true;
|
|
238
265
|
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
239
266
|
const key = keys[j];
|
|
240
267
|
pairs.push([key, nValue]);
|
|
241
268
|
}
|
|
242
|
-
} else if (found && !fullScan) {
|
|
243
|
-
done = true;
|
|
244
|
-
break;
|
|
245
269
|
}
|
|
246
270
|
}
|
|
247
271
|
if (!node.next) {
|
|
@@ -252,12 +276,12 @@ var BPTreeSync = class extends BPTree {
|
|
|
252
276
|
}
|
|
253
277
|
return new Map(pairs);
|
|
254
278
|
}
|
|
255
|
-
getPairs(value, startNode,
|
|
279
|
+
getPairs(value, startNode, endNode, comparator, direction) {
|
|
256
280
|
switch (direction) {
|
|
257
281
|
case -1:
|
|
258
|
-
return this.getPairsRightToLeft(value, startNode,
|
|
282
|
+
return this.getPairsRightToLeft(value, startNode, endNode, comparator);
|
|
259
283
|
case 1:
|
|
260
|
-
return this.getPairsLeftToRight(value, startNode,
|
|
284
|
+
return this.getPairsLeftToRight(value, startNode, endNode, comparator);
|
|
261
285
|
default:
|
|
262
286
|
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
263
287
|
}
|
|
@@ -581,6 +605,25 @@ var BPTreeSync = class extends BPTree {
|
|
|
581
605
|
}
|
|
582
606
|
return node;
|
|
583
607
|
}
|
|
608
|
+
insertableEndNode(value, direction) {
|
|
609
|
+
const insertableNode = this.insertableNode(value);
|
|
610
|
+
let key;
|
|
611
|
+
switch (direction) {
|
|
612
|
+
case -1:
|
|
613
|
+
key = "prev";
|
|
614
|
+
break;
|
|
615
|
+
case 1:
|
|
616
|
+
key = "next";
|
|
617
|
+
break;
|
|
618
|
+
default:
|
|
619
|
+
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
620
|
+
}
|
|
621
|
+
const guessNode = insertableNode[key];
|
|
622
|
+
if (!guessNode) {
|
|
623
|
+
return null;
|
|
624
|
+
}
|
|
625
|
+
return this.getNode(guessNode);
|
|
626
|
+
}
|
|
584
627
|
leftestNode() {
|
|
585
628
|
let node = this.root;
|
|
586
629
|
while (!node.leaf) {
|
|
@@ -589,6 +632,14 @@ var BPTreeSync = class extends BPTree {
|
|
|
589
632
|
}
|
|
590
633
|
return node;
|
|
591
634
|
}
|
|
635
|
+
rightestNode() {
|
|
636
|
+
let node = this.root;
|
|
637
|
+
while (!node.leaf) {
|
|
638
|
+
const keys = node.keys;
|
|
639
|
+
node = this.getNode(keys[keys.length - 1]);
|
|
640
|
+
}
|
|
641
|
+
return node;
|
|
642
|
+
}
|
|
592
643
|
commitHeadBuffer() {
|
|
593
644
|
if (!this._strategyDirty) {
|
|
594
645
|
return;
|
|
@@ -619,10 +670,10 @@ var BPTreeSync = class extends BPTree {
|
|
|
619
670
|
const key = k;
|
|
620
671
|
const value = condition[key];
|
|
621
672
|
const startNode = this.verifierStartNode[key](value);
|
|
673
|
+
const endNode = this.verifierEndNode[key](value);
|
|
622
674
|
const direction = this.verifierDirection[key];
|
|
623
|
-
const fullScan = this.verifierFullScan[key];
|
|
624
675
|
const comparator = this.verifierMap[key];
|
|
625
|
-
const pairs = this.getPairs(value, startNode,
|
|
676
|
+
const pairs = this.getPairs(value, startNode, endNode, comparator, direction);
|
|
626
677
|
if (!filterValues) {
|
|
627
678
|
filterValues = new Set(pairs.keys());
|
|
628
679
|
} else {
|
|
@@ -644,10 +695,10 @@ var BPTreeSync = class extends BPTree {
|
|
|
644
695
|
const key = k;
|
|
645
696
|
const value = condition[key];
|
|
646
697
|
const startNode = this.verifierStartNode[key](value);
|
|
698
|
+
const endNode = this.verifierEndNode[key](value);
|
|
647
699
|
const direction = this.verifierDirection[key];
|
|
648
|
-
const fullScan = this.verifierFullScan[key];
|
|
649
700
|
const comparator = this.verifierMap[key];
|
|
650
|
-
const pairs = this.getPairs(value, startNode,
|
|
701
|
+
const pairs = this.getPairs(value, startNode, endNode, comparator, direction);
|
|
651
702
|
if (result === null) {
|
|
652
703
|
result = pairs;
|
|
653
704
|
} else {
|
|
@@ -757,25 +808,24 @@ var BPTreeAsync = class extends BPTree {
|
|
|
757
808
|
constructor(strategy, comparator) {
|
|
758
809
|
super(strategy, comparator);
|
|
759
810
|
}
|
|
760
|
-
async getPairsRightToLeft(value, startNode,
|
|
811
|
+
async getPairsRightToLeft(value, startNode, endNode, comparator) {
|
|
761
812
|
const pairs = [];
|
|
762
813
|
let node = startNode;
|
|
763
814
|
let done = false;
|
|
764
|
-
let found = false;
|
|
765
815
|
while (!done) {
|
|
816
|
+
if (endNode && node.id === endNode.id) {
|
|
817
|
+
done = true;
|
|
818
|
+
break;
|
|
819
|
+
}
|
|
766
820
|
let i = node.values.length;
|
|
767
821
|
while (i--) {
|
|
768
822
|
const nValue = node.values[i];
|
|
769
823
|
const keys = node.keys[i];
|
|
770
824
|
if (comparator(nValue, value)) {
|
|
771
|
-
found = true;
|
|
772
825
|
let j = keys.length;
|
|
773
826
|
while (j--) {
|
|
774
827
|
pairs.push([keys[j], nValue]);
|
|
775
828
|
}
|
|
776
|
-
} else if (found && !fullScan) {
|
|
777
|
-
done = true;
|
|
778
|
-
break;
|
|
779
829
|
}
|
|
780
830
|
}
|
|
781
831
|
if (!node.prev) {
|
|
@@ -786,24 +836,23 @@ var BPTreeAsync = class extends BPTree {
|
|
|
786
836
|
}
|
|
787
837
|
return new Map(pairs.reverse());
|
|
788
838
|
}
|
|
789
|
-
async getPairsLeftToRight(value, startNode,
|
|
839
|
+
async getPairsLeftToRight(value, startNode, endNode, comparator) {
|
|
790
840
|
const pairs = [];
|
|
791
841
|
let node = startNode;
|
|
792
842
|
let done = false;
|
|
793
|
-
let found = false;
|
|
794
843
|
while (!done) {
|
|
844
|
+
if (endNode && node.id === endNode.id) {
|
|
845
|
+
done = true;
|
|
846
|
+
break;
|
|
847
|
+
}
|
|
795
848
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
796
849
|
const nValue = node.values[i];
|
|
797
850
|
const keys = node.keys[i];
|
|
798
851
|
if (comparator(nValue, value)) {
|
|
799
|
-
found = true;
|
|
800
852
|
for (let j = 0, len2 = keys.length; j < len2; j++) {
|
|
801
853
|
const key = keys[j];
|
|
802
854
|
pairs.push([key, nValue]);
|
|
803
855
|
}
|
|
804
|
-
} else if (found && !fullScan) {
|
|
805
|
-
done = true;
|
|
806
|
-
break;
|
|
807
856
|
}
|
|
808
857
|
}
|
|
809
858
|
if (!node.next) {
|
|
@@ -814,12 +863,12 @@ var BPTreeAsync = class extends BPTree {
|
|
|
814
863
|
}
|
|
815
864
|
return new Map(pairs);
|
|
816
865
|
}
|
|
817
|
-
async getPairs(value, startNode,
|
|
866
|
+
async getPairs(value, startNode, endNode, comparator, direction) {
|
|
818
867
|
switch (direction) {
|
|
819
868
|
case -1:
|
|
820
|
-
return await this.getPairsRightToLeft(value, startNode,
|
|
869
|
+
return await this.getPairsRightToLeft(value, startNode, endNode, comparator);
|
|
821
870
|
case 1:
|
|
822
|
-
return await this.getPairsLeftToRight(value, startNode,
|
|
871
|
+
return await this.getPairsLeftToRight(value, startNode, endNode, comparator);
|
|
823
872
|
default:
|
|
824
873
|
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
825
874
|
}
|
|
@@ -1143,6 +1192,25 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1143
1192
|
}
|
|
1144
1193
|
return node;
|
|
1145
1194
|
}
|
|
1195
|
+
async insertableEndNode(value, direction) {
|
|
1196
|
+
const insertableNode = await this.insertableNode(value);
|
|
1197
|
+
let key;
|
|
1198
|
+
switch (direction) {
|
|
1199
|
+
case -1:
|
|
1200
|
+
key = "prev";
|
|
1201
|
+
break;
|
|
1202
|
+
case 1:
|
|
1203
|
+
key = "next";
|
|
1204
|
+
break;
|
|
1205
|
+
default:
|
|
1206
|
+
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
1207
|
+
}
|
|
1208
|
+
const guessNode = insertableNode[key];
|
|
1209
|
+
if (!guessNode) {
|
|
1210
|
+
return null;
|
|
1211
|
+
}
|
|
1212
|
+
return await this.getNode(guessNode);
|
|
1213
|
+
}
|
|
1146
1214
|
async leftestNode() {
|
|
1147
1215
|
let node = this.root;
|
|
1148
1216
|
while (!node.leaf) {
|
|
@@ -1151,6 +1219,14 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1151
1219
|
}
|
|
1152
1220
|
return node;
|
|
1153
1221
|
}
|
|
1222
|
+
async rightestNode() {
|
|
1223
|
+
let node = this.root;
|
|
1224
|
+
while (!node.leaf) {
|
|
1225
|
+
const keys = node.keys;
|
|
1226
|
+
node = await this.getNode(keys[keys.length - 1]);
|
|
1227
|
+
}
|
|
1228
|
+
return node;
|
|
1229
|
+
}
|
|
1154
1230
|
async commitHeadBuffer() {
|
|
1155
1231
|
if (!this._strategyDirty) {
|
|
1156
1232
|
return;
|
|
@@ -1181,10 +1257,10 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1181
1257
|
const key = k;
|
|
1182
1258
|
const value = condition[key];
|
|
1183
1259
|
const startNode = await this.verifierStartNode[key](value);
|
|
1260
|
+
const endNode = await this.verifierEndNode[key](value);
|
|
1184
1261
|
const direction = this.verifierDirection[key];
|
|
1185
|
-
const fullScan = this.verifierFullScan[key];
|
|
1186
1262
|
const comparator = this.verifierMap[key];
|
|
1187
|
-
const pairs = await this.getPairs(value, startNode,
|
|
1263
|
+
const pairs = await this.getPairs(value, startNode, endNode, comparator, direction);
|
|
1188
1264
|
if (!filterValues) {
|
|
1189
1265
|
filterValues = new Set(pairs.keys());
|
|
1190
1266
|
} else {
|
|
@@ -1206,10 +1282,10 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1206
1282
|
const key = k;
|
|
1207
1283
|
const value = condition[key];
|
|
1208
1284
|
const startNode = await this.verifierStartNode[key](value);
|
|
1285
|
+
const endNode = await this.verifierEndNode[key](value);
|
|
1209
1286
|
const direction = this.verifierDirection[key];
|
|
1210
|
-
const fullScan = this.verifierFullScan[key];
|
|
1211
1287
|
const comparator = this.verifierMap[key];
|
|
1212
|
-
const pairs = await this.getPairs(value, startNode,
|
|
1288
|
+
const pairs = await this.getPairs(value, startNode, endNode, comparator, direction);
|
|
1213
1289
|
if (result === null) {
|
|
1214
1290
|
result = pairs;
|
|
1215
1291
|
} else {
|
|
@@ -5,9 +5,9 @@ import { SerializableData } from './base/SerializeStrategy';
|
|
|
5
5
|
export declare class BPTreeAsync<K, V> extends BPTree<K, V> {
|
|
6
6
|
protected readonly strategy: SerializeStrategyAsync<K, V>;
|
|
7
7
|
constructor(strategy: SerializeStrategyAsync<K, V>, comparator: ValueComparator<V>);
|
|
8
|
-
protected getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>,
|
|
9
|
-
protected getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>,
|
|
10
|
-
protected getPairs(value: V, startNode: BPTreeLeafNode<K, V>,
|
|
8
|
+
protected getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean): Promise<BPTreePair<K, V>>;
|
|
9
|
+
protected getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean): Promise<BPTreePair<K, V>>;
|
|
10
|
+
protected getPairs(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean, direction: 1 | -1): Promise<BPTreePair<K, V>>;
|
|
11
11
|
protected _createNodeId(isLeaf: boolean): Promise<string>;
|
|
12
12
|
protected _createNode(isLeaf: boolean, keys: string[] | K[][], values: V[], leaf?: boolean, parent?: string | null, next?: string | null, prev?: string | null): Promise<BPTreeUnknownNode<K, V>>;
|
|
13
13
|
protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>, value: V): Promise<void>;
|
|
@@ -15,7 +15,9 @@ export declare class BPTreeAsync<K, V> extends BPTree<K, V> {
|
|
|
15
15
|
init(): Promise<void>;
|
|
16
16
|
protected getNode(id: string): Promise<BPTreeUnknownNode<K, V>>;
|
|
17
17
|
protected insertableNode(value: V): Promise<BPTreeLeafNode<K, V>>;
|
|
18
|
+
protected insertableEndNode(value: V, direction: 1 | -1): Promise<BPTreeLeafNode<K, V> | null>;
|
|
18
19
|
protected leftestNode(): Promise<BPTreeLeafNode<K, V>>;
|
|
20
|
+
protected rightestNode(): Promise<BPTreeLeafNode<K, V>>;
|
|
19
21
|
protected commitHeadBuffer(): Promise<void>;
|
|
20
22
|
protected commitNodeCreateBuffer(): Promise<void>;
|
|
21
23
|
protected commitNodeUpdateBuffer(): Promise<void>;
|
|
@@ -5,9 +5,9 @@ import { SerializableData } from './base/SerializeStrategy';
|
|
|
5
5
|
export declare class BPTreeSync<K, V> extends BPTree<K, V> {
|
|
6
6
|
protected readonly strategy: SerializeStrategySync<K, V>;
|
|
7
7
|
constructor(strategy: SerializeStrategySync<K, V>, comparator: ValueComparator<V>);
|
|
8
|
-
protected getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>,
|
|
9
|
-
protected getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>,
|
|
10
|
-
protected getPairs(value: V, startNode: BPTreeLeafNode<K, V>,
|
|
8
|
+
protected getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean): BPTreePair<K, V>;
|
|
9
|
+
protected getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean): BPTreePair<K, V>;
|
|
10
|
+
protected getPairs(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean, direction: 1 | -1): BPTreePair<K, V>;
|
|
11
11
|
protected _createNodeId(isLeaf: boolean): string;
|
|
12
12
|
protected _createNode(isLeaf: boolean, keys: string[] | K[][], values: V[], leaf?: boolean, parent?: string | null, next?: string | null, prev?: string | null): BPTreeUnknownNode<K, V>;
|
|
13
13
|
protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>, value: V): void;
|
|
@@ -15,7 +15,9 @@ export declare class BPTreeSync<K, V> extends BPTree<K, V> {
|
|
|
15
15
|
init(): void;
|
|
16
16
|
protected getNode(id: string): BPTreeUnknownNode<K, V>;
|
|
17
17
|
protected insertableNode(value: V): BPTreeLeafNode<K, V>;
|
|
18
|
+
protected insertableEndNode(value: V, direction: 1 | -1): BPTreeLeafNode<K, V> | null;
|
|
18
19
|
protected leftestNode(): BPTreeLeafNode<K, V>;
|
|
20
|
+
protected rightestNode(): BPTreeLeafNode<K, V>;
|
|
19
21
|
protected commitHeadBuffer(): void;
|
|
20
22
|
protected commitNodeCreateBuffer(): void;
|
|
21
23
|
protected commitNodeUpdateBuffer(): void;
|
|
@@ -18,6 +18,8 @@ export type BPTreeCondition<V> = Partial<{
|
|
|
18
18
|
equal: Partial<V>;
|
|
19
19
|
/** Searches for pairs not equal to the given value. */
|
|
20
20
|
notEqual: Partial<V>;
|
|
21
|
+
/** Searches for pairs that satisfy at least one of the conditions. */
|
|
22
|
+
or: Partial<V>[];
|
|
21
23
|
/** Searches for values matching the given pattern. '%' matches zero or more characters, and '_' matches exactly one character. */
|
|
22
24
|
like: Partial<V>;
|
|
23
25
|
}>;
|
|
@@ -51,21 +53,23 @@ export declare abstract class BPTree<K, V> {
|
|
|
51
53
|
protected readonly _nodeCreateBuffer: Map<string, BPTreeUnknownNode<K, V>>;
|
|
52
54
|
protected readonly _nodeUpdateBuffer: Map<string, BPTreeUnknownNode<K, V>>;
|
|
53
55
|
protected readonly _nodeDeleteBuffer: Map<string, BPTreeUnknownNode<K, V>>;
|
|
54
|
-
protected readonly verifierMap: Record<keyof BPTreeCondition<V>, (nodeValue: V, value: V) => boolean>;
|
|
56
|
+
protected readonly verifierMap: Record<keyof BPTreeCondition<V>, (nodeValue: V, value: V | V[]) => boolean>;
|
|
55
57
|
protected readonly verifierStartNode: Record<keyof BPTreeCondition<V>, (value: V) => Deferred<BPTreeLeafNode<K, V>>>;
|
|
58
|
+
protected readonly verifierEndNode: Record<keyof BPTreeCondition<V>, (value: V) => Deferred<BPTreeLeafNode<K, V> | null>>;
|
|
56
59
|
protected readonly verifierDirection: Record<keyof BPTreeCondition<V>, -1 | 1>;
|
|
57
|
-
protected readonly verifierFullScan: Record<keyof BPTreeCondition<V>, boolean>;
|
|
58
60
|
protected constructor(strategy: SerializeStrategy<K, V>, comparator: ValueComparator<V>);
|
|
59
|
-
protected abstract getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>,
|
|
60
|
-
protected abstract getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>,
|
|
61
|
-
protected abstract getPairs(value: V, startNode: BPTreeLeafNode<K, V>,
|
|
61
|
+
protected abstract getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean): Deferred<BPTreePair<K, V>>;
|
|
62
|
+
protected abstract getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean): Deferred<BPTreePair<K, V>>;
|
|
63
|
+
protected abstract getPairs(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean, direction: -1 | 1): Deferred<BPTreePair<K, V>>;
|
|
62
64
|
protected abstract _createNodeId(isLeaf: boolean): Deferred<string>;
|
|
63
65
|
protected abstract _createNode(isLeaf: boolean, keys: string[] | K[][], values: V[], leaf?: boolean, parent?: string | null, next?: string | null, prev?: string | null): Deferred<BPTreeUnknownNode<K, V>>;
|
|
64
66
|
protected abstract _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>, value: V): Deferred<void>;
|
|
65
67
|
protected abstract _insertInParent(node: BPTreeUnknownNode<K, V>, value: V, pointer: BPTreeUnknownNode<K, V>): Deferred<void>;
|
|
66
68
|
protected abstract getNode(id: string): Deferred<BPTreeUnknownNode<K, V>>;
|
|
67
69
|
protected abstract insertableNode(value: V): Deferred<BPTreeLeafNode<K, V>>;
|
|
70
|
+
protected abstract insertableEndNode(value: V, direction: 1 | -1): Deferred<BPTreeLeafNode<K, V> | null>;
|
|
68
71
|
protected abstract leftestNode(): Deferred<BPTreeLeafNode<K, V>>;
|
|
72
|
+
protected abstract rightestNode(): Deferred<BPTreeLeafNode<K, V>>;
|
|
69
73
|
protected abstract commitHeadBuffer(): Deferred<void>;
|
|
70
74
|
protected abstract commitNodeCreateBuffer(): Deferred<void>;
|
|
71
75
|
protected abstract commitNodeUpdateBuffer(): Deferred<void>;
|
|
@@ -123,6 +127,9 @@ export declare abstract class BPTree<K, V> {
|
|
|
123
127
|
* @returns The return value is the total number of nodes updated.
|
|
124
128
|
*/
|
|
125
129
|
abstract forceUpdate(): Deferred<number>;
|
|
130
|
+
protected ensureValues(v: V | V[]): V[];
|
|
131
|
+
protected lowestValue(v: V[]): V;
|
|
132
|
+
protected highestValue(v: V[]): V;
|
|
126
133
|
protected _insertAtLeaf(node: BPTreeLeafNode<K, V>, key: K, value: V): void;
|
|
127
134
|
protected bufferForNodeCreate(node: BPTreeUnknownNode<K, V>): void;
|
|
128
135
|
protected bufferForNodeUpdate(node: BPTreeUnknownNode<K, V>): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "serializable-bptree",
|
|
3
|
-
"version": "5.0
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "Store the B+tree flexibly, not only in-memory.",
|
|
5
5
|
"types": "./dist/types/index.d.ts",
|
|
6
6
|
"main": "./dist/cjs/index.cjs",
|
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
"license": "MIT",
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/jest": "^29.5.14",
|
|
40
|
-
"esbuild": "^0.
|
|
40
|
+
"esbuild": "^0.25.4",
|
|
41
41
|
"jest": "^29.7.0",
|
|
42
|
-
"ts-jest": "^29.
|
|
43
|
-
"typescript": "^5.
|
|
42
|
+
"ts-jest": "^29.3.3",
|
|
43
|
+
"typescript": "^5.8.3"
|
|
44
44
|
}
|
|
45
45
|
}
|