serializable-bptree 3.2.3 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/{index.js → index.cjs} +419 -91
- package/dist/esm/{index.js → index.mjs} +419 -91
- package/dist/typings/BPTreeAsync.d.ts +3 -3
- package/dist/typings/BPTreeSync.d.ts +0 -1
- package/dist/typings/base/BPTree.d.ts +5 -5
- package/dist/typings/base/SerializeStrategy.d.ts +1 -0
- package/package.json +13 -3
- package/dist/typings/utils/CacheStorage.d.ts +0 -3
|
@@ -27,19 +27,374 @@ var StringComparator = class extends ValueComparator {
|
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
//
|
|
31
|
-
var
|
|
30
|
+
// node_modules/cachebranch/dist/esm/index.mjs
|
|
31
|
+
var CacheBranch = class {
|
|
32
|
+
data;
|
|
33
|
+
branches;
|
|
34
|
+
constructor(data) {
|
|
35
|
+
this.data = data;
|
|
36
|
+
this.branches = /* @__PURE__ */ new Map();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The method splits the provided key value into tokens and returns them as an array.
|
|
40
|
+
* For instance, if you pass `'user/name/middle'` as the parameter, it will return `['user', 'name', 'middle']` as the split values.
|
|
41
|
+
* @param key The key value to split.
|
|
42
|
+
*/
|
|
43
|
+
tokens(key) {
|
|
44
|
+
return key.split("/");
|
|
45
|
+
}
|
|
46
|
+
to(key, getNextBranch) {
|
|
47
|
+
const tokens = this.tokens(key);
|
|
48
|
+
let current = this;
|
|
49
|
+
for (let i = 0, len = tokens.length; i < len; i++) {
|
|
50
|
+
const last = i === len - 1;
|
|
51
|
+
const key2 = tokens[i];
|
|
52
|
+
const next = getNextBranch(current, key2, i, last);
|
|
53
|
+
if (next === null) {
|
|
54
|
+
return void 0;
|
|
55
|
+
}
|
|
56
|
+
current = next;
|
|
57
|
+
}
|
|
58
|
+
return current;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
var VOID = -1;
|
|
62
|
+
var PRIMITIVE = 0;
|
|
63
|
+
var ARRAY = 1;
|
|
64
|
+
var OBJECT = 2;
|
|
65
|
+
var DATE = 3;
|
|
66
|
+
var REGEXP = 4;
|
|
67
|
+
var MAP = 5;
|
|
68
|
+
var SET = 6;
|
|
69
|
+
var ERROR = 7;
|
|
70
|
+
var BIGINT = 8;
|
|
71
|
+
var env = typeof self === "object" ? self : globalThis;
|
|
72
|
+
var deserializer = ($, _) => {
|
|
73
|
+
const as = (out, index) => {
|
|
74
|
+
$.set(index, out);
|
|
75
|
+
return out;
|
|
76
|
+
};
|
|
77
|
+
const unpair = (index) => {
|
|
78
|
+
if ($.has(index))
|
|
79
|
+
return $.get(index);
|
|
80
|
+
const [type, value] = _[index];
|
|
81
|
+
switch (type) {
|
|
82
|
+
case PRIMITIVE:
|
|
83
|
+
case VOID:
|
|
84
|
+
return as(value, index);
|
|
85
|
+
case ARRAY: {
|
|
86
|
+
const arr = as([], index);
|
|
87
|
+
for (const index2 of value)
|
|
88
|
+
arr.push(unpair(index2));
|
|
89
|
+
return arr;
|
|
90
|
+
}
|
|
91
|
+
case OBJECT: {
|
|
92
|
+
const object = as({}, index);
|
|
93
|
+
for (const [key, index2] of value)
|
|
94
|
+
object[unpair(key)] = unpair(index2);
|
|
95
|
+
return object;
|
|
96
|
+
}
|
|
97
|
+
case DATE:
|
|
98
|
+
return as(new Date(value), index);
|
|
99
|
+
case REGEXP: {
|
|
100
|
+
const { source, flags } = value;
|
|
101
|
+
return as(new RegExp(source, flags), index);
|
|
102
|
+
}
|
|
103
|
+
case MAP: {
|
|
104
|
+
const map = as(/* @__PURE__ */ new Map(), index);
|
|
105
|
+
for (const [key, index2] of value)
|
|
106
|
+
map.set(unpair(key), unpair(index2));
|
|
107
|
+
return map;
|
|
108
|
+
}
|
|
109
|
+
case SET: {
|
|
110
|
+
const set = as(/* @__PURE__ */ new Set(), index);
|
|
111
|
+
for (const index2 of value)
|
|
112
|
+
set.add(unpair(index2));
|
|
113
|
+
return set;
|
|
114
|
+
}
|
|
115
|
+
case ERROR: {
|
|
116
|
+
const { name, message } = value;
|
|
117
|
+
return as(new env[name](message), index);
|
|
118
|
+
}
|
|
119
|
+
case BIGINT:
|
|
120
|
+
return as(BigInt(value), index);
|
|
121
|
+
case "BigInt":
|
|
122
|
+
return as(Object(BigInt(value)), index);
|
|
123
|
+
}
|
|
124
|
+
return as(new env[type](value), index);
|
|
125
|
+
};
|
|
126
|
+
return unpair;
|
|
127
|
+
};
|
|
128
|
+
var deserialize = (serialized) => deserializer(/* @__PURE__ */ new Map(), serialized)(0);
|
|
129
|
+
var EMPTY = "";
|
|
130
|
+
var { toString } = {};
|
|
131
|
+
var { keys } = Object;
|
|
132
|
+
var typeOf = (value) => {
|
|
133
|
+
const type = typeof value;
|
|
134
|
+
if (type !== "object" || !value)
|
|
135
|
+
return [PRIMITIVE, type];
|
|
136
|
+
const asString = toString.call(value).slice(8, -1);
|
|
137
|
+
switch (asString) {
|
|
138
|
+
case "Array":
|
|
139
|
+
return [ARRAY, EMPTY];
|
|
140
|
+
case "Object":
|
|
141
|
+
return [OBJECT, EMPTY];
|
|
142
|
+
case "Date":
|
|
143
|
+
return [DATE, EMPTY];
|
|
144
|
+
case "RegExp":
|
|
145
|
+
return [REGEXP, EMPTY];
|
|
146
|
+
case "Map":
|
|
147
|
+
return [MAP, EMPTY];
|
|
148
|
+
case "Set":
|
|
149
|
+
return [SET, EMPTY];
|
|
150
|
+
}
|
|
151
|
+
if (asString.includes("Array"))
|
|
152
|
+
return [ARRAY, asString];
|
|
153
|
+
if (asString.includes("Error"))
|
|
154
|
+
return [ERROR, asString];
|
|
155
|
+
return [OBJECT, asString];
|
|
156
|
+
};
|
|
157
|
+
var shouldSkip = ([TYPE, type]) => TYPE === PRIMITIVE && (type === "function" || type === "symbol");
|
|
158
|
+
var serializer = (strict, json, $, _) => {
|
|
159
|
+
const as = (out, value) => {
|
|
160
|
+
const index = _.push(out) - 1;
|
|
161
|
+
$.set(value, index);
|
|
162
|
+
return index;
|
|
163
|
+
};
|
|
164
|
+
const pair = (value) => {
|
|
165
|
+
if ($.has(value))
|
|
166
|
+
return $.get(value);
|
|
167
|
+
let [TYPE, type] = typeOf(value);
|
|
168
|
+
switch (TYPE) {
|
|
169
|
+
case PRIMITIVE: {
|
|
170
|
+
let entry = value;
|
|
171
|
+
switch (type) {
|
|
172
|
+
case "bigint":
|
|
173
|
+
TYPE = BIGINT;
|
|
174
|
+
entry = value.toString();
|
|
175
|
+
break;
|
|
176
|
+
case "function":
|
|
177
|
+
case "symbol":
|
|
178
|
+
if (strict)
|
|
179
|
+
throw new TypeError("unable to serialize " + type);
|
|
180
|
+
entry = null;
|
|
181
|
+
break;
|
|
182
|
+
case "undefined":
|
|
183
|
+
return as([VOID], value);
|
|
184
|
+
}
|
|
185
|
+
return as([TYPE, entry], value);
|
|
186
|
+
}
|
|
187
|
+
case ARRAY: {
|
|
188
|
+
if (type)
|
|
189
|
+
return as([type, [...value]], value);
|
|
190
|
+
const arr = [];
|
|
191
|
+
const index = as([TYPE, arr], value);
|
|
192
|
+
for (const entry of value)
|
|
193
|
+
arr.push(pair(entry));
|
|
194
|
+
return index;
|
|
195
|
+
}
|
|
196
|
+
case OBJECT: {
|
|
197
|
+
if (type) {
|
|
198
|
+
switch (type) {
|
|
199
|
+
case "BigInt":
|
|
200
|
+
return as([type, value.toString()], value);
|
|
201
|
+
case "Boolean":
|
|
202
|
+
case "Number":
|
|
203
|
+
case "String":
|
|
204
|
+
return as([type, value.valueOf()], value);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (json && "toJSON" in value)
|
|
208
|
+
return pair(value.toJSON());
|
|
209
|
+
const entries = [];
|
|
210
|
+
const index = as([TYPE, entries], value);
|
|
211
|
+
for (const key of keys(value)) {
|
|
212
|
+
if (strict || !shouldSkip(typeOf(value[key])))
|
|
213
|
+
entries.push([pair(key), pair(value[key])]);
|
|
214
|
+
}
|
|
215
|
+
return index;
|
|
216
|
+
}
|
|
217
|
+
case DATE:
|
|
218
|
+
return as([TYPE, value.toISOString()], value);
|
|
219
|
+
case REGEXP: {
|
|
220
|
+
const { source, flags } = value;
|
|
221
|
+
return as([TYPE, { source, flags }], value);
|
|
222
|
+
}
|
|
223
|
+
case MAP: {
|
|
224
|
+
const entries = [];
|
|
225
|
+
const index = as([TYPE, entries], value);
|
|
226
|
+
for (const [key, entry] of value) {
|
|
227
|
+
if (strict || !(shouldSkip(typeOf(key)) || shouldSkip(typeOf(entry))))
|
|
228
|
+
entries.push([pair(key), pair(entry)]);
|
|
229
|
+
}
|
|
230
|
+
return index;
|
|
231
|
+
}
|
|
232
|
+
case SET: {
|
|
233
|
+
const entries = [];
|
|
234
|
+
const index = as([TYPE, entries], value);
|
|
235
|
+
for (const entry of value) {
|
|
236
|
+
if (strict || !shouldSkip(typeOf(entry)))
|
|
237
|
+
entries.push(pair(entry));
|
|
238
|
+
}
|
|
239
|
+
return index;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
const { message } = value;
|
|
243
|
+
return as([TYPE, { name: type, message }], value);
|
|
244
|
+
};
|
|
245
|
+
return pair;
|
|
246
|
+
};
|
|
247
|
+
var serialize = (value, { json, lossy } = {}) => {
|
|
248
|
+
const _ = [];
|
|
249
|
+
return serializer(!(json || lossy), !!json, /* @__PURE__ */ new Map(), _)(value), _;
|
|
250
|
+
};
|
|
251
|
+
var esm_default = typeof structuredClone === "function" ? (
|
|
252
|
+
/* c8 ignore start */
|
|
253
|
+
(any, options) => options && ("json" in options || "lossy" in options) ? deserialize(serialize(any, options)) : structuredClone(any)
|
|
254
|
+
) : (any, options) => deserialize(serialize(any, options));
|
|
255
|
+
var CacheData = class _CacheData {
|
|
256
|
+
static IsDirty(data) {
|
|
257
|
+
return data.dirty;
|
|
258
|
+
}
|
|
259
|
+
static SetDirty(data, value) {
|
|
260
|
+
data.dirty = value;
|
|
261
|
+
return data;
|
|
262
|
+
}
|
|
263
|
+
static StructuredClone = globalThis.structuredClone ?? esm_default;
|
|
264
|
+
_raw;
|
|
265
|
+
generator;
|
|
266
|
+
dirty;
|
|
267
|
+
constructor(generator) {
|
|
268
|
+
this._raw = void 0;
|
|
269
|
+
this.dirty = false;
|
|
270
|
+
this.generator = generator;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* This is cached data.
|
|
274
|
+
* It was generated at the time of caching, so there is a risk of modification if it's an object due to shallow copying.
|
|
275
|
+
* Therefore, if it's not a primitive type, please avoid using this value directly and use the `clone` method to use a copied version of the data.
|
|
276
|
+
*/
|
|
277
|
+
get raw() {
|
|
278
|
+
if (!this.dirty) {
|
|
279
|
+
throw new Error(`The data is not initialized and cannot be accessed. Please use the 'ensure' or 'set' method to create the data first.`);
|
|
280
|
+
}
|
|
281
|
+
return this._raw;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* The method returns a copied value of the cached data.
|
|
285
|
+
* You can pass a function as a parameter to copy the value. This parameter function should return the copied value.
|
|
286
|
+
*
|
|
287
|
+
* If no parameter is passed, it defaults to using Javascript's or \@ungap/structured-clone's `structuredClone` function to copy the value.
|
|
288
|
+
* If you prefer shallow copying instead of deep copying,
|
|
289
|
+
* you can use the default options `array-shallow-copy`, `object-shallow-copy` and `deep-copy`,
|
|
290
|
+
* which are replaced with functions to shallow copy arrays and objects, respectively. This is a syntactic sugar.
|
|
291
|
+
* @param strategy The function that returns the copied value.
|
|
292
|
+
* If you want to perform a shallow copy, simply pass the strings `array-shallow-copy` or `object-shallow-copy` for easy use.
|
|
293
|
+
* The default is `structuredClone`.
|
|
294
|
+
*/
|
|
295
|
+
clone(strategy = "deep-copy") {
|
|
296
|
+
if (strategy && typeof strategy !== "string") {
|
|
297
|
+
return strategy(this.raw);
|
|
298
|
+
}
|
|
299
|
+
switch (strategy) {
|
|
300
|
+
case "array-shallow-copy":
|
|
301
|
+
return [].concat(this.raw);
|
|
302
|
+
case "object-shallow-copy":
|
|
303
|
+
return Object.assign({}, this.raw);
|
|
304
|
+
case "deep-copy":
|
|
305
|
+
default:
|
|
306
|
+
return _CacheData.StructuredClone(this.raw);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
var CacheDataSync = class extends CacheData {
|
|
311
|
+
static EmptyDataGenerator = () => void 0;
|
|
312
|
+
static Update(branch, data, generator) {
|
|
313
|
+
data._raw = generator(branch);
|
|
314
|
+
data.generator = generator;
|
|
315
|
+
data.dirty = true;
|
|
316
|
+
return data;
|
|
317
|
+
}
|
|
318
|
+
static Cache(branch, data) {
|
|
319
|
+
data._raw = data.generator(branch);
|
|
320
|
+
return data;
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
var CacheBranchSync = class _CacheBranchSync extends CacheBranch {
|
|
324
|
+
root;
|
|
325
|
+
constructor(generator = CacheDataSync.EmptyDataGenerator, root) {
|
|
326
|
+
super(new CacheDataSync(generator));
|
|
327
|
+
this.root = root ?? this;
|
|
328
|
+
}
|
|
329
|
+
ensureBranch(key, generator) {
|
|
330
|
+
return this.to(key, (b, k) => {
|
|
331
|
+
const branch = b;
|
|
332
|
+
if (!branch.branches.has(k)) {
|
|
333
|
+
branch.branches.set(k, new _CacheBranchSync(generator, this.root));
|
|
334
|
+
}
|
|
335
|
+
return branch.branches.get(k);
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
getBranch(key) {
|
|
339
|
+
return this.to(key, (b, k) => {
|
|
340
|
+
const branch = b;
|
|
341
|
+
if (!branch.branches.has(k)) {
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
return branch.branches.get(k);
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
cache(key, recursive) {
|
|
348
|
+
const branch = this.ensureBranch(key, CacheDataSync.EmptyDataGenerator);
|
|
349
|
+
if (!branch) {
|
|
350
|
+
return this;
|
|
351
|
+
}
|
|
352
|
+
if (recursive === "bottom-up") {
|
|
353
|
+
for (const key2 of branch.branches.keys()) {
|
|
354
|
+
branch.cache(key2, recursive);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
CacheDataSync.Cache(this.root, branch.data);
|
|
358
|
+
if (recursive === "top-down") {
|
|
359
|
+
for (const key2 of branch.branches.keys()) {
|
|
360
|
+
branch.cache(key2, recursive);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
return this;
|
|
364
|
+
}
|
|
32
365
|
ensure(key, generator) {
|
|
33
|
-
|
|
34
|
-
|
|
366
|
+
const branch = this.ensureBranch(key, CacheDataSync.EmptyDataGenerator);
|
|
367
|
+
if (!CacheDataSync.IsDirty(branch.data)) {
|
|
368
|
+
CacheDataSync.Update(this.root, branch.data, generator);
|
|
369
|
+
}
|
|
370
|
+
return branch.data;
|
|
371
|
+
}
|
|
372
|
+
get(key) {
|
|
373
|
+
const branch = this.ensureBranch(key, CacheDataSync.EmptyDataGenerator);
|
|
374
|
+
if (!CacheDataSync.IsDirty(branch.data)) {
|
|
375
|
+
return void 0;
|
|
376
|
+
}
|
|
377
|
+
return branch.data;
|
|
378
|
+
}
|
|
379
|
+
set(key, generator) {
|
|
380
|
+
const branch = this.ensureBranch(key, CacheDataSync.EmptyDataGenerator);
|
|
381
|
+
CacheDataSync.Update(this.root, branch.data, generator);
|
|
382
|
+
return this;
|
|
383
|
+
}
|
|
384
|
+
delete(key) {
|
|
385
|
+
const branch = this.ensureBranch(key, CacheDataSync.EmptyDataGenerator);
|
|
386
|
+
if (branch) {
|
|
387
|
+
branch.branches.clear();
|
|
388
|
+
CacheDataSync.Update(this.root, branch.data, CacheDataSync.EmptyDataGenerator);
|
|
389
|
+
CacheDataSync.SetDirty(branch.data, false);
|
|
35
390
|
}
|
|
36
|
-
return this
|
|
391
|
+
return this;
|
|
37
392
|
}
|
|
38
393
|
};
|
|
39
394
|
|
|
40
395
|
// src/base/BPTree.ts
|
|
41
396
|
var BPTree = class {
|
|
42
|
-
|
|
397
|
+
_cachedRegexp;
|
|
43
398
|
strategy;
|
|
44
399
|
comparator;
|
|
45
400
|
nodes;
|
|
@@ -57,10 +412,10 @@ var BPTree = class {
|
|
|
57
412
|
like: (nv, v) => {
|
|
58
413
|
const nodeValue = this.comparator.match(nv);
|
|
59
414
|
const value = this.comparator.match(v);
|
|
60
|
-
const regexp = this.
|
|
415
|
+
const regexp = this._cachedRegexp.ensure(value, () => {
|
|
61
416
|
const pattern = value.replace(/%/g, ".*").replace(/_/g, ".");
|
|
62
417
|
return new RegExp(`^${pattern}$`, "i");
|
|
63
|
-
});
|
|
418
|
+
}).raw;
|
|
64
419
|
return regexp.test(nodeValue);
|
|
65
420
|
}
|
|
66
421
|
};
|
|
@@ -92,7 +447,7 @@ var BPTree = class {
|
|
|
92
447
|
like: true
|
|
93
448
|
};
|
|
94
449
|
constructor(strategy, comparator) {
|
|
95
|
-
this.
|
|
450
|
+
this._cachedRegexp = new CacheBranchSync();
|
|
96
451
|
this._nodeCreateBuffer = /* @__PURE__ */ new Map();
|
|
97
452
|
this._nodeUpdateBuffer = /* @__PURE__ */ new Map();
|
|
98
453
|
this.nodes = /* @__PURE__ */ new Map();
|
|
@@ -104,8 +459,8 @@ var BPTree = class {
|
|
|
104
459
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
105
460
|
const nValue = node.values[i];
|
|
106
461
|
if (this.comparator.isSame(value, nValue)) {
|
|
107
|
-
const
|
|
108
|
-
|
|
462
|
+
const keys2 = node.keys[i];
|
|
463
|
+
keys2.push(key);
|
|
109
464
|
this.bufferForNodeUpdate(node);
|
|
110
465
|
break;
|
|
111
466
|
} else if (this.comparator.isLower(value, nValue)) {
|
|
@@ -156,12 +511,12 @@ var BPTreeSync = class extends BPTree {
|
|
|
156
511
|
let i = node.values.length;
|
|
157
512
|
while (i--) {
|
|
158
513
|
const nValue = node.values[i];
|
|
159
|
-
const
|
|
514
|
+
const keys2 = node.keys[i];
|
|
160
515
|
if (comparator(nValue, value)) {
|
|
161
516
|
found = true;
|
|
162
|
-
let j =
|
|
517
|
+
let j = keys2.length;
|
|
163
518
|
while (j--) {
|
|
164
|
-
pairs.push({ key:
|
|
519
|
+
pairs.push({ key: keys2[j], value: nValue });
|
|
165
520
|
}
|
|
166
521
|
} else if (found && !fullScan) {
|
|
167
522
|
done = true;
|
|
@@ -184,10 +539,10 @@ var BPTreeSync = class extends BPTree {
|
|
|
184
539
|
while (!done) {
|
|
185
540
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
186
541
|
const nValue = node.values[i];
|
|
187
|
-
const
|
|
542
|
+
const keys2 = node.keys[i];
|
|
188
543
|
if (comparator(nValue, value)) {
|
|
189
544
|
found = true;
|
|
190
|
-
for (const key of
|
|
545
|
+
for (const key of keys2) {
|
|
191
546
|
pairs.push({ key, value: nValue });
|
|
192
547
|
}
|
|
193
548
|
} else if (found && !fullScan) {
|
|
@@ -220,11 +575,11 @@ var BPTreeSync = class extends BPTree {
|
|
|
220
575
|
}
|
|
221
576
|
return id;
|
|
222
577
|
}
|
|
223
|
-
_createNode(
|
|
578
|
+
_createNode(keys2, values, leaf = false, parent = 0, next = 0, prev = 0) {
|
|
224
579
|
const id = this._createNodeId();
|
|
225
580
|
const node = {
|
|
226
581
|
id,
|
|
227
|
-
keys,
|
|
582
|
+
keys: keys2,
|
|
228
583
|
values,
|
|
229
584
|
leaf,
|
|
230
585
|
parent,
|
|
@@ -254,8 +609,8 @@ var BPTreeSync = class extends BPTree {
|
|
|
254
609
|
}
|
|
255
610
|
}
|
|
256
611
|
if (this.root === node && node.keys.length === 1) {
|
|
257
|
-
const
|
|
258
|
-
this.root = this.getNode(
|
|
612
|
+
const keys2 = node.keys;
|
|
613
|
+
this.root = this.getNode(keys2[0]);
|
|
259
614
|
this.root.parent = 0;
|
|
260
615
|
this.strategy.head.root = this.root.id;
|
|
261
616
|
this.bufferForNodeUpdate(this.root);
|
|
@@ -329,8 +684,8 @@ var BPTreeSync = class extends BPTree {
|
|
|
329
684
|
}
|
|
330
685
|
pointer.values.push(...node.values);
|
|
331
686
|
if (!pointer.leaf) {
|
|
332
|
-
const
|
|
333
|
-
for (const key2 of
|
|
687
|
+
const keys2 = pointer.keys;
|
|
688
|
+
for (const key2 of keys2) {
|
|
334
689
|
const node2 = this.getNode(key2);
|
|
335
690
|
node2.parent = pointer.id;
|
|
336
691
|
this.bufferForNodeUpdate(node2);
|
|
@@ -432,33 +787,6 @@ var BPTreeSync = class extends BPTree {
|
|
|
432
787
|
}
|
|
433
788
|
}
|
|
434
789
|
}
|
|
435
|
-
_insertAtLeaf(node, key, value) {
|
|
436
|
-
if (node.values.length) {
|
|
437
|
-
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
438
|
-
const nValue = node.values[i];
|
|
439
|
-
if (this.comparator.isSame(value, nValue)) {
|
|
440
|
-
const keys = node.keys[i];
|
|
441
|
-
keys.push(key);
|
|
442
|
-
this.bufferForNodeUpdate(node);
|
|
443
|
-
break;
|
|
444
|
-
} else if (this.comparator.isLower(value, nValue)) {
|
|
445
|
-
node.values.splice(i, 0, value);
|
|
446
|
-
node.keys.splice(i, 0, [key]);
|
|
447
|
-
this.bufferForNodeUpdate(node);
|
|
448
|
-
break;
|
|
449
|
-
} else if (i + 1 === node.values.length) {
|
|
450
|
-
node.values.push(value);
|
|
451
|
-
node.keys.push([key]);
|
|
452
|
-
this.bufferForNodeUpdate(node);
|
|
453
|
-
break;
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
} else {
|
|
457
|
-
node.values = [value];
|
|
458
|
-
node.keys = [[key]];
|
|
459
|
-
this.bufferForNodeUpdate(node);
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
790
|
_insertInParent(node, value, pointer) {
|
|
463
791
|
if (this.root === node) {
|
|
464
792
|
const root = this._createNode([node.id, pointer.id], [value]);
|
|
@@ -556,8 +884,8 @@ var BPTreeSync = class extends BPTree {
|
|
|
556
884
|
leftestNode() {
|
|
557
885
|
let node = this.root;
|
|
558
886
|
while (!node.leaf) {
|
|
559
|
-
const
|
|
560
|
-
node = this.getNode(
|
|
887
|
+
const keys2 = node.keys;
|
|
888
|
+
node = this.getNode(keys2[0]);
|
|
561
889
|
}
|
|
562
890
|
return node;
|
|
563
891
|
}
|
|
@@ -661,17 +989,17 @@ var BPTreeSync = class extends BPTree {
|
|
|
661
989
|
while (i--) {
|
|
662
990
|
const nValue = node.values[i];
|
|
663
991
|
if (this.comparator.isSame(value, nValue)) {
|
|
664
|
-
const
|
|
665
|
-
if (
|
|
666
|
-
if (
|
|
667
|
-
|
|
992
|
+
const keys2 = node.keys[i];
|
|
993
|
+
if (keys2.includes(key)) {
|
|
994
|
+
if (keys2.length > 1) {
|
|
995
|
+
keys2.splice(keys2.indexOf(key), 1);
|
|
668
996
|
this.bufferForNodeUpdate(node);
|
|
669
997
|
} else if (node === this.root) {
|
|
670
998
|
node.values.splice(i, 1);
|
|
671
999
|
node.keys.splice(i, 1);
|
|
672
1000
|
this.bufferForNodeUpdate(node);
|
|
673
1001
|
} else {
|
|
674
|
-
|
|
1002
|
+
keys2.splice(keys2.indexOf(key), 1);
|
|
675
1003
|
node.keys.splice(i, 1);
|
|
676
1004
|
node.values.splice(node.values.indexOf(value), 1);
|
|
677
1005
|
this._deleteEntry(node, key, value);
|
|
@@ -689,8 +1017,8 @@ var BPTreeSync = class extends BPTree {
|
|
|
689
1017
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
690
1018
|
const nValue = node.values[i];
|
|
691
1019
|
if (this.comparator.isSame(value, nValue)) {
|
|
692
|
-
const
|
|
693
|
-
return
|
|
1020
|
+
const keys2 = node.keys[i];
|
|
1021
|
+
return keys2.includes(key);
|
|
694
1022
|
}
|
|
695
1023
|
}
|
|
696
1024
|
return false;
|
|
@@ -700,13 +1028,13 @@ var BPTreeSync = class extends BPTree {
|
|
|
700
1028
|
this.commitHeadBuffer();
|
|
701
1029
|
}
|
|
702
1030
|
forceUpdate() {
|
|
703
|
-
const
|
|
1031
|
+
const keys2 = [...this.nodes.keys()];
|
|
704
1032
|
this.nodes.clear();
|
|
705
1033
|
this.init();
|
|
706
|
-
for (const key of
|
|
1034
|
+
for (const key of keys2) {
|
|
707
1035
|
this.getNode(key);
|
|
708
1036
|
}
|
|
709
|
-
return
|
|
1037
|
+
return keys2.length;
|
|
710
1038
|
}
|
|
711
1039
|
};
|
|
712
1040
|
|
|
@@ -715,7 +1043,7 @@ var BPTreeAsync = class extends BPTree {
|
|
|
715
1043
|
constructor(strategy, comparator) {
|
|
716
1044
|
super(strategy, comparator);
|
|
717
1045
|
}
|
|
718
|
-
async _getPairsRightToLeft(value, startNode,
|
|
1046
|
+
async _getPairsRightToLeft(value, startNode, fullScan, comparator) {
|
|
719
1047
|
const pairs = [];
|
|
720
1048
|
let node = startNode;
|
|
721
1049
|
let done = false;
|
|
@@ -724,14 +1052,14 @@ var BPTreeAsync = class extends BPTree {
|
|
|
724
1052
|
let i = node.values.length;
|
|
725
1053
|
while (i--) {
|
|
726
1054
|
const nValue = node.values[i];
|
|
727
|
-
const
|
|
1055
|
+
const keys2 = node.keys[i];
|
|
728
1056
|
if (comparator(nValue, value)) {
|
|
729
1057
|
found = true;
|
|
730
|
-
let j =
|
|
1058
|
+
let j = keys2.length;
|
|
731
1059
|
while (j--) {
|
|
732
|
-
pairs.push({ key:
|
|
1060
|
+
pairs.push({ key: keys2[j], value: nValue });
|
|
733
1061
|
}
|
|
734
|
-
} else if (found && !
|
|
1062
|
+
} else if (found && !fullScan) {
|
|
735
1063
|
done = true;
|
|
736
1064
|
break;
|
|
737
1065
|
}
|
|
@@ -744,7 +1072,7 @@ var BPTreeAsync = class extends BPTree {
|
|
|
744
1072
|
}
|
|
745
1073
|
return pairs.reverse();
|
|
746
1074
|
}
|
|
747
|
-
async _getPairsLeftToRight(value, startNode,
|
|
1075
|
+
async _getPairsLeftToRight(value, startNode, fullScan, comparator) {
|
|
748
1076
|
const pairs = [];
|
|
749
1077
|
let node = startNode;
|
|
750
1078
|
let done = false;
|
|
@@ -752,13 +1080,13 @@ var BPTreeAsync = class extends BPTree {
|
|
|
752
1080
|
while (!done) {
|
|
753
1081
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
754
1082
|
const nValue = node.values[i];
|
|
755
|
-
const
|
|
1083
|
+
const keys2 = node.keys[i];
|
|
756
1084
|
if (comparator(nValue, value)) {
|
|
757
1085
|
found = true;
|
|
758
|
-
for (const key of
|
|
1086
|
+
for (const key of keys2) {
|
|
759
1087
|
pairs.push({ key, value: nValue });
|
|
760
1088
|
}
|
|
761
|
-
} else if (found && !
|
|
1089
|
+
} else if (found && !fullScan) {
|
|
762
1090
|
done = true;
|
|
763
1091
|
break;
|
|
764
1092
|
}
|
|
@@ -771,12 +1099,12 @@ var BPTreeAsync = class extends BPTree {
|
|
|
771
1099
|
}
|
|
772
1100
|
return pairs;
|
|
773
1101
|
}
|
|
774
|
-
async getPairs(value, startNode,
|
|
1102
|
+
async getPairs(value, startNode, fullScan, comparator, direction) {
|
|
775
1103
|
switch (direction) {
|
|
776
1104
|
case -1:
|
|
777
|
-
return await this._getPairsRightToLeft(value, startNode,
|
|
1105
|
+
return await this._getPairsRightToLeft(value, startNode, fullScan, comparator);
|
|
778
1106
|
case 1:
|
|
779
|
-
return await this._getPairsLeftToRight(value, startNode,
|
|
1107
|
+
return await this._getPairsLeftToRight(value, startNode, fullScan, comparator);
|
|
780
1108
|
default:
|
|
781
1109
|
throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
|
|
782
1110
|
}
|
|
@@ -788,11 +1116,11 @@ var BPTreeAsync = class extends BPTree {
|
|
|
788
1116
|
}
|
|
789
1117
|
return id;
|
|
790
1118
|
}
|
|
791
|
-
async _createNode(
|
|
1119
|
+
async _createNode(keys2, values, leaf = false, parent = 0, next = 0, prev = 0) {
|
|
792
1120
|
const id = await this._createNodeId();
|
|
793
1121
|
const node = {
|
|
794
1122
|
id,
|
|
795
|
-
keys,
|
|
1123
|
+
keys: keys2,
|
|
796
1124
|
values,
|
|
797
1125
|
leaf,
|
|
798
1126
|
parent,
|
|
@@ -822,8 +1150,8 @@ var BPTreeAsync = class extends BPTree {
|
|
|
822
1150
|
}
|
|
823
1151
|
}
|
|
824
1152
|
if (this.root === node && node.keys.length === 1) {
|
|
825
|
-
const
|
|
826
|
-
this.root = await this.getNode(
|
|
1153
|
+
const keys2 = node.keys;
|
|
1154
|
+
this.root = await this.getNode(keys2[0]);
|
|
827
1155
|
this.root.parent = 0;
|
|
828
1156
|
this.strategy.head.root = this.root.id;
|
|
829
1157
|
this.bufferForNodeUpdate(this.root);
|
|
@@ -897,8 +1225,8 @@ var BPTreeAsync = class extends BPTree {
|
|
|
897
1225
|
}
|
|
898
1226
|
pointer.values.push(...node.values);
|
|
899
1227
|
if (!pointer.leaf) {
|
|
900
|
-
const
|
|
901
|
-
for (const key2 of
|
|
1228
|
+
const keys2 = pointer.keys;
|
|
1229
|
+
for (const key2 of keys2) {
|
|
902
1230
|
const node2 = await this.getNode(key2);
|
|
903
1231
|
node2.parent = pointer.id;
|
|
904
1232
|
this.bufferForNodeUpdate(node2);
|
|
@@ -1097,8 +1425,8 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1097
1425
|
async leftestNode() {
|
|
1098
1426
|
let node = this.root;
|
|
1099
1427
|
while (!node.leaf) {
|
|
1100
|
-
const
|
|
1101
|
-
node = await this.getNode(
|
|
1428
|
+
const keys2 = node.keys;
|
|
1429
|
+
node = await this.getNode(keys2[0]);
|
|
1102
1430
|
}
|
|
1103
1431
|
return node;
|
|
1104
1432
|
}
|
|
@@ -1202,17 +1530,17 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1202
1530
|
while (i--) {
|
|
1203
1531
|
const nValue = node.values[i];
|
|
1204
1532
|
if (this.comparator.isSame(value, nValue)) {
|
|
1205
|
-
const
|
|
1206
|
-
if (
|
|
1207
|
-
if (
|
|
1208
|
-
|
|
1533
|
+
const keys2 = node.keys[i];
|
|
1534
|
+
if (keys2.includes(key)) {
|
|
1535
|
+
if (keys2.length > 1) {
|
|
1536
|
+
keys2.splice(keys2.indexOf(key), 1);
|
|
1209
1537
|
this.bufferForNodeUpdate(node);
|
|
1210
1538
|
} else if (node === this.root) {
|
|
1211
1539
|
node.values.splice(i, 1);
|
|
1212
1540
|
node.keys.splice(i, 1);
|
|
1213
1541
|
this.bufferForNodeUpdate(node);
|
|
1214
1542
|
} else {
|
|
1215
|
-
|
|
1543
|
+
keys2.splice(keys2.indexOf(key), 1);
|
|
1216
1544
|
node.keys.splice(i, 1);
|
|
1217
1545
|
node.values.splice(node.values.indexOf(value), 1);
|
|
1218
1546
|
await this._deleteEntry(node, key, value);
|
|
@@ -1230,8 +1558,8 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1230
1558
|
for (let i = 0, len = node.values.length; i < len; i++) {
|
|
1231
1559
|
const nValue = node.values[i];
|
|
1232
1560
|
if (this.comparator.isSame(value, nValue)) {
|
|
1233
|
-
const
|
|
1234
|
-
return
|
|
1561
|
+
const keys2 = node.keys[i];
|
|
1562
|
+
return keys2.includes(key);
|
|
1235
1563
|
}
|
|
1236
1564
|
}
|
|
1237
1565
|
return false;
|
|
@@ -1241,13 +1569,13 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1241
1569
|
await this.commitHeadBuffer();
|
|
1242
1570
|
}
|
|
1243
1571
|
async forceUpdate() {
|
|
1244
|
-
const
|
|
1572
|
+
const keys2 = [...this.nodes.keys()];
|
|
1245
1573
|
this.nodes.clear();
|
|
1246
1574
|
await this.init();
|
|
1247
|
-
for (const key of
|
|
1575
|
+
for (const key of keys2) {
|
|
1248
1576
|
await this.getNode(key);
|
|
1249
1577
|
}
|
|
1250
|
-
return
|
|
1578
|
+
return keys2.length;
|
|
1251
1579
|
}
|
|
1252
1580
|
};
|
|
1253
1581
|
|