serializable-bptree 2.0.0 → 3.0.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 +152 -10
- package/dist/cjs/index.js +926 -407
- package/dist/esm/index.js +926 -407
- package/dist/typings/BPTreeAsync.d.ts +45 -0
- package/dist/typings/BPTreeSync.d.ts +46 -0
- package/dist/typings/SerializeStrategyAsync.d.ts +21 -0
- package/dist/typings/SerializeStrategySync.d.ts +21 -0
- package/dist/typings/base/BPTree.d.ts +138 -0
- package/dist/typings/{SerializeStrategy.d.ts → base/SerializeStrategy.d.ts} +7 -19
- package/dist/typings/index.d.ts +6 -2
- package/package.json +5 -1
- package/dist/typings/BPTree.d.ts +0 -127
- package/dist/typings/utils/BinarySearch.d.ts +0 -9
package/dist/esm/index.js
CHANGED
|
@@ -1,72 +1,15 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
var BinarySearch = class {
|
|
3
|
-
comparator;
|
|
4
|
-
constructor(comparator) {
|
|
5
|
-
this.comparator = comparator;
|
|
6
|
-
}
|
|
7
|
-
_withRange(array, value, left = 0, right = array.length - 1) {
|
|
8
|
-
while (left <= right) {
|
|
9
|
-
const mid = Math.floor((left + right) / 2);
|
|
10
|
-
const guess = array[mid];
|
|
11
|
-
if (this.comparator.isSame(guess, value)) {
|
|
12
|
-
return mid;
|
|
13
|
-
} else if (this.comparator.isLower(guess, value)) {
|
|
14
|
-
left = mid + 1;
|
|
15
|
-
continue;
|
|
16
|
-
} else {
|
|
17
|
-
right = mid - 1;
|
|
18
|
-
continue;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
return -1;
|
|
22
|
-
}
|
|
23
|
-
leftest(array, value) {
|
|
24
|
-
let i = this._withRange(array, value);
|
|
25
|
-
if (i === -1) {
|
|
26
|
-
return -1;
|
|
27
|
-
}
|
|
28
|
-
while (i > 0) {
|
|
29
|
-
if (!this.comparator.isSame(array[i - 1], value)) {
|
|
30
|
-
break;
|
|
31
|
-
}
|
|
32
|
-
i--;
|
|
33
|
-
}
|
|
34
|
-
return i;
|
|
35
|
-
}
|
|
36
|
-
rightest(array, value) {
|
|
37
|
-
let i = this._withRange(array, value);
|
|
38
|
-
if (i === -1) {
|
|
39
|
-
return -1;
|
|
40
|
-
}
|
|
41
|
-
const max = array.length - 1;
|
|
42
|
-
while (i < max) {
|
|
43
|
-
if (!this.comparator.isSame(array[i + 1], value)) {
|
|
44
|
-
break;
|
|
45
|
-
}
|
|
46
|
-
i++;
|
|
47
|
-
}
|
|
48
|
-
return i;
|
|
49
|
-
}
|
|
50
|
-
range(array, value) {
|
|
51
|
-
const left = this.leftest(array, value);
|
|
52
|
-
const right = this.rightest(array, value) + 1;
|
|
53
|
-
return [left, right];
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
// src/BPTree.ts
|
|
1
|
+
// src/base/BPTree.ts
|
|
58
2
|
var BPTree = class {
|
|
59
3
|
strategy;
|
|
60
4
|
comparator;
|
|
61
|
-
search;
|
|
62
|
-
order;
|
|
63
5
|
nodes;
|
|
6
|
+
order;
|
|
64
7
|
data;
|
|
65
8
|
root;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
9
|
+
_nodeCreateBuffer;
|
|
10
|
+
_nodeUpdateBuffer;
|
|
11
|
+
_headBuffer;
|
|
12
|
+
verifierMap = {
|
|
70
13
|
gt: (nv, v) => this.comparator.isHigher(nv, v),
|
|
71
14
|
gte: (nv, v) => this.comparator.isHigher(nv, v) || this.comparator.isSame(nv, v),
|
|
72
15
|
lt: (nv, v) => this.comparator.isLower(nv, v),
|
|
@@ -81,19 +24,16 @@ var BPTree = class {
|
|
|
81
24
|
return regex.test(nodeValue);
|
|
82
25
|
}
|
|
83
26
|
};
|
|
84
|
-
|
|
27
|
+
verifierStartNode = {
|
|
85
28
|
gt: (v) => this.insertableNode(v),
|
|
86
29
|
gte: (v) => this.insertableNode(v),
|
|
87
|
-
// todo
|
|
88
30
|
lt: (v) => this.insertableNode(v),
|
|
89
31
|
lte: (v) => this.insertableNode(v),
|
|
90
|
-
// todo
|
|
91
32
|
equal: (v) => this.insertableNode(v),
|
|
92
33
|
notEqual: (v) => this.leftestNode(),
|
|
93
34
|
like: (v) => this.leftestNode()
|
|
94
|
-
// todo
|
|
95
35
|
};
|
|
96
|
-
|
|
36
|
+
verifierDirection = {
|
|
97
37
|
gt: 1,
|
|
98
38
|
gte: 1,
|
|
99
39
|
lt: -1,
|
|
@@ -102,7 +42,7 @@ var BPTree = class {
|
|
|
102
42
|
notEqual: 1,
|
|
103
43
|
like: 1
|
|
104
44
|
};
|
|
105
|
-
|
|
45
|
+
verifierFullSearch = {
|
|
106
46
|
gt: false,
|
|
107
47
|
gte: false,
|
|
108
48
|
lt: false,
|
|
@@ -111,59 +51,7 @@ var BPTree = class {
|
|
|
111
51
|
notEqual: true,
|
|
112
52
|
like: true
|
|
113
53
|
};
|
|
114
|
-
|
|
115
|
-
const id = this.strategy.id();
|
|
116
|
-
if (id === 0) {
|
|
117
|
-
throw new Error(`The node's id should never be 0.`);
|
|
118
|
-
}
|
|
119
|
-
return id;
|
|
120
|
-
}
|
|
121
|
-
_createNode(keys, values, leaf = false, parent = 0, next = 0, prev = 0) {
|
|
122
|
-
const id = this._createNodeId();
|
|
123
|
-
const node = {
|
|
124
|
-
id,
|
|
125
|
-
keys,
|
|
126
|
-
values,
|
|
127
|
-
leaf,
|
|
128
|
-
parent,
|
|
129
|
-
next,
|
|
130
|
-
prev
|
|
131
|
-
};
|
|
132
|
-
this.nodes.set(id, node);
|
|
133
|
-
return node;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* @param strategy An instance of a strategy that manages the read/write state of a node.
|
|
137
|
-
* @param comparator An instance of a comparator that compares the size of values.
|
|
138
|
-
*/
|
|
139
|
-
constructor(strategy, comparator) {
|
|
140
|
-
const head = strategy.readHead();
|
|
141
|
-
this._creates = /* @__PURE__ */ new Map();
|
|
142
|
-
this._updates = /* @__PURE__ */ new Map();
|
|
143
|
-
this._updatedHead = null;
|
|
144
|
-
this.nodes = /* @__PURE__ */ new Map();
|
|
145
|
-
this.search = new BinarySearch(comparator);
|
|
146
|
-
this.strategy = strategy;
|
|
147
|
-
this.comparator = comparator;
|
|
148
|
-
if (head === null) {
|
|
149
|
-
this.order = strategy.order;
|
|
150
|
-
this.data = {};
|
|
151
|
-
this.root = this._createNode([], [], true);
|
|
152
|
-
this._setHeadUpdate(this._headState);
|
|
153
|
-
this._setCreates(this.root);
|
|
154
|
-
this._emitHeadUpdates();
|
|
155
|
-
this._emitCreates();
|
|
156
|
-
} else {
|
|
157
|
-
const { root, order, data } = head;
|
|
158
|
-
this.order = order;
|
|
159
|
-
this.data = data ?? {};
|
|
160
|
-
this.root = this.getNode(root);
|
|
161
|
-
}
|
|
162
|
-
if (this.order < 3) {
|
|
163
|
-
throw new Error(`The 'order' parameter must be greater than 2. but got a '${this.order}'.`);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
get _headState() {
|
|
54
|
+
get headState() {
|
|
167
55
|
const root = this.root.id;
|
|
168
56
|
const order = this.order;
|
|
169
57
|
const data = this.data;
|
|
@@ -173,82 +61,13 @@ var BPTree = class {
|
|
|
173
61
|
data
|
|
174
62
|
};
|
|
175
63
|
}
|
|
176
|
-
|
|
177
|
-
this.
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
this.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
this._updates.set(node.id, node);
|
|
184
|
-
}
|
|
185
|
-
_emitHeadUpdates() {
|
|
186
|
-
if (this._updatedHead !== null) {
|
|
187
|
-
this.strategy.writeHead(this._updatedHead);
|
|
188
|
-
}
|
|
189
|
-
this._updatedHead = null;
|
|
190
|
-
}
|
|
191
|
-
_emitCreates() {
|
|
192
|
-
for (const node of this._creates.values()) {
|
|
193
|
-
this.strategy.write(node.id, node);
|
|
194
|
-
}
|
|
195
|
-
this._creates.clear();
|
|
196
|
-
}
|
|
197
|
-
_emitUpdates() {
|
|
198
|
-
for (const node of this._updates.values()) {
|
|
199
|
-
this.strategy.write(node.id, node);
|
|
200
|
-
}
|
|
201
|
-
this._updates.clear();
|
|
202
|
-
}
|
|
203
|
-
getNode(id) {
|
|
204
|
-
if (!this.nodes.has(id)) {
|
|
205
|
-
this.nodes.set(id, this.strategy.read(id));
|
|
206
|
-
}
|
|
207
|
-
return this.nodes.get(id);
|
|
208
|
-
}
|
|
209
|
-
leftestNode() {
|
|
210
|
-
let node = this.root;
|
|
211
|
-
while (!node.leaf) {
|
|
212
|
-
const keys = node.keys;
|
|
213
|
-
node = this.getNode(keys[0]);
|
|
214
|
-
}
|
|
215
|
-
return node;
|
|
216
|
-
}
|
|
217
|
-
insertableNode(value) {
|
|
218
|
-
let node = this.root;
|
|
219
|
-
while (!node.leaf) {
|
|
220
|
-
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
221
|
-
const nValue = node.values[i];
|
|
222
|
-
const k = node.keys;
|
|
223
|
-
if (this.comparator.isSame(value, nValue)) {
|
|
224
|
-
node = this.getNode(k[i + 1]);
|
|
225
|
-
break;
|
|
226
|
-
} else if (this.comparator.isLower(value, nValue)) {
|
|
227
|
-
node = this.getNode(k[i]);
|
|
228
|
-
break;
|
|
229
|
-
} else if (i + 1 === node.values.length) {
|
|
230
|
-
node = this.getNode(k[i + 1]);
|
|
231
|
-
break;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
return node;
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* It returns whether there is a value in the tree.
|
|
239
|
-
* @param key The key value to search for.
|
|
240
|
-
* @param value The value to search for.
|
|
241
|
-
*/
|
|
242
|
-
exists(key, value) {
|
|
243
|
-
const node = this.insertableNode(value);
|
|
244
|
-
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
245
|
-
const nValue = node.values[i];
|
|
246
|
-
if (this.comparator.isSame(value, nValue)) {
|
|
247
|
-
const keys = node.keys[i];
|
|
248
|
-
return keys.includes(key);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
return false;
|
|
64
|
+
constructor(strategy, comparator) {
|
|
65
|
+
this._headBuffer = null;
|
|
66
|
+
this._nodeCreateBuffer = /* @__PURE__ */ new Map();
|
|
67
|
+
this._nodeUpdateBuffer = /* @__PURE__ */ new Map();
|
|
68
|
+
this.nodes = /* @__PURE__ */ new Map();
|
|
69
|
+
this.strategy = strategy;
|
|
70
|
+
this.comparator = comparator;
|
|
252
71
|
}
|
|
253
72
|
_insertAtLeaf(node, key, value) {
|
|
254
73
|
if (node.values.length) {
|
|
@@ -257,74 +76,49 @@ var BPTree = class {
|
|
|
257
76
|
if (this.comparator.isSame(value, nValue)) {
|
|
258
77
|
const keys = node.keys[i];
|
|
259
78
|
keys.push(key);
|
|
260
|
-
this.
|
|
79
|
+
this.bufferForNodeUpdate(node);
|
|
261
80
|
break;
|
|
262
81
|
} else if (this.comparator.isLower(value, nValue)) {
|
|
263
82
|
node.values.splice(i, 0, value);
|
|
264
83
|
node.keys.splice(i, 0, [key]);
|
|
265
|
-
this.
|
|
84
|
+
this.bufferForNodeUpdate(node);
|
|
266
85
|
break;
|
|
267
86
|
} else if (i + 1 === node.values.length) {
|
|
268
87
|
node.values.push(value);
|
|
269
88
|
node.keys.push([key]);
|
|
270
|
-
this.
|
|
89
|
+
this.bufferForNodeUpdate(node);
|
|
271
90
|
break;
|
|
272
91
|
}
|
|
273
92
|
}
|
|
274
93
|
} else {
|
|
275
94
|
node.values = [value];
|
|
276
95
|
node.keys = [[key]];
|
|
277
|
-
this.
|
|
96
|
+
this.bufferForNodeUpdate(node);
|
|
278
97
|
}
|
|
279
98
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
parentPointer.values = parentNode.values.slice(mid + 1);
|
|
304
|
-
parentPointer.keys = parentNode.keys.slice(mid + 1);
|
|
305
|
-
const midValue = parentNode.values[mid];
|
|
306
|
-
if (mid === 0) {
|
|
307
|
-
parentNode.values = parentNode.values.slice(0, mid + 1);
|
|
308
|
-
} else {
|
|
309
|
-
parentNode.values = parentNode.values.slice(0, mid);
|
|
310
|
-
}
|
|
311
|
-
parentNode.keys = parentNode.keys.slice(0, mid + 1);
|
|
312
|
-
for (const k of parentNode.keys) {
|
|
313
|
-
const node2 = this.getNode(k);
|
|
314
|
-
node2.parent = parentNode.id;
|
|
315
|
-
this._setUpdates(node2);
|
|
316
|
-
}
|
|
317
|
-
for (const k of parentPointer.keys) {
|
|
318
|
-
const node2 = this.getNode(k);
|
|
319
|
-
node2.parent = parentPointer.id;
|
|
320
|
-
this._setUpdates(node2);
|
|
321
|
-
}
|
|
322
|
-
this._insertInParent(parentNode, midValue, parentPointer);
|
|
323
|
-
this._setCreates(parentPointer);
|
|
324
|
-
this._setUpdates(parentNode);
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
}
|
|
99
|
+
bufferForHeadUpdate(head) {
|
|
100
|
+
this._headBuffer = head;
|
|
101
|
+
}
|
|
102
|
+
bufferForNodeCreate(node) {
|
|
103
|
+
this._nodeCreateBuffer.set(node.id, node);
|
|
104
|
+
}
|
|
105
|
+
bufferForNodeUpdate(node) {
|
|
106
|
+
this._nodeUpdateBuffer.set(node.id, node);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Returns the user-defined data stored in the head of the tree.
|
|
110
|
+
* 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 `{}`.
|
|
111
|
+
* @returns User-defined data stored in the head of the tree.
|
|
112
|
+
*/
|
|
113
|
+
getHeadData() {
|
|
114
|
+
return this.data;
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
// src/BPTreeSync.ts
|
|
119
|
+
var BPTreeSync = class extends BPTree {
|
|
120
|
+
constructor(strategy, comparator) {
|
|
121
|
+
super(strategy, comparator);
|
|
328
122
|
}
|
|
329
123
|
_getPairsRightToLeft(value, startNode, fullSearch, comparator) {
|
|
330
124
|
const pairs = [];
|
|
@@ -392,96 +186,441 @@ var BPTree = class {
|
|
|
392
186
|
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
393
187
|
}
|
|
394
188
|
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
* @param condition You can use the `gt`, `lt`, `gte`, `lte`, `equal`, `notEqual`, `like` condition statements.
|
|
400
|
-
*/
|
|
401
|
-
keys(condition) {
|
|
402
|
-
let result = null;
|
|
403
|
-
for (const k in condition) {
|
|
404
|
-
const key = k;
|
|
405
|
-
const value = condition[key];
|
|
406
|
-
const startNode = this._verifierStartNode[key](value);
|
|
407
|
-
const direction = this._verifierDirection[key];
|
|
408
|
-
const fullSearch = this._verifierFullSearch[key];
|
|
409
|
-
const comparator = this._verifierMap[key];
|
|
410
|
-
const pairs = this.getPairs(value, startNode, fullSearch, comparator, direction);
|
|
411
|
-
if (result === null) {
|
|
412
|
-
result = pairs.map((pair) => pair.key);
|
|
413
|
-
} else {
|
|
414
|
-
result = result.filter((key2) => pairs.find((p) => p.key === key2));
|
|
415
|
-
}
|
|
189
|
+
_createNodeId() {
|
|
190
|
+
const id = this.strategy.id();
|
|
191
|
+
if (id === 0) {
|
|
192
|
+
throw new Error(`The node's id should never be 0.`);
|
|
416
193
|
}
|
|
417
|
-
return
|
|
194
|
+
return id;
|
|
418
195
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
const comparator = this._verifierMap[key];
|
|
433
|
-
const pairs = this.getPairs(value, startNode, fullSearch, comparator, direction);
|
|
434
|
-
if (result === null) {
|
|
435
|
-
result = pairs;
|
|
436
|
-
} else {
|
|
437
|
-
result = result.filter((pair) => pairs.find((p) => p.key === pair.key));
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
return result ?? [];
|
|
196
|
+
_createNode(keys, values, leaf = false, parent = 0, next = 0, prev = 0) {
|
|
197
|
+
const id = this._createNodeId();
|
|
198
|
+
const node = {
|
|
199
|
+
id,
|
|
200
|
+
keys,
|
|
201
|
+
values,
|
|
202
|
+
leaf,
|
|
203
|
+
parent,
|
|
204
|
+
next,
|
|
205
|
+
prev
|
|
206
|
+
};
|
|
207
|
+
this.nodes.set(id, node);
|
|
208
|
+
return node;
|
|
441
209
|
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
[]
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
210
|
+
_deleteEntry(node, key, value) {
|
|
211
|
+
if (!node.leaf) {
|
|
212
|
+
for (let i = 0, len = node.keys.length; i < len; i++) {
|
|
213
|
+
const nKey = node.keys[i];
|
|
214
|
+
if (nKey === key) {
|
|
215
|
+
node.keys.splice(i, 1);
|
|
216
|
+
this.bufferForNodeUpdate(node);
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
221
|
+
const nValue = node.values[i];
|
|
222
|
+
if (this.comparator.isSame(value, nValue)) {
|
|
223
|
+
node.values.splice(i, 1);
|
|
224
|
+
this.bufferForNodeUpdate(node);
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (this.root === node && node.keys.length === 1) {
|
|
230
|
+
const keys = node.keys;
|
|
231
|
+
this.root = this.getNode(keys[0]);
|
|
232
|
+
this.root.parent = 0;
|
|
233
|
+
this.bufferForHeadUpdate(this.headState);
|
|
234
|
+
this.bufferForNodeUpdate(this.root);
|
|
235
|
+
return;
|
|
236
|
+
} else if (this.root === node) {
|
|
237
|
+
return;
|
|
238
|
+
} else if (node.keys.length < Math.ceil(this.order / 2) && !node.leaf || node.values.length < Math.ceil((this.order - 1) / 2) && node.leaf) {
|
|
239
|
+
let isPredecessor = false;
|
|
240
|
+
let parentNode = this.getNode(node.parent);
|
|
241
|
+
let prevNode = null;
|
|
242
|
+
let nextNode = null;
|
|
243
|
+
let prevValue = null;
|
|
244
|
+
let postValue = null;
|
|
245
|
+
for (let i = 0, len = parentNode.keys.length; i < len; i++) {
|
|
246
|
+
const nKey = parentNode.keys[i];
|
|
247
|
+
if (nKey === node.id) {
|
|
248
|
+
if (i > 0) {
|
|
249
|
+
prevNode = this.getNode(parentNode.keys[i - 1]);
|
|
250
|
+
prevValue = parentNode.values[i - 1];
|
|
251
|
+
}
|
|
252
|
+
if (i < parentNode.keys.length - 1) {
|
|
253
|
+
nextNode = this.getNode(parentNode.keys[i + 1]);
|
|
254
|
+
postValue = parentNode.values[i];
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
let pointer;
|
|
259
|
+
let guess;
|
|
260
|
+
if (prevNode === null) {
|
|
261
|
+
pointer = nextNode;
|
|
262
|
+
guess = postValue;
|
|
263
|
+
} else if (nextNode === null) {
|
|
264
|
+
isPredecessor = true;
|
|
265
|
+
pointer = prevNode;
|
|
266
|
+
guess = prevValue;
|
|
267
|
+
} else {
|
|
268
|
+
if (node.values.length + nextNode.values.length < this.order) {
|
|
269
|
+
pointer = nextNode;
|
|
270
|
+
guess = postValue;
|
|
271
|
+
} else {
|
|
272
|
+
isPredecessor = true;
|
|
273
|
+
pointer = prevNode;
|
|
274
|
+
guess = prevValue;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (node.values.length + pointer.values.length < this.order) {
|
|
278
|
+
if (!isPredecessor) {
|
|
279
|
+
const pTemp = pointer;
|
|
280
|
+
pointer = node;
|
|
281
|
+
node = pTemp;
|
|
282
|
+
}
|
|
283
|
+
pointer.keys.push(...node.keys);
|
|
284
|
+
if (!node.leaf) {
|
|
285
|
+
pointer.values.push(guess);
|
|
286
|
+
} else {
|
|
287
|
+
pointer.next = node.next;
|
|
288
|
+
pointer.prev = node.id;
|
|
289
|
+
if (pointer.next) {
|
|
290
|
+
const n = this.getNode(node.next);
|
|
291
|
+
n.prev = pointer.id;
|
|
292
|
+
this.bufferForNodeUpdate(n);
|
|
293
|
+
}
|
|
294
|
+
if (pointer.prev) {
|
|
295
|
+
const n = this.getNode(node.id);
|
|
296
|
+
n.next = pointer.id;
|
|
297
|
+
this.bufferForNodeUpdate(n);
|
|
298
|
+
}
|
|
299
|
+
if (isPredecessor) {
|
|
300
|
+
pointer.prev = 0;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
pointer.values.push(...node.values);
|
|
304
|
+
if (!pointer.leaf) {
|
|
305
|
+
const keys = pointer.keys;
|
|
306
|
+
for (const key2 of keys) {
|
|
307
|
+
const node2 = this.getNode(key2);
|
|
308
|
+
node2.parent = pointer.id;
|
|
309
|
+
this.bufferForNodeUpdate(node2);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
this._deleteEntry(this.getNode(node.parent), node.id, guess);
|
|
313
|
+
this.bufferForNodeUpdate(pointer);
|
|
314
|
+
} else {
|
|
315
|
+
if (isPredecessor) {
|
|
316
|
+
let pointerPm;
|
|
317
|
+
let pointerKm;
|
|
318
|
+
if (!node.leaf) {
|
|
319
|
+
pointerPm = pointer.keys.splice(-1)[0];
|
|
320
|
+
pointerKm = pointer.values.splice(-1)[0];
|
|
321
|
+
node.keys = [pointerPm, ...node.keys];
|
|
322
|
+
node.values = [guess, ...node.values];
|
|
323
|
+
parentNode = this.getNode(node.parent);
|
|
324
|
+
for (let i = 0, len = parentNode.values.length; i < len; i++) {
|
|
325
|
+
const nValue = parentNode.values[i];
|
|
326
|
+
if (this.comparator.isSame(guess, nValue)) {
|
|
327
|
+
parentNode.values[i] = pointerKm;
|
|
328
|
+
this.bufferForNodeUpdate(parentNode);
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
} else {
|
|
333
|
+
pointerPm = pointer.keys.splice(-1)[0];
|
|
334
|
+
pointerKm = pointer.values.splice(-1)[0];
|
|
335
|
+
node.keys = [pointerPm, ...node.keys];
|
|
336
|
+
node.values = [pointerKm, ...node.values];
|
|
337
|
+
parentNode = this.getNode(node.parent);
|
|
338
|
+
for (let i = 0, len = parentNode.values.length; i < len; i++) {
|
|
339
|
+
const nValue = parentNode.values[i];
|
|
340
|
+
if (this.comparator.isSame(guess, nValue)) {
|
|
341
|
+
parentNode.values[i] = pointerKm;
|
|
342
|
+
this.bufferForNodeUpdate(parentNode);
|
|
343
|
+
break;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
this.bufferForNodeUpdate(node);
|
|
348
|
+
this.bufferForNodeUpdate(pointer);
|
|
349
|
+
} else {
|
|
350
|
+
let pointerP0;
|
|
351
|
+
let pointerK0;
|
|
352
|
+
if (!node.leaf) {
|
|
353
|
+
pointerP0 = pointer.keys.splice(0, 1)[0];
|
|
354
|
+
pointerK0 = pointer.values.splice(0, 1)[0];
|
|
355
|
+
node.keys = [...node.keys, pointerP0];
|
|
356
|
+
node.values = [...node.values, guess];
|
|
357
|
+
parentNode = this.getNode(node.parent);
|
|
358
|
+
for (let i = 0, len = parentNode.values.length; i < len; i++) {
|
|
359
|
+
const nValue = parentNode.values[i];
|
|
360
|
+
if (this.comparator.isSame(guess, nValue)) {
|
|
361
|
+
parentNode.values[i] = pointerK0;
|
|
362
|
+
this.bufferForNodeUpdate(parentNode);
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
} else {
|
|
367
|
+
pointerP0 = pointer.keys.splice(0, 1)[0];
|
|
368
|
+
pointerK0 = pointer.values.splice(0, 1)[0];
|
|
369
|
+
node.keys = [...node.keys, pointerP0];
|
|
370
|
+
node.values = [...node.values, pointerK0];
|
|
371
|
+
parentNode = this.getNode(node.parent);
|
|
372
|
+
for (let i = 0, len = parentNode.values.length; i < len; i++) {
|
|
373
|
+
const nValue = parentNode.values[i];
|
|
374
|
+
if (this.comparator.isSame(guess, nValue)) {
|
|
375
|
+
parentNode.values[i] = pointer.values[0];
|
|
376
|
+
this.bufferForNodeUpdate(parentNode);
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
this.bufferForNodeUpdate(node);
|
|
382
|
+
this.bufferForNodeUpdate(pointer);
|
|
383
|
+
}
|
|
384
|
+
if (!pointer.leaf) {
|
|
385
|
+
for (const key2 of pointer.keys) {
|
|
386
|
+
const n = this.getNode(key2);
|
|
387
|
+
n.parent = pointer.id;
|
|
388
|
+
this.bufferForNodeUpdate(n);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
if (!node.leaf) {
|
|
392
|
+
for (const key2 of node.keys) {
|
|
393
|
+
const n = this.getNode(key2);
|
|
394
|
+
n.parent = node.id;
|
|
395
|
+
this.bufferForNodeUpdate(n);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
if (!parentNode.leaf) {
|
|
399
|
+
for (const key2 of parentNode.keys) {
|
|
400
|
+
const n = this.getNode(key2);
|
|
401
|
+
n.parent = parentNode.id;
|
|
402
|
+
this.bufferForNodeUpdate(n);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
471
405
|
}
|
|
472
|
-
this._insertInParent(before, after.values[0], after);
|
|
473
|
-
this._setCreates(after);
|
|
474
|
-
this._setUpdates(before);
|
|
475
406
|
}
|
|
476
|
-
this._emitHeadUpdates();
|
|
477
|
-
this._emitCreates();
|
|
478
|
-
this._emitUpdates();
|
|
479
407
|
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
408
|
+
_insertAtLeaf(node, key, value) {
|
|
409
|
+
if (node.values.length) {
|
|
410
|
+
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
411
|
+
const nValue = node.values[i];
|
|
412
|
+
if (this.comparator.isSame(value, nValue)) {
|
|
413
|
+
const keys = node.keys[i];
|
|
414
|
+
keys.push(key);
|
|
415
|
+
this.bufferForNodeUpdate(node);
|
|
416
|
+
break;
|
|
417
|
+
} else if (this.comparator.isLower(value, nValue)) {
|
|
418
|
+
node.values.splice(i, 0, value);
|
|
419
|
+
node.keys.splice(i, 0, [key]);
|
|
420
|
+
this.bufferForNodeUpdate(node);
|
|
421
|
+
break;
|
|
422
|
+
} else if (i + 1 === node.values.length) {
|
|
423
|
+
node.values.push(value);
|
|
424
|
+
node.keys.push([key]);
|
|
425
|
+
this.bufferForNodeUpdate(node);
|
|
426
|
+
break;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
} else {
|
|
430
|
+
node.values = [value];
|
|
431
|
+
node.keys = [[key]];
|
|
432
|
+
this.bufferForNodeUpdate(node);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
_insertInParent(node, value, pointer) {
|
|
436
|
+
if (this.root === node) {
|
|
437
|
+
const root = this._createNode([node.id, pointer.id], [value]);
|
|
438
|
+
this.root = root;
|
|
439
|
+
node.parent = root.id;
|
|
440
|
+
pointer.parent = root.id;
|
|
441
|
+
this.bufferForHeadUpdate(this.headState);
|
|
442
|
+
this.bufferForNodeCreate(root);
|
|
443
|
+
this.bufferForNodeUpdate(node);
|
|
444
|
+
this.bufferForNodeUpdate(pointer);
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
const parentNode = this.getNode(node.parent);
|
|
448
|
+
for (let i = 0, len = parentNode.keys.length; i < len; i++) {
|
|
449
|
+
const nKeys = parentNode.keys[i];
|
|
450
|
+
if (nKeys === node.id) {
|
|
451
|
+
parentNode.values.splice(i, 0, value);
|
|
452
|
+
parentNode.keys.splice(i + 1, 0, pointer.id);
|
|
453
|
+
this.bufferForNodeUpdate(parentNode);
|
|
454
|
+
if (parentNode.keys.length > this.order) {
|
|
455
|
+
const parentPointer = this._createNode([], []);
|
|
456
|
+
parentPointer.parent = parentNode.parent;
|
|
457
|
+
const mid = Math.ceil(this.order / 2) - 1;
|
|
458
|
+
parentPointer.values = parentNode.values.slice(mid + 1);
|
|
459
|
+
parentPointer.keys = parentNode.keys.slice(mid + 1);
|
|
460
|
+
const midValue = parentNode.values[mid];
|
|
461
|
+
if (mid === 0) {
|
|
462
|
+
parentNode.values = parentNode.values.slice(0, mid + 1);
|
|
463
|
+
} else {
|
|
464
|
+
parentNode.values = parentNode.values.slice(0, mid);
|
|
465
|
+
}
|
|
466
|
+
parentNode.keys = parentNode.keys.slice(0, mid + 1);
|
|
467
|
+
for (const k of parentNode.keys) {
|
|
468
|
+
const node2 = this.getNode(k);
|
|
469
|
+
node2.parent = parentNode.id;
|
|
470
|
+
this.bufferForNodeUpdate(node2);
|
|
471
|
+
}
|
|
472
|
+
for (const k of parentPointer.keys) {
|
|
473
|
+
const node2 = this.getNode(k);
|
|
474
|
+
node2.parent = parentPointer.id;
|
|
475
|
+
this.bufferForNodeUpdate(node2);
|
|
476
|
+
}
|
|
477
|
+
this._insertInParent(parentNode, midValue, parentPointer);
|
|
478
|
+
this.bufferForNodeCreate(parentPointer);
|
|
479
|
+
this.bufferForNodeUpdate(parentNode);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
init() {
|
|
485
|
+
const head = this.strategy.readHead();
|
|
486
|
+
if (head === null) {
|
|
487
|
+
this.order = this.strategy.order;
|
|
488
|
+
this.data = {};
|
|
489
|
+
this.root = this._createNode([], [], true);
|
|
490
|
+
this.bufferForHeadUpdate(this.headState);
|
|
491
|
+
this.bufferForNodeCreate(this.root);
|
|
492
|
+
this.commitHeadBuffer();
|
|
493
|
+
this.commitNodeCreateBuffer();
|
|
494
|
+
} else {
|
|
495
|
+
const { root, order, data } = head;
|
|
496
|
+
this.order = order;
|
|
497
|
+
this.data = data ?? {};
|
|
498
|
+
this.root = this.getNode(root);
|
|
499
|
+
}
|
|
500
|
+
if (this.order < 3) {
|
|
501
|
+
throw new Error(`The 'order' parameter must be greater than 2. but got a '${this.order}'.`);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
getNode(id) {
|
|
505
|
+
if (!this.nodes.has(id)) {
|
|
506
|
+
this.nodes.set(id, this.strategy.read(id));
|
|
507
|
+
}
|
|
508
|
+
return this.nodes.get(id);
|
|
509
|
+
}
|
|
510
|
+
insertableNode(value) {
|
|
511
|
+
let node = this.root;
|
|
512
|
+
while (!node.leaf) {
|
|
513
|
+
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
514
|
+
const nValue = node.values[i];
|
|
515
|
+
const k = node.keys;
|
|
516
|
+
if (this.comparator.isSame(value, nValue)) {
|
|
517
|
+
node = this.getNode(k[i + 1]);
|
|
518
|
+
break;
|
|
519
|
+
} else if (this.comparator.isLower(value, nValue)) {
|
|
520
|
+
node = this.getNode(k[i]);
|
|
521
|
+
break;
|
|
522
|
+
} else if (i + 1 === node.values.length) {
|
|
523
|
+
node = this.getNode(k[i + 1]);
|
|
524
|
+
break;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
return node;
|
|
529
|
+
}
|
|
530
|
+
leftestNode() {
|
|
531
|
+
let node = this.root;
|
|
532
|
+
while (!node.leaf) {
|
|
533
|
+
const keys = node.keys;
|
|
534
|
+
node = this.getNode(keys[0]);
|
|
535
|
+
}
|
|
536
|
+
return node;
|
|
537
|
+
}
|
|
538
|
+
commitHeadBuffer() {
|
|
539
|
+
if (this._headBuffer !== null) {
|
|
540
|
+
this.strategy.writeHead(this._headBuffer);
|
|
541
|
+
}
|
|
542
|
+
this.bufferForHeadUpdate(null);
|
|
543
|
+
}
|
|
544
|
+
commitNodeCreateBuffer() {
|
|
545
|
+
for (const node of this._nodeCreateBuffer.values()) {
|
|
546
|
+
this.strategy.write(node.id, node);
|
|
547
|
+
}
|
|
548
|
+
this._nodeCreateBuffer.clear();
|
|
549
|
+
}
|
|
550
|
+
commitNodeUpdateBuffer() {
|
|
551
|
+
for (const node of this._nodeUpdateBuffer.values()) {
|
|
552
|
+
this.strategy.write(node.id, node);
|
|
553
|
+
}
|
|
554
|
+
this._nodeUpdateBuffer.clear();
|
|
555
|
+
}
|
|
556
|
+
keys(condition) {
|
|
557
|
+
let result = null;
|
|
558
|
+
for (const k in condition) {
|
|
559
|
+
const key = k;
|
|
560
|
+
const value = condition[key];
|
|
561
|
+
const startNode = this.verifierStartNode[key](value);
|
|
562
|
+
const direction = this.verifierDirection[key];
|
|
563
|
+
const fullSearch = this.verifierFullSearch[key];
|
|
564
|
+
const comparator = this.verifierMap[key];
|
|
565
|
+
const pairs = this.getPairs(value, startNode, fullSearch, comparator, direction);
|
|
566
|
+
if (result === null) {
|
|
567
|
+
result = pairs.map((pair) => pair.key);
|
|
568
|
+
} else {
|
|
569
|
+
result = result.filter((key2) => pairs.find((p) => p.key === key2));
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
return new Set(result ?? []);
|
|
573
|
+
}
|
|
574
|
+
where(condition) {
|
|
575
|
+
let result = null;
|
|
576
|
+
for (const k in condition) {
|
|
577
|
+
const key = k;
|
|
578
|
+
const value = condition[key];
|
|
579
|
+
const startNode = this.verifierStartNode[key](value);
|
|
580
|
+
const direction = this.verifierDirection[key];
|
|
581
|
+
const fullSearch = this.verifierFullSearch[key];
|
|
582
|
+
const comparator = this.verifierMap[key];
|
|
583
|
+
const pairs = this.getPairs(value, startNode, fullSearch, comparator, direction);
|
|
584
|
+
if (result === null) {
|
|
585
|
+
result = pairs;
|
|
586
|
+
} else {
|
|
587
|
+
result = result.filter((pair) => pairs.find((p) => p.key === pair.key));
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
return result ?? [];
|
|
591
|
+
}
|
|
592
|
+
insert(key, value) {
|
|
593
|
+
const before = this.insertableNode(value);
|
|
594
|
+
this._insertAtLeaf(before, key, value);
|
|
595
|
+
if (before.values.length === this.order) {
|
|
596
|
+
const after = this._createNode(
|
|
597
|
+
[],
|
|
598
|
+
[],
|
|
599
|
+
true,
|
|
600
|
+
before.parent,
|
|
601
|
+
before.next,
|
|
602
|
+
before.id
|
|
603
|
+
);
|
|
604
|
+
const mid = Math.ceil(this.order / 2) - 1;
|
|
605
|
+
const beforeNext = before.next;
|
|
606
|
+
after.values = before.values.slice(mid + 1);
|
|
607
|
+
after.keys = before.keys.slice(mid + 1);
|
|
608
|
+
before.values = before.values.slice(0, mid + 1);
|
|
609
|
+
before.keys = before.keys.slice(0, mid + 1);
|
|
610
|
+
before.next = after.id;
|
|
611
|
+
if (beforeNext) {
|
|
612
|
+
const node = this.getNode(beforeNext);
|
|
613
|
+
node.prev = after.id;
|
|
614
|
+
this.bufferForNodeUpdate(node);
|
|
615
|
+
}
|
|
616
|
+
this._insertInParent(before, after.values[0], after);
|
|
617
|
+
this.bufferForNodeCreate(after);
|
|
618
|
+
this.bufferForNodeUpdate(before);
|
|
619
|
+
}
|
|
620
|
+
this.commitHeadBuffer();
|
|
621
|
+
this.commitNodeCreateBuffer();
|
|
622
|
+
this.commitNodeUpdateBuffer();
|
|
623
|
+
}
|
|
485
624
|
delete(key, value) {
|
|
486
625
|
const node = this.insertableNode(value);
|
|
487
626
|
let i = node.values.length;
|
|
@@ -489,35 +628,153 @@ var BPTree = class {
|
|
|
489
628
|
const nValue = node.values[i];
|
|
490
629
|
if (this.comparator.isSame(value, nValue)) {
|
|
491
630
|
const keys = node.keys[i];
|
|
492
|
-
if (keys.includes(key)) {
|
|
493
|
-
if (keys.length > 1) {
|
|
494
|
-
keys.splice(keys.indexOf(key), 1);
|
|
495
|
-
this.
|
|
496
|
-
} else if (node === this.root) {
|
|
497
|
-
node.values.splice(i, 1);
|
|
498
|
-
node.keys.splice(i, 1);
|
|
499
|
-
this.
|
|
500
|
-
} else {
|
|
501
|
-
keys.splice(keys.indexOf(key), 1);
|
|
502
|
-
node.keys.splice(i, 1);
|
|
503
|
-
node.values.splice(node.values.indexOf(value), 1);
|
|
504
|
-
this._deleteEntry(node, key, value);
|
|
505
|
-
this.
|
|
631
|
+
if (keys.includes(key)) {
|
|
632
|
+
if (keys.length > 1) {
|
|
633
|
+
keys.splice(keys.indexOf(key), 1);
|
|
634
|
+
this.bufferForNodeUpdate(node);
|
|
635
|
+
} else if (node === this.root) {
|
|
636
|
+
node.values.splice(i, 1);
|
|
637
|
+
node.keys.splice(i, 1);
|
|
638
|
+
this.bufferForNodeUpdate(node);
|
|
639
|
+
} else {
|
|
640
|
+
keys.splice(keys.indexOf(key), 1);
|
|
641
|
+
node.keys.splice(i, 1);
|
|
642
|
+
node.values.splice(node.values.indexOf(value), 1);
|
|
643
|
+
this._deleteEntry(node, key, value);
|
|
644
|
+
this.bufferForNodeUpdate(node);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
this.commitHeadBuffer();
|
|
650
|
+
this.commitNodeCreateBuffer();
|
|
651
|
+
this.commitNodeUpdateBuffer();
|
|
652
|
+
}
|
|
653
|
+
exists(key, value) {
|
|
654
|
+
const node = this.insertableNode(value);
|
|
655
|
+
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
656
|
+
const nValue = node.values[i];
|
|
657
|
+
if (this.comparator.isSame(value, nValue)) {
|
|
658
|
+
const keys = node.keys[i];
|
|
659
|
+
return keys.includes(key);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
return false;
|
|
663
|
+
}
|
|
664
|
+
setHeadData(data) {
|
|
665
|
+
this.data = data;
|
|
666
|
+
this.bufferForHeadUpdate(this.headState);
|
|
667
|
+
this.commitHeadBuffer();
|
|
668
|
+
}
|
|
669
|
+
forceUpdate(nodeId = null) {
|
|
670
|
+
const ids = nodeId === null ? [...this.nodes.keys()] : [nodeId];
|
|
671
|
+
for (const id of ids) {
|
|
672
|
+
this.nodes.delete(id);
|
|
673
|
+
this.getNode(id);
|
|
674
|
+
}
|
|
675
|
+
return ids.length;
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
|
|
679
|
+
// src/BPTreeAsync.ts
|
|
680
|
+
var BPTreeAsync = class extends BPTree {
|
|
681
|
+
constructor(strategy, comparator) {
|
|
682
|
+
super(strategy, comparator);
|
|
683
|
+
}
|
|
684
|
+
async _getPairsRightToLeft(value, startNode, fullSearch, comparator) {
|
|
685
|
+
const pairs = [];
|
|
686
|
+
let node = startNode;
|
|
687
|
+
let done = false;
|
|
688
|
+
let found = false;
|
|
689
|
+
while (!done) {
|
|
690
|
+
let i = node.values.length;
|
|
691
|
+
while (i--) {
|
|
692
|
+
const nValue = node.values[i];
|
|
693
|
+
const keys = node.keys[i];
|
|
694
|
+
if (comparator(nValue, value)) {
|
|
695
|
+
found = true;
|
|
696
|
+
let j = keys.length;
|
|
697
|
+
while (j--) {
|
|
698
|
+
pairs.push({ key: keys[j], value: nValue });
|
|
699
|
+
}
|
|
700
|
+
} else if (found && !fullSearch) {
|
|
701
|
+
done = true;
|
|
702
|
+
break;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
if (!node.prev) {
|
|
706
|
+
done = true;
|
|
707
|
+
break;
|
|
708
|
+
}
|
|
709
|
+
node = await this.getNode(node.prev);
|
|
710
|
+
}
|
|
711
|
+
return pairs.reverse();
|
|
712
|
+
}
|
|
713
|
+
async _getPairsLeftToRight(value, startNode, fullSearch, comparator) {
|
|
714
|
+
const pairs = [];
|
|
715
|
+
let node = startNode;
|
|
716
|
+
let done = false;
|
|
717
|
+
let found = false;
|
|
718
|
+
while (!done) {
|
|
719
|
+
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
720
|
+
const nValue = node.values[i];
|
|
721
|
+
const keys = node.keys[i];
|
|
722
|
+
if (comparator(nValue, value)) {
|
|
723
|
+
found = true;
|
|
724
|
+
for (const key of keys) {
|
|
725
|
+
pairs.push({ key, value: nValue });
|
|
506
726
|
}
|
|
727
|
+
} else if (found && !fullSearch) {
|
|
728
|
+
done = true;
|
|
729
|
+
break;
|
|
507
730
|
}
|
|
508
731
|
}
|
|
732
|
+
if (!node.next) {
|
|
733
|
+
done = true;
|
|
734
|
+
break;
|
|
735
|
+
}
|
|
736
|
+
node = await this.getNode(node.next);
|
|
509
737
|
}
|
|
510
|
-
|
|
511
|
-
this._emitCreates();
|
|
512
|
-
this._emitUpdates();
|
|
738
|
+
return pairs;
|
|
513
739
|
}
|
|
514
|
-
|
|
740
|
+
async getPairs(value, startNode, fullSearch, comparator, direction) {
|
|
741
|
+
switch (direction) {
|
|
742
|
+
case -1:
|
|
743
|
+
return await this._getPairsRightToLeft(value, startNode, fullSearch, comparator);
|
|
744
|
+
case 1:
|
|
745
|
+
return await this._getPairsLeftToRight(value, startNode, fullSearch, comparator);
|
|
746
|
+
default:
|
|
747
|
+
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
async _createNodeId() {
|
|
751
|
+
const id = await this.strategy.id();
|
|
752
|
+
if (id === 0) {
|
|
753
|
+
throw new Error(`The node's id should never be 0.`);
|
|
754
|
+
}
|
|
755
|
+
return id;
|
|
756
|
+
}
|
|
757
|
+
async _createNode(keys, values, leaf = false, parent = 0, next = 0, prev = 0) {
|
|
758
|
+
const id = await this._createNodeId();
|
|
759
|
+
const node = {
|
|
760
|
+
id,
|
|
761
|
+
keys,
|
|
762
|
+
values,
|
|
763
|
+
leaf,
|
|
764
|
+
parent,
|
|
765
|
+
next,
|
|
766
|
+
prev
|
|
767
|
+
};
|
|
768
|
+
this.nodes.set(id, node);
|
|
769
|
+
return node;
|
|
770
|
+
}
|
|
771
|
+
async _deleteEntry(node, key, value) {
|
|
515
772
|
if (!node.leaf) {
|
|
516
773
|
for (let i = 0, len = node.keys.length; i < len; i++) {
|
|
517
774
|
const nKey = node.keys[i];
|
|
518
775
|
if (nKey === key) {
|
|
519
776
|
node.keys.splice(i, 1);
|
|
520
|
-
this.
|
|
777
|
+
this.bufferForNodeUpdate(node);
|
|
521
778
|
break;
|
|
522
779
|
}
|
|
523
780
|
}
|
|
@@ -525,23 +782,23 @@ var BPTree = class {
|
|
|
525
782
|
const nValue = node.values[i];
|
|
526
783
|
if (this.comparator.isSame(value, nValue)) {
|
|
527
784
|
node.values.splice(i, 1);
|
|
528
|
-
this.
|
|
785
|
+
this.bufferForNodeUpdate(node);
|
|
529
786
|
break;
|
|
530
787
|
}
|
|
531
788
|
}
|
|
532
789
|
}
|
|
533
790
|
if (this.root === node && node.keys.length === 1) {
|
|
534
791
|
const keys = node.keys;
|
|
535
|
-
this.root = this.getNode(keys[0]);
|
|
792
|
+
this.root = await this.getNode(keys[0]);
|
|
536
793
|
this.root.parent = 0;
|
|
537
|
-
this.
|
|
538
|
-
this.
|
|
794
|
+
this.bufferForHeadUpdate(this.headState);
|
|
795
|
+
this.bufferForNodeUpdate(this.root);
|
|
539
796
|
return;
|
|
540
797
|
} else if (this.root === node) {
|
|
541
798
|
return;
|
|
542
799
|
} else if (node.keys.length < Math.ceil(this.order / 2) && !node.leaf || node.values.length < Math.ceil((this.order - 1) / 2) && node.leaf) {
|
|
543
800
|
let isPredecessor = false;
|
|
544
|
-
let parentNode = this.getNode(node.parent);
|
|
801
|
+
let parentNode = await this.getNode(node.parent);
|
|
545
802
|
let prevNode = null;
|
|
546
803
|
let nextNode = null;
|
|
547
804
|
let prevValue = null;
|
|
@@ -550,11 +807,11 @@ var BPTree = class {
|
|
|
550
807
|
const nKey = parentNode.keys[i];
|
|
551
808
|
if (nKey === node.id) {
|
|
552
809
|
if (i > 0) {
|
|
553
|
-
prevNode = this.getNode(parentNode.keys[i - 1]);
|
|
810
|
+
prevNode = await this.getNode(parentNode.keys[i - 1]);
|
|
554
811
|
prevValue = parentNode.values[i - 1];
|
|
555
812
|
}
|
|
556
813
|
if (i < parentNode.keys.length - 1) {
|
|
557
|
-
nextNode = this.getNode(parentNode.keys[i + 1]);
|
|
814
|
+
nextNode = await this.getNode(parentNode.keys[i + 1]);
|
|
558
815
|
postValue = parentNode.values[i];
|
|
559
816
|
}
|
|
560
817
|
}
|
|
@@ -591,14 +848,14 @@ var BPTree = class {
|
|
|
591
848
|
pointer.next = node.next;
|
|
592
849
|
pointer.prev = node.id;
|
|
593
850
|
if (pointer.next) {
|
|
594
|
-
const n = this.getNode(node.next);
|
|
851
|
+
const n = await this.getNode(node.next);
|
|
595
852
|
n.prev = pointer.id;
|
|
596
|
-
this.
|
|
853
|
+
this.bufferForNodeUpdate(n);
|
|
597
854
|
}
|
|
598
855
|
if (pointer.prev) {
|
|
599
|
-
const n = this.getNode(node.id);
|
|
856
|
+
const n = await this.getNode(node.id);
|
|
600
857
|
n.next = pointer.id;
|
|
601
|
-
this.
|
|
858
|
+
this.bufferForNodeUpdate(n);
|
|
602
859
|
}
|
|
603
860
|
if (isPredecessor) {
|
|
604
861
|
pointer.prev = 0;
|
|
@@ -608,13 +865,13 @@ var BPTree = class {
|
|
|
608
865
|
if (!pointer.leaf) {
|
|
609
866
|
const keys = pointer.keys;
|
|
610
867
|
for (const key2 of keys) {
|
|
611
|
-
const node2 = this.getNode(key2);
|
|
868
|
+
const node2 = await this.getNode(key2);
|
|
612
869
|
node2.parent = pointer.id;
|
|
613
|
-
this.
|
|
870
|
+
this.bufferForNodeUpdate(node2);
|
|
614
871
|
}
|
|
615
872
|
}
|
|
616
|
-
this._deleteEntry(this.getNode(node.parent), node.id, guess);
|
|
617
|
-
this.
|
|
873
|
+
await this._deleteEntry(await this.getNode(node.parent), node.id, guess);
|
|
874
|
+
this.bufferForNodeUpdate(pointer);
|
|
618
875
|
} else {
|
|
619
876
|
if (isPredecessor) {
|
|
620
877
|
let pointerPm;
|
|
@@ -624,12 +881,12 @@ var BPTree = class {
|
|
|
624
881
|
pointerKm = pointer.values.splice(-1)[0];
|
|
625
882
|
node.keys = [pointerPm, ...node.keys];
|
|
626
883
|
node.values = [guess, ...node.values];
|
|
627
|
-
parentNode = this.getNode(node.parent);
|
|
884
|
+
parentNode = await this.getNode(node.parent);
|
|
628
885
|
for (let i = 0, len = parentNode.values.length; i < len; i++) {
|
|
629
886
|
const nValue = parentNode.values[i];
|
|
630
887
|
if (this.comparator.isSame(guess, nValue)) {
|
|
631
888
|
parentNode.values[i] = pointerKm;
|
|
632
|
-
this.
|
|
889
|
+
this.bufferForNodeUpdate(parentNode);
|
|
633
890
|
break;
|
|
634
891
|
}
|
|
635
892
|
}
|
|
@@ -638,18 +895,18 @@ var BPTree = class {
|
|
|
638
895
|
pointerKm = pointer.values.splice(-1)[0];
|
|
639
896
|
node.keys = [pointerPm, ...node.keys];
|
|
640
897
|
node.values = [pointerKm, ...node.values];
|
|
641
|
-
parentNode = this.getNode(node.parent);
|
|
898
|
+
parentNode = await this.getNode(node.parent);
|
|
642
899
|
for (let i = 0, len = parentNode.values.length; i < len; i++) {
|
|
643
900
|
const nValue = parentNode.values[i];
|
|
644
901
|
if (this.comparator.isSame(guess, nValue)) {
|
|
645
902
|
parentNode.values[i] = pointerKm;
|
|
646
|
-
this.
|
|
903
|
+
this.bufferForNodeUpdate(parentNode);
|
|
647
904
|
break;
|
|
648
905
|
}
|
|
649
906
|
}
|
|
650
907
|
}
|
|
651
|
-
this.
|
|
652
|
-
this.
|
|
908
|
+
this.bufferForNodeUpdate(node);
|
|
909
|
+
this.bufferForNodeUpdate(pointer);
|
|
653
910
|
} else {
|
|
654
911
|
let pointerP0;
|
|
655
912
|
let pointerK0;
|
|
@@ -658,12 +915,12 @@ var BPTree = class {
|
|
|
658
915
|
pointerK0 = pointer.values.splice(0, 1)[0];
|
|
659
916
|
node.keys = [...node.keys, pointerP0];
|
|
660
917
|
node.values = [...node.values, guess];
|
|
661
|
-
parentNode = this.getNode(node.parent);
|
|
918
|
+
parentNode = await this.getNode(node.parent);
|
|
662
919
|
for (let i = 0, len = parentNode.values.length; i < len; i++) {
|
|
663
920
|
const nValue = parentNode.values[i];
|
|
664
921
|
if (this.comparator.isSame(guess, nValue)) {
|
|
665
922
|
parentNode.values[i] = pointerK0;
|
|
666
|
-
this.
|
|
923
|
+
this.bufferForNodeUpdate(parentNode);
|
|
667
924
|
break;
|
|
668
925
|
}
|
|
669
926
|
}
|
|
@@ -672,72 +929,299 @@ var BPTree = class {
|
|
|
672
929
|
pointerK0 = pointer.values.splice(0, 1)[0];
|
|
673
930
|
node.keys = [...node.keys, pointerP0];
|
|
674
931
|
node.values = [...node.values, pointerK0];
|
|
675
|
-
parentNode = this.getNode(node.parent);
|
|
932
|
+
parentNode = await this.getNode(node.parent);
|
|
676
933
|
for (let i = 0, len = parentNode.values.length; i < len; i++) {
|
|
677
934
|
const nValue = parentNode.values[i];
|
|
678
935
|
if (this.comparator.isSame(guess, nValue)) {
|
|
679
936
|
parentNode.values[i] = pointer.values[0];
|
|
680
|
-
this.
|
|
937
|
+
this.bufferForNodeUpdate(parentNode);
|
|
681
938
|
break;
|
|
682
939
|
}
|
|
683
940
|
}
|
|
684
941
|
}
|
|
685
|
-
this.
|
|
686
|
-
this.
|
|
942
|
+
this.bufferForNodeUpdate(node);
|
|
943
|
+
this.bufferForNodeUpdate(pointer);
|
|
687
944
|
}
|
|
688
945
|
if (!pointer.leaf) {
|
|
689
946
|
for (const key2 of pointer.keys) {
|
|
690
|
-
const n = this.getNode(key2);
|
|
947
|
+
const n = await this.getNode(key2);
|
|
691
948
|
n.parent = pointer.id;
|
|
692
|
-
this.
|
|
949
|
+
this.bufferForNodeUpdate(n);
|
|
693
950
|
}
|
|
694
951
|
}
|
|
695
952
|
if (!node.leaf) {
|
|
696
953
|
for (const key2 of node.keys) {
|
|
697
|
-
const n = this.getNode(key2);
|
|
954
|
+
const n = await this.getNode(key2);
|
|
698
955
|
n.parent = node.id;
|
|
699
|
-
this.
|
|
956
|
+
this.bufferForNodeUpdate(n);
|
|
700
957
|
}
|
|
701
958
|
}
|
|
702
959
|
if (!parentNode.leaf) {
|
|
703
960
|
for (const key2 of parentNode.keys) {
|
|
704
|
-
const n = this.getNode(key2);
|
|
961
|
+
const n = await this.getNode(key2);
|
|
705
962
|
n.parent = parentNode.id;
|
|
706
|
-
this.
|
|
963
|
+
this.bufferForNodeUpdate(n);
|
|
707
964
|
}
|
|
708
965
|
}
|
|
709
966
|
}
|
|
710
967
|
}
|
|
711
968
|
}
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
969
|
+
async _insertInParent(node, value, pointer) {
|
|
970
|
+
if (this.root === node) {
|
|
971
|
+
const root = await this._createNode([node.id, pointer.id], [value]);
|
|
972
|
+
this.root = root;
|
|
973
|
+
node.parent = root.id;
|
|
974
|
+
pointer.parent = root.id;
|
|
975
|
+
this.bufferForHeadUpdate(this.headState);
|
|
976
|
+
this.bufferForNodeCreate(root);
|
|
977
|
+
this.bufferForNodeUpdate(node);
|
|
978
|
+
this.bufferForNodeUpdate(pointer);
|
|
979
|
+
return;
|
|
980
|
+
}
|
|
981
|
+
const parentNode = await this.getNode(node.parent);
|
|
982
|
+
for (let i = 0, len = parentNode.keys.length; i < len; i++) {
|
|
983
|
+
const nKeys = parentNode.keys[i];
|
|
984
|
+
if (nKeys === node.id) {
|
|
985
|
+
parentNode.values.splice(i, 0, value);
|
|
986
|
+
parentNode.keys.splice(i + 1, 0, pointer.id);
|
|
987
|
+
this.bufferForNodeUpdate(parentNode);
|
|
988
|
+
if (parentNode.keys.length > this.order) {
|
|
989
|
+
const parentPointer = await this._createNode([], []);
|
|
990
|
+
parentPointer.parent = parentNode.parent;
|
|
991
|
+
const mid = Math.ceil(this.order / 2) - 1;
|
|
992
|
+
parentPointer.values = parentNode.values.slice(mid + 1);
|
|
993
|
+
parentPointer.keys = parentNode.keys.slice(mid + 1);
|
|
994
|
+
const midValue = parentNode.values[mid];
|
|
995
|
+
if (mid === 0) {
|
|
996
|
+
parentNode.values = parentNode.values.slice(0, mid + 1);
|
|
997
|
+
} else {
|
|
998
|
+
parentNode.values = parentNode.values.slice(0, mid);
|
|
999
|
+
}
|
|
1000
|
+
parentNode.keys = parentNode.keys.slice(0, mid + 1);
|
|
1001
|
+
for (const k of parentNode.keys) {
|
|
1002
|
+
const node2 = await this.getNode(k);
|
|
1003
|
+
node2.parent = parentNode.id;
|
|
1004
|
+
this.bufferForNodeUpdate(node2);
|
|
1005
|
+
}
|
|
1006
|
+
for (const k of parentPointer.keys) {
|
|
1007
|
+
const node2 = await this.getNode(k);
|
|
1008
|
+
node2.parent = parentPointer.id;
|
|
1009
|
+
this.bufferForNodeUpdate(node2);
|
|
1010
|
+
}
|
|
1011
|
+
await this._insertInParent(parentNode, midValue, parentPointer);
|
|
1012
|
+
this.bufferForNodeCreate(parentPointer);
|
|
1013
|
+
this.bufferForNodeUpdate(parentNode);
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
719
1017
|
}
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
1018
|
+
async init() {
|
|
1019
|
+
const head = await this.strategy.readHead();
|
|
1020
|
+
if (head === null) {
|
|
1021
|
+
this.order = this.strategy.order;
|
|
1022
|
+
this.data = {};
|
|
1023
|
+
this.root = await this._createNode([], [], true);
|
|
1024
|
+
this.bufferForHeadUpdate(this.headState);
|
|
1025
|
+
this.bufferForNodeCreate(this.root);
|
|
1026
|
+
this.commitHeadBuffer();
|
|
1027
|
+
this.commitNodeCreateBuffer();
|
|
1028
|
+
} else {
|
|
1029
|
+
const { root, order, data } = head;
|
|
1030
|
+
this.order = order;
|
|
1031
|
+
this.data = data ?? {};
|
|
1032
|
+
this.root = await this.getNode(root);
|
|
1033
|
+
}
|
|
1034
|
+
if (this.order < 3) {
|
|
1035
|
+
throw new Error(`The 'order' parameter must be greater than 2. but got a '${this.order}'.`);
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
async getNode(id) {
|
|
1039
|
+
if (!this.nodes.has(id)) {
|
|
1040
|
+
this.nodes.set(id, await this.strategy.read(id));
|
|
1041
|
+
}
|
|
1042
|
+
return this.nodes.get(id);
|
|
1043
|
+
}
|
|
1044
|
+
async insertableNode(value) {
|
|
1045
|
+
let node = this.root;
|
|
1046
|
+
while (!node.leaf) {
|
|
1047
|
+
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
1048
|
+
const nValue = node.values[i];
|
|
1049
|
+
const k = node.keys;
|
|
1050
|
+
if (this.comparator.isSame(value, nValue)) {
|
|
1051
|
+
node = await this.getNode(k[i + 1]);
|
|
1052
|
+
break;
|
|
1053
|
+
} else if (this.comparator.isLower(value, nValue)) {
|
|
1054
|
+
node = await this.getNode(k[i]);
|
|
1055
|
+
break;
|
|
1056
|
+
} else if (i + 1 === node.values.length) {
|
|
1057
|
+
node = await this.getNode(k[i + 1]);
|
|
1058
|
+
break;
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
return node;
|
|
1063
|
+
}
|
|
1064
|
+
async leftestNode() {
|
|
1065
|
+
let node = this.root;
|
|
1066
|
+
while (!node.leaf) {
|
|
1067
|
+
const keys = node.keys;
|
|
1068
|
+
node = await this.getNode(keys[0]);
|
|
1069
|
+
}
|
|
1070
|
+
return node;
|
|
1071
|
+
}
|
|
1072
|
+
async commitHeadBuffer() {
|
|
1073
|
+
if (this._headBuffer !== null) {
|
|
1074
|
+
await this.strategy.writeHead(this._headBuffer);
|
|
1075
|
+
}
|
|
1076
|
+
this.bufferForHeadUpdate(null);
|
|
1077
|
+
}
|
|
1078
|
+
async commitNodeCreateBuffer() {
|
|
1079
|
+
for (const node of this._nodeCreateBuffer.values()) {
|
|
1080
|
+
await this.strategy.write(node.id, node);
|
|
1081
|
+
}
|
|
1082
|
+
this._nodeCreateBuffer.clear();
|
|
1083
|
+
}
|
|
1084
|
+
async commitNodeUpdateBuffer() {
|
|
1085
|
+
for (const node of this._nodeUpdateBuffer.values()) {
|
|
1086
|
+
await this.strategy.write(node.id, node);
|
|
1087
|
+
}
|
|
1088
|
+
this._nodeUpdateBuffer.clear();
|
|
1089
|
+
}
|
|
1090
|
+
async keys(condition) {
|
|
1091
|
+
let result = null;
|
|
1092
|
+
for (const k in condition) {
|
|
1093
|
+
const key = k;
|
|
1094
|
+
const value = condition[key];
|
|
1095
|
+
const startNode = await this.verifierStartNode[key](value);
|
|
1096
|
+
const direction = this.verifierDirection[key];
|
|
1097
|
+
const fullSearch = this.verifierFullSearch[key];
|
|
1098
|
+
const comparator = this.verifierMap[key];
|
|
1099
|
+
const pairs = await this.getPairs(value, startNode, fullSearch, comparator, direction);
|
|
1100
|
+
if (result === null) {
|
|
1101
|
+
result = pairs.map((pair) => pair.key);
|
|
1102
|
+
} else {
|
|
1103
|
+
result = result.filter((key2) => pairs.find((p) => p.key === key2));
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
return new Set(result ?? []);
|
|
1107
|
+
}
|
|
1108
|
+
async where(condition) {
|
|
1109
|
+
let result = null;
|
|
1110
|
+
for (const k in condition) {
|
|
1111
|
+
const key = k;
|
|
1112
|
+
const value = condition[key];
|
|
1113
|
+
const startNode = await this.verifierStartNode[key](value);
|
|
1114
|
+
const direction = this.verifierDirection[key];
|
|
1115
|
+
const fullSearch = this.verifierFullSearch[key];
|
|
1116
|
+
const comparator = this.verifierMap[key];
|
|
1117
|
+
const pairs = await this.getPairs(value, startNode, fullSearch, comparator, direction);
|
|
1118
|
+
if (result === null) {
|
|
1119
|
+
result = pairs;
|
|
1120
|
+
} else {
|
|
1121
|
+
result = result.filter((pair) => pairs.find((p) => p.key === pair.key));
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
return result ?? [];
|
|
1125
|
+
}
|
|
1126
|
+
async insert(key, value) {
|
|
1127
|
+
const before = await this.insertableNode(value);
|
|
1128
|
+
this._insertAtLeaf(before, key, value);
|
|
1129
|
+
if (before.values.length === this.order) {
|
|
1130
|
+
const after = await this._createNode(
|
|
1131
|
+
[],
|
|
1132
|
+
[],
|
|
1133
|
+
true,
|
|
1134
|
+
before.parent,
|
|
1135
|
+
before.next,
|
|
1136
|
+
before.id
|
|
1137
|
+
);
|
|
1138
|
+
const mid = Math.ceil(this.order / 2) - 1;
|
|
1139
|
+
const beforeNext = before.next;
|
|
1140
|
+
after.values = before.values.slice(mid + 1);
|
|
1141
|
+
after.keys = before.keys.slice(mid + 1);
|
|
1142
|
+
before.values = before.values.slice(0, mid + 1);
|
|
1143
|
+
before.keys = before.keys.slice(0, mid + 1);
|
|
1144
|
+
before.next = after.id;
|
|
1145
|
+
if (beforeNext) {
|
|
1146
|
+
const node = await this.getNode(beforeNext);
|
|
1147
|
+
node.prev = after.id;
|
|
1148
|
+
this.bufferForNodeUpdate(node);
|
|
1149
|
+
}
|
|
1150
|
+
await this._insertInParent(before, after.values[0], after);
|
|
1151
|
+
this.bufferForNodeCreate(after);
|
|
1152
|
+
this.bufferForNodeUpdate(before);
|
|
1153
|
+
}
|
|
1154
|
+
await this.commitHeadBuffer();
|
|
1155
|
+
await this.commitNodeCreateBuffer();
|
|
1156
|
+
await this.commitNodeUpdateBuffer();
|
|
1157
|
+
}
|
|
1158
|
+
async delete(key, value) {
|
|
1159
|
+
const node = await this.insertableNode(value);
|
|
1160
|
+
let i = node.values.length;
|
|
1161
|
+
while (i--) {
|
|
1162
|
+
const nValue = node.values[i];
|
|
1163
|
+
if (this.comparator.isSame(value, nValue)) {
|
|
1164
|
+
const keys = node.keys[i];
|
|
1165
|
+
if (keys.includes(key)) {
|
|
1166
|
+
if (keys.length > 1) {
|
|
1167
|
+
keys.splice(keys.indexOf(key), 1);
|
|
1168
|
+
this.bufferForNodeUpdate(node);
|
|
1169
|
+
} else if (node === this.root) {
|
|
1170
|
+
node.values.splice(i, 1);
|
|
1171
|
+
node.keys.splice(i, 1);
|
|
1172
|
+
this.bufferForNodeUpdate(node);
|
|
1173
|
+
} else {
|
|
1174
|
+
keys.splice(keys.indexOf(key), 1);
|
|
1175
|
+
node.keys.splice(i, 1);
|
|
1176
|
+
node.values.splice(node.values.indexOf(value), 1);
|
|
1177
|
+
await this._deleteEntry(node, key, value);
|
|
1178
|
+
this.bufferForNodeUpdate(node);
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
await this.commitHeadBuffer();
|
|
1184
|
+
await this.commitNodeCreateBuffer();
|
|
1185
|
+
await this.commitNodeUpdateBuffer();
|
|
1186
|
+
}
|
|
1187
|
+
async exists(key, value) {
|
|
1188
|
+
const node = await this.insertableNode(value);
|
|
1189
|
+
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
1190
|
+
const nValue = node.values[i];
|
|
1191
|
+
if (this.comparator.isSame(value, nValue)) {
|
|
1192
|
+
const keys = node.keys[i];
|
|
1193
|
+
return keys.includes(key);
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
return false;
|
|
1197
|
+
}
|
|
1198
|
+
async setHeadData(data) {
|
|
727
1199
|
this.data = data;
|
|
728
|
-
this.
|
|
729
|
-
this.
|
|
1200
|
+
this.bufferForHeadUpdate(this.headState);
|
|
1201
|
+
await this.commitHeadBuffer();
|
|
1202
|
+
}
|
|
1203
|
+
async forceUpdate(nodeId = null) {
|
|
1204
|
+
const ids = nodeId === null ? [...this.nodes.keys()] : [nodeId];
|
|
1205
|
+
for (const id of ids) {
|
|
1206
|
+
this.nodes.delete(id);
|
|
1207
|
+
await this.getNode(id);
|
|
1208
|
+
}
|
|
1209
|
+
return ids.length;
|
|
730
1210
|
}
|
|
731
1211
|
};
|
|
732
1212
|
|
|
733
|
-
// src/SerializeStrategy.ts
|
|
1213
|
+
// src/base/SerializeStrategy.ts
|
|
734
1214
|
var SerializeStrategy = class {
|
|
735
1215
|
order;
|
|
736
1216
|
constructor(order) {
|
|
737
1217
|
this.order = order;
|
|
738
1218
|
}
|
|
739
1219
|
};
|
|
740
|
-
|
|
1220
|
+
|
|
1221
|
+
// src/SerializeStrategySync.ts
|
|
1222
|
+
var SerializeStrategySync = class extends SerializeStrategy {
|
|
1223
|
+
};
|
|
1224
|
+
var InMemoryStoreStrategySync = class extends SerializeStrategySync {
|
|
741
1225
|
data;
|
|
742
1226
|
constructor(order) {
|
|
743
1227
|
super(order);
|
|
@@ -766,6 +1250,38 @@ var InMemoryStoreStrategy = class extends SerializeStrategy {
|
|
|
766
1250
|
}
|
|
767
1251
|
};
|
|
768
1252
|
|
|
1253
|
+
// src/SerializeStrategyAsync.ts
|
|
1254
|
+
var SerializeStrategyAsync = class extends SerializeStrategy {
|
|
1255
|
+
};
|
|
1256
|
+
var InMemoryStoreStrategyAsync = class extends SerializeStrategyAsync {
|
|
1257
|
+
data;
|
|
1258
|
+
constructor(order) {
|
|
1259
|
+
super(order);
|
|
1260
|
+
this.data = {
|
|
1261
|
+
head: null,
|
|
1262
|
+
node: {}
|
|
1263
|
+
};
|
|
1264
|
+
}
|
|
1265
|
+
async id() {
|
|
1266
|
+
return Math.ceil(Math.random() * Number.MAX_SAFE_INTEGER - 1);
|
|
1267
|
+
}
|
|
1268
|
+
async read(id) {
|
|
1269
|
+
if (!Object.prototype.hasOwnProperty.call(this.data.node, id)) {
|
|
1270
|
+
throw new Error(`The tree attempted to reference node '${id}', but couldn't find the corresponding node.`);
|
|
1271
|
+
}
|
|
1272
|
+
return this.data.node[id];
|
|
1273
|
+
}
|
|
1274
|
+
async write(id, node) {
|
|
1275
|
+
this.data.node[id] = node;
|
|
1276
|
+
}
|
|
1277
|
+
async readHead() {
|
|
1278
|
+
return this.data.head;
|
|
1279
|
+
}
|
|
1280
|
+
async writeHead(head) {
|
|
1281
|
+
this.data.head = head;
|
|
1282
|
+
}
|
|
1283
|
+
};
|
|
1284
|
+
|
|
769
1285
|
// src/ValueComparator.ts
|
|
770
1286
|
var ValueComparator = class {
|
|
771
1287
|
isLower(value, than) {
|
|
@@ -789,10 +1305,13 @@ var StringComparator = class extends ValueComparator {
|
|
|
789
1305
|
}
|
|
790
1306
|
};
|
|
791
1307
|
export {
|
|
792
|
-
|
|
793
|
-
|
|
1308
|
+
BPTreeAsync,
|
|
1309
|
+
BPTreeSync,
|
|
1310
|
+
InMemoryStoreStrategyAsync,
|
|
1311
|
+
InMemoryStoreStrategySync,
|
|
794
1312
|
NumericComparator,
|
|
795
|
-
|
|
1313
|
+
SerializeStrategyAsync,
|
|
1314
|
+
SerializeStrategySync,
|
|
796
1315
|
StringComparator,
|
|
797
1316
|
ValueComparator
|
|
798
1317
|
};
|