serializable-bptree 5.1.0 → 5.1.2

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.
@@ -27,16 +27,167 @@ var StringComparator = class extends ValueComparator {
27
27
  }
28
28
  };
29
29
 
30
- // src/utils/InvertedWeakMap.ts
30
+ // node_modules/cache-entanglement/dist/esm/index.mjs
31
+ var __create = Object.create;
32
+ var __defProp = Object.defineProperty;
33
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
34
+ var __getOwnPropNames = Object.getOwnPropertyNames;
35
+ var __getProtoOf = Object.getPrototypeOf;
36
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
37
+ var __commonJS = (cb, mod) => function __require() {
38
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
39
+ };
40
+ var __copyProps = (to, from, except, desc) => {
41
+ if (from && typeof from === "object" || typeof from === "function") {
42
+ for (let key of __getOwnPropNames(from))
43
+ if (!__hasOwnProp.call(to, key) && key !== except)
44
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
45
+ }
46
+ return to;
47
+ };
48
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
49
+ // If the importer is in node compatibility mode or this is not an ESM
50
+ // file that has been converted to a CommonJS file using a Babel-
51
+ // compatible transform (i.e. "__esModule" has not been set), then set
52
+ // "default" to the CommonJS "module.exports" for node compatibility.
53
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
54
+ mod
55
+ ));
56
+ var require_ms = __commonJS({
57
+ "node_modules/ms/index.js"(exports, module) {
58
+ var s = 1e3;
59
+ var m = s * 60;
60
+ var h = m * 60;
61
+ var d = h * 24;
62
+ var w = d * 7;
63
+ var y = d * 365.25;
64
+ module.exports = function(val, options) {
65
+ options = options || {};
66
+ var type = typeof val;
67
+ if (type === "string" && val.length > 0) {
68
+ return parse(val);
69
+ } else if (type === "number" && isFinite(val)) {
70
+ return options.long ? fmtLong(val) : fmtShort(val);
71
+ }
72
+ throw new Error(
73
+ "val is not a non-empty string or a valid number. val=" + JSON.stringify(val)
74
+ );
75
+ };
76
+ function parse(str) {
77
+ str = String(str);
78
+ if (str.length > 100) {
79
+ return;
80
+ }
81
+ var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
82
+ str
83
+ );
84
+ if (!match) {
85
+ return;
86
+ }
87
+ var n = parseFloat(match[1]);
88
+ var type = (match[2] || "ms").toLowerCase();
89
+ switch (type) {
90
+ case "years":
91
+ case "year":
92
+ case "yrs":
93
+ case "yr":
94
+ case "y":
95
+ return n * y;
96
+ case "weeks":
97
+ case "week":
98
+ case "w":
99
+ return n * w;
100
+ case "days":
101
+ case "day":
102
+ case "d":
103
+ return n * d;
104
+ case "hours":
105
+ case "hour":
106
+ case "hrs":
107
+ case "hr":
108
+ case "h":
109
+ return n * h;
110
+ case "minutes":
111
+ case "minute":
112
+ case "mins":
113
+ case "min":
114
+ case "m":
115
+ return n * m;
116
+ case "seconds":
117
+ case "second":
118
+ case "secs":
119
+ case "sec":
120
+ case "s":
121
+ return n * s;
122
+ case "milliseconds":
123
+ case "millisecond":
124
+ case "msecs":
125
+ case "msec":
126
+ case "ms":
127
+ return n;
128
+ default:
129
+ return void 0;
130
+ }
131
+ }
132
+ function fmtShort(ms2) {
133
+ var msAbs = Math.abs(ms2);
134
+ if (msAbs >= d) {
135
+ return Math.round(ms2 / d) + "d";
136
+ }
137
+ if (msAbs >= h) {
138
+ return Math.round(ms2 / h) + "h";
139
+ }
140
+ if (msAbs >= m) {
141
+ return Math.round(ms2 / m) + "m";
142
+ }
143
+ if (msAbs >= s) {
144
+ return Math.round(ms2 / s) + "s";
145
+ }
146
+ return ms2 + "ms";
147
+ }
148
+ function fmtLong(ms2) {
149
+ var msAbs = Math.abs(ms2);
150
+ if (msAbs >= d) {
151
+ return plural(ms2, msAbs, d, "day");
152
+ }
153
+ if (msAbs >= h) {
154
+ return plural(ms2, msAbs, h, "hour");
155
+ }
156
+ if (msAbs >= m) {
157
+ return plural(ms2, msAbs, m, "minute");
158
+ }
159
+ if (msAbs >= s) {
160
+ return plural(ms2, msAbs, s, "second");
161
+ }
162
+ return ms2 + " ms";
163
+ }
164
+ function plural(ms2, msAbs, n, name) {
165
+ var isPlural = msAbs >= n * 1.5;
166
+ return Math.round(ms2 / n) + " " + name + (isPlural ? "s" : "");
167
+ }
168
+ }
169
+ });
170
+ var import_ms = __toESM(require_ms());
31
171
  var InvertedWeakMap = class {
32
172
  _map;
173
+ _keepAlive;
174
+ _timeouts;
33
175
  _registry;
34
- constructor() {
176
+ _lifespan;
177
+ constructor(option) {
178
+ const { lifespan } = option;
179
+ this._lifespan = lifespan;
35
180
  this._map = /* @__PURE__ */ new Map();
36
- this._registry = new FinalizationRegistry((key) => this._map.delete(key));
181
+ this._keepAlive = /* @__PURE__ */ new Map();
182
+ this._timeouts = /* @__PURE__ */ new Map();
183
+ this._registry = new FinalizationRegistry((key) => {
184
+ this._stopExpire(key, true);
185
+ this._map.delete(key);
186
+ });
37
187
  }
38
188
  clear() {
39
- return this._map.clear();
189
+ this._keepAlive.clear();
190
+ this._map.clear();
40
191
  }
41
192
  delete(key) {
42
193
  const ref = this._map.get(key);
@@ -46,6 +197,8 @@ var InvertedWeakMap = class {
46
197
  this._registry.unregister(raw);
47
198
  }
48
199
  }
200
+ this._stopExpire(key, true);
201
+ this._keepAlive.delete(key);
49
202
  return this._map.delete(key);
50
203
  }
51
204
  get(key) {
@@ -57,8 +210,39 @@ var InvertedWeakMap = class {
57
210
  set(key, value) {
58
211
  this._map.set(key, new WeakRef(value));
59
212
  this._registry.register(value, key);
213
+ if (this._lifespan > 0) {
214
+ this._stopExpire(key, true);
215
+ this._startExpire(key, value);
216
+ }
60
217
  return this;
61
218
  }
219
+ extendExpire(key) {
220
+ if (!(this._lifespan > 0)) {
221
+ return;
222
+ }
223
+ if (!this._keepAlive.has(key)) {
224
+ return;
225
+ }
226
+ this._stopExpire(key, false);
227
+ this._startExpire(key, this._keepAlive.get(key));
228
+ }
229
+ _startExpire(key, value) {
230
+ this._keepAlive.set(key, value);
231
+ this._timeouts.set(key, setTimeout(() => {
232
+ this._keepAlive.delete(key);
233
+ }, this._lifespan));
234
+ }
235
+ _stopExpire(key, removeKeepAlive) {
236
+ if (!this._timeouts.has(key)) {
237
+ return;
238
+ }
239
+ const timeout = this._timeouts.get(key);
240
+ this._timeouts.delete(key);
241
+ clearTimeout(timeout);
242
+ if (removeKeepAlive) {
243
+ this._keepAlive.delete(key);
244
+ }
245
+ }
62
246
  get size() {
63
247
  return this._map.size;
64
248
  }
@@ -66,13 +250,252 @@ var InvertedWeakMap = class {
66
250
  return this._map.keys();
67
251
  }
68
252
  };
253
+ var CacheEntanglement = class {
254
+ creation;
255
+ beforeUpdateHook;
256
+ lifespan;
257
+ dependencies;
258
+ caches;
259
+ assignments;
260
+ parameters;
261
+ dependencyKeys;
262
+ constructor(creation, option) {
263
+ option = option ?? {};
264
+ const {
265
+ dependencies,
266
+ lifespan,
267
+ beforeUpdateHook
268
+ } = option;
269
+ this.creation = creation;
270
+ this.beforeUpdateHook = beforeUpdateHook ?? (() => {
271
+ });
272
+ this.lifespan = this._normalizeMs(lifespan ?? 0);
273
+ this.assignments = [];
274
+ this.caches = new InvertedWeakMap({ lifespan: this.lifespan });
275
+ this.dependencies = dependencies ?? {};
276
+ this.dependencyKeys = Object.keys(this.dependencies);
277
+ this.parameters = {};
278
+ for (const name in this.dependencies) {
279
+ const dependency = this.dependencies[name];
280
+ if (!dependency.assignments.includes(this)) {
281
+ dependency.assignments.push(this);
282
+ }
283
+ }
284
+ }
285
+ _normalizeMs(time) {
286
+ if (typeof time === "string") {
287
+ return (0, import_ms.default)(time);
288
+ }
289
+ return time;
290
+ }
291
+ dependencyKey(key) {
292
+ const tokens = key.split("/");
293
+ tokens.pop();
294
+ return tokens.join("/");
295
+ }
296
+ /**
297
+ * Returns all keys stored in the instance.
298
+ */
299
+ keys() {
300
+ return this.caches.keys();
301
+ }
302
+ /**
303
+ * Deletes all cache values stored in the instance.
304
+ */
305
+ clear() {
306
+ for (const key of this.keys()) {
307
+ this.delete(key);
308
+ }
309
+ }
310
+ /**
311
+ * Checks if there is a cache value stored in the key within the instance.
312
+ * @param key The key to search.
313
+ */
314
+ exists(key) {
315
+ return this.caches.has(key);
316
+ }
317
+ /**
318
+ * Returns the cache value stored in the key within the instance. If the cached value is not present, an error is thrown.
319
+ * @param key The key to search.
320
+ */
321
+ get(key) {
322
+ if (!this.caches.has(key)) {
323
+ throw new Error(`Cache value not found: ${key}`);
324
+ }
325
+ return this.caches.get(key);
326
+ }
327
+ };
328
+ var CacheData = class _CacheData {
329
+ static StructuredClone = globalThis.structuredClone.bind(globalThis);
330
+ _value;
331
+ constructor(value) {
332
+ this._value = value;
333
+ }
334
+ /**
335
+ * This is cached data.
336
+ * It was generated at the time of caching, so there is a risk of modification if it's an object due to shallow copying.
337
+ * 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.
338
+ */
339
+ get raw() {
340
+ return this._value;
341
+ }
342
+ /**
343
+ * The method returns a copied value of the cached data.
344
+ * You can pass a function as a parameter to copy the value. This parameter function should return the copied value.
345
+ *
346
+ * If no parameter is passed, it defaults to using `structuredClone` function to copy the value.
347
+ * If you prefer shallow copying instead of deep copying,
348
+ * you can use the default options `array-shallow-copy`, `object-shallow-copy` and `deep-copy`,
349
+ * which are replaced with functions to shallow copy arrays and objects, respectively. This is a syntactic sugar.
350
+ * @param strategy The function that returns the copied value.
351
+ * If you want to perform a shallow copy, simply pass the strings `array-shallow-copy` or `object-shallow-copy` for easy use.
352
+ * The `array-shallow-copy` strategy performs a shallow copy of an array.
353
+ * The `object-shallow-copy` strategy performs a shallow copy of an object.
354
+ * The `deep-copy` strategy performs a deep copy of the value using `structuredClone`.
355
+ * The default is `deep-copy`.
356
+ */
357
+ clone(strategy = "deep-copy") {
358
+ if (strategy && typeof strategy !== "string") {
359
+ return strategy(this.raw);
360
+ }
361
+ switch (strategy) {
362
+ case "array-shallow-copy":
363
+ return [].concat(this.raw);
364
+ case "object-shallow-copy":
365
+ return Object.assign({}, this.raw);
366
+ case "deep-copy":
367
+ default:
368
+ return _CacheData.StructuredClone(this.raw);
369
+ }
370
+ }
371
+ };
372
+ var CacheEntanglementSync = class extends CacheEntanglement {
373
+ constructor(creation, option) {
374
+ super(creation, option);
375
+ }
376
+ resolve(key, ...parameter) {
377
+ const resolved = {};
378
+ const dependencyKey = this.dependencyKey(key);
379
+ this.beforeUpdateHook(key, dependencyKey, ...parameter);
380
+ for (let i = 0, len = this.dependencyKeys.length; i < len; i++) {
381
+ const name = this.dependencyKeys[i];
382
+ const dependency = this.dependencies[name];
383
+ if (!dependency.caches.has(key) && !dependency.caches.has(dependencyKey)) {
384
+ throw new Error(`The key '${key}' or '${dependencyKey}' has not been assigned yet in dependency '${name.toString()}'.`, {
385
+ cause: {
386
+ from: this
387
+ }
388
+ });
389
+ }
390
+ const dependencyValue = dependency.caches.get(key) ?? dependency.caches.get(dependencyKey);
391
+ resolved[name] = dependencyValue;
392
+ }
393
+ this.parameters[key] = parameter;
394
+ const value = new CacheData(this.creation(key, resolved, ...parameter));
395
+ this.caches.set(key, value);
396
+ return value;
397
+ }
398
+ cache(key, ...parameter) {
399
+ if (!this.caches.has(key)) {
400
+ this.resolve(key, ...parameter);
401
+ } else {
402
+ this.caches.extendExpire(key);
403
+ }
404
+ return this.caches.get(key);
405
+ }
406
+ update(key, ...parameter) {
407
+ this.resolve(key, ...parameter);
408
+ for (let i = 0, len = this.assignments.length; i < len; i++) {
409
+ const t = this.assignments[i];
410
+ const instance = t;
411
+ for (const cacheKey of instance.caches.keys()) {
412
+ if (cacheKey === key || cacheKey.startsWith(`${key}/`)) {
413
+ instance.update(cacheKey, ...instance.parameters[cacheKey]);
414
+ }
415
+ }
416
+ }
417
+ return this.caches.get(key);
418
+ }
419
+ delete(key) {
420
+ this.caches.delete(key);
421
+ for (let i = 0, len = this.assignments.length; i < len; i++) {
422
+ const t = this.assignments[i];
423
+ const instance = t;
424
+ for (const cacheKey of instance.caches.keys()) {
425
+ if (cacheKey === key || cacheKey.startsWith(`${key}/`)) {
426
+ instance.delete(cacheKey);
427
+ }
428
+ }
429
+ }
430
+ }
431
+ };
432
+ var CacheEntanglementAsync = class extends CacheEntanglement {
433
+ constructor(creation, option) {
434
+ super(creation, option);
435
+ }
436
+ async resolve(key, ...parameter) {
437
+ const resolved = {};
438
+ const dependencyKey = this.dependencyKey(key);
439
+ await this.beforeUpdateHook(key, dependencyKey, ...parameter);
440
+ for (let i = 0, len = this.dependencyKeys.length; i < len; i++) {
441
+ const name = this.dependencyKeys[i];
442
+ const dependency = this.dependencies[name];
443
+ if (!dependency.caches.has(key) && !dependency.caches.has(dependencyKey)) {
444
+ throw new Error(`The key '${key}' or '${dependencyKey}' has not been assigned yet in dependency '${name.toString()}'.`, {
445
+ cause: {
446
+ from: this
447
+ }
448
+ });
449
+ }
450
+ const dependencyValue = dependency.caches.get(key) ?? dependency.caches.get(dependencyKey);
451
+ resolved[name] = dependencyValue;
452
+ }
453
+ this.parameters[key] = parameter;
454
+ const value = new CacheData(await this.creation(key, resolved, ...parameter));
455
+ this.caches.set(key, value);
456
+ return value;
457
+ }
458
+ async cache(key, ...parameter) {
459
+ if (!this.caches.has(key)) {
460
+ await this.resolve(key, ...parameter);
461
+ } else {
462
+ this.caches.extendExpire(key);
463
+ }
464
+ return this.caches.get(key);
465
+ }
466
+ async update(key, ...parameter) {
467
+ await this.resolve(key, ...parameter);
468
+ for (let i = 0, len = this.assignments.length; i < len; i++) {
469
+ const t = this.assignments[i];
470
+ const instance = t;
471
+ for (const cacheKey of instance.caches.keys()) {
472
+ if (cacheKey === key || cacheKey.startsWith(`${key}/`)) {
473
+ await instance.update(cacheKey, ...instance.parameters[cacheKey]);
474
+ }
475
+ }
476
+ }
477
+ return this.caches.get(key);
478
+ }
479
+ async delete(key) {
480
+ this.caches.delete(key);
481
+ for (let i = 0, len = this.assignments.length; i < len; i++) {
482
+ const t = this.assignments[i];
483
+ const instance = t;
484
+ for (const cacheKey of instance.caches.keys()) {
485
+ if (cacheKey === key || cacheKey.startsWith(`${key}/`)) {
486
+ await instance.delete(cacheKey);
487
+ }
488
+ }
489
+ }
490
+ }
491
+ };
69
492
 
70
493
  // src/base/BPTree.ts
71
494
  var BPTree = class {
72
495
  _cachedRegexp;
73
496
  strategy;
74
497
  comparator;
75
- nodes;
498
+ option;
76
499
  order;
77
500
  root;
78
501
  _strategyDirty;
@@ -90,12 +513,8 @@ var BPTree = class {
90
513
  like: (nv, v) => {
91
514
  const nodeValue = this.comparator.match(nv);
92
515
  const value = this.comparator.match(v);
93
- if (!this._cachedRegexp.has(value)) {
94
- const pattern = value.replace(/%/g, ".*").replace(/_/g, ".");
95
- const regexp2 = new RegExp(`^${pattern}$`, "i");
96
- this._cachedRegexp.set(value, regexp2);
97
- }
98
- const regexp = this._cachedRegexp.get(value);
516
+ const cache = this._cachedRegexp.cache(value);
517
+ const regexp = cache.raw;
99
518
  return regexp.test(nodeValue);
100
519
  }
101
520
  };
@@ -132,15 +551,24 @@ var BPTree = class {
132
551
  or: 1,
133
552
  like: 1
134
553
  };
135
- constructor(strategy, comparator) {
554
+ constructor(strategy, comparator, option) {
555
+ this.strategy = strategy;
556
+ this.comparator = comparator;
557
+ this.option = option ?? {};
136
558
  this._strategyDirty = false;
137
- this._cachedRegexp = new InvertedWeakMap();
138
559
  this._nodeCreateBuffer = /* @__PURE__ */ new Map();
139
560
  this._nodeUpdateBuffer = /* @__PURE__ */ new Map();
140
561
  this._nodeDeleteBuffer = /* @__PURE__ */ new Map();
141
- this.nodes = new InvertedWeakMap();
142
- this.strategy = strategy;
143
- this.comparator = comparator;
562
+ this._cachedRegexp = this._createCachedRegexp();
563
+ }
564
+ _createCachedRegexp() {
565
+ return new CacheEntanglementSync((key) => {
566
+ const pattern = key.replace(/%/g, ".*").replace(/_/g, ".");
567
+ const regexp = new RegExp(`^${pattern}$`, "i");
568
+ return regexp;
569
+ }, {
570
+ lifespan: this.option.lifespan ?? "3m"
571
+ });
144
572
  }
145
573
  ensureValues(v) {
146
574
  if (!Array.isArray(v)) {
@@ -214,12 +642,28 @@ var BPTree = class {
214
642
  getHeadData() {
215
643
  return this.strategy.head.data;
216
644
  }
645
+ /**
646
+ * Clears all cached nodes.
647
+ * This method is useful for freeing up memory when the tree is no longer needed.
648
+ */
649
+ clear() {
650
+ this._cachedRegexp.clear();
651
+ this.nodes.clear();
652
+ }
217
653
  };
218
654
 
219
655
  // src/BPTreeSync.ts
220
656
  var BPTreeSync = class extends BPTree {
221
- constructor(strategy, comparator) {
222
- super(strategy, comparator);
657
+ constructor(strategy, comparator, option) {
658
+ super(strategy, comparator, option);
659
+ this.nodes = this._createCachedNode();
660
+ }
661
+ _createCachedNode() {
662
+ return new CacheEntanglementSync((key) => {
663
+ return this.strategy.read(key);
664
+ }, {
665
+ lifespan: this.option.lifespan ?? "3m"
666
+ });
223
667
  }
224
668
  getPairsRightToLeft(value, startNode, endNode, comparator) {
225
669
  const pairs = [];
@@ -304,7 +748,7 @@ var BPTreeSync = class extends BPTree {
304
748
  next,
305
749
  prev
306
750
  };
307
- this.nodes.set(id, node);
751
+ this._nodeCreateBuffer.set(id, node);
308
752
  return node;
309
753
  }
310
754
  _deleteEntry(node, key, value) {
@@ -518,7 +962,6 @@ var BPTreeSync = class extends BPTree {
518
962
  this.strategy.head.root = root.id;
519
963
  node.parent = root.id;
520
964
  pointer.parent = root.id;
521
- this.bufferForNodeCreate(root);
522
965
  this.bufferForNodeUpdate(node);
523
966
  this.bufferForNodeUpdate(pointer);
524
967
  return;
@@ -554,7 +997,6 @@ var BPTreeSync = class extends BPTree {
554
997
  this.bufferForNodeUpdate(node2);
555
998
  }
556
999
  this._insertInParent(parentNode, midValue, parentPointer);
557
- this.bufferForNodeCreate(parentPointer);
558
1000
  this.bufferForNodeUpdate(parentNode);
559
1001
  }
560
1002
  }
@@ -566,7 +1008,6 @@ var BPTreeSync = class extends BPTree {
566
1008
  this.order = this.strategy.order;
567
1009
  this.root = this._createNode(true, [], [], true);
568
1010
  this.strategy.head.root = this.root.id;
569
- this.bufferForNodeCreate(this.root);
570
1011
  this.commitHeadBuffer();
571
1012
  this.commitNodeCreateBuffer();
572
1013
  } else {
@@ -580,10 +1021,11 @@ var BPTreeSync = class extends BPTree {
580
1021
  }
581
1022
  }
582
1023
  getNode(id) {
583
- if (!this.nodes.has(id)) {
584
- this.nodes.set(id, this.strategy.read(id));
1024
+ if (this._nodeCreateBuffer.has(id)) {
1025
+ return this._nodeCreateBuffer.get(id);
585
1026
  }
586
- return this.nodes.get(id);
1027
+ const cache = this.nodes.cache(id);
1028
+ return cache.raw;
587
1029
  }
588
1030
  insertableNode(value) {
589
1031
  let node = this.root;
@@ -739,7 +1181,6 @@ var BPTreeSync = class extends BPTree {
739
1181
  this.bufferForNodeUpdate(node);
740
1182
  }
741
1183
  this._insertInParent(before, after.values[0], after);
742
- this.bufferForNodeCreate(after);
743
1184
  this.bufferForNodeUpdate(before);
744
1185
  }
745
1186
  this.commitHeadBuffer();
@@ -805,8 +1246,16 @@ var BPTreeSync = class extends BPTree {
805
1246
 
806
1247
  // src/BPTreeAsync.ts
807
1248
  var BPTreeAsync = class extends BPTree {
808
- constructor(strategy, comparator) {
809
- super(strategy, comparator);
1249
+ constructor(strategy, comparator, option) {
1250
+ super(strategy, comparator, option);
1251
+ this.nodes = this._createCachedNode();
1252
+ }
1253
+ _createCachedNode() {
1254
+ return new CacheEntanglementAsync(async (key) => {
1255
+ return await this.strategy.read(key);
1256
+ }, {
1257
+ lifespan: this.option.lifespan ?? "3m"
1258
+ });
810
1259
  }
811
1260
  async getPairsRightToLeft(value, startNode, endNode, comparator) {
812
1261
  const pairs = [];
@@ -891,7 +1340,7 @@ var BPTreeAsync = class extends BPTree {
891
1340
  next,
892
1341
  prev
893
1342
  };
894
- this.nodes.set(id, node);
1343
+ this._nodeCreateBuffer.set(id, node);
895
1344
  return node;
896
1345
  }
897
1346
  async _deleteEntry(node, key, value) {
@@ -1105,7 +1554,6 @@ var BPTreeAsync = class extends BPTree {
1105
1554
  this.strategy.head.root = root.id;
1106
1555
  node.parent = root.id;
1107
1556
  pointer.parent = root.id;
1108
- this.bufferForNodeCreate(root);
1109
1557
  this.bufferForNodeUpdate(node);
1110
1558
  this.bufferForNodeUpdate(pointer);
1111
1559
  return;
@@ -1141,7 +1589,6 @@ var BPTreeAsync = class extends BPTree {
1141
1589
  this.bufferForNodeUpdate(node2);
1142
1590
  }
1143
1591
  await this._insertInParent(parentNode, midValue, parentPointer);
1144
- this.bufferForNodeCreate(parentPointer);
1145
1592
  this.bufferForNodeUpdate(parentNode);
1146
1593
  }
1147
1594
  }
@@ -1153,7 +1600,6 @@ var BPTreeAsync = class extends BPTree {
1153
1600
  this.order = this.strategy.order;
1154
1601
  this.root = await this._createNode(true, [], [], true);
1155
1602
  this.strategy.head.root = this.root.id;
1156
- this.bufferForNodeCreate(this.root);
1157
1603
  await this.commitHeadBuffer();
1158
1604
  await this.commitNodeCreateBuffer();
1159
1605
  } else {
@@ -1167,10 +1613,11 @@ var BPTreeAsync = class extends BPTree {
1167
1613
  }
1168
1614
  }
1169
1615
  async getNode(id) {
1170
- if (!this.nodes.has(id)) {
1171
- this.nodes.set(id, await this.strategy.read(id));
1616
+ if (this._nodeCreateBuffer.has(id)) {
1617
+ return this._nodeCreateBuffer.get(id);
1172
1618
  }
1173
- return this.nodes.get(id);
1619
+ const cache = await this.nodes.cache(id);
1620
+ return cache.raw;
1174
1621
  }
1175
1622
  async insertableNode(value) {
1176
1623
  let node = this.root;
@@ -1326,7 +1773,6 @@ var BPTreeAsync = class extends BPTree {
1326
1773
  this.bufferForNodeUpdate(node);
1327
1774
  }
1328
1775
  await this._insertInParent(before, after.values[0], after);
1329
- this.bufferForNodeCreate(after);
1330
1776
  this.bufferForNodeUpdate(before);
1331
1777
  }
1332
1778
  await this.commitHeadBuffer();
@@ -1,10 +1,12 @@
1
- import { BPTree, BPTreeCondition, BPTreeLeafNode, BPTreePair, BPTreeNodeKey, BPTreeUnknownNode } from './base/BPTree';
1
+ import { BPTree, BPTreeCondition, BPTreeLeafNode, BPTreePair, BPTreeNodeKey, BPTreeUnknownNode, BPTreeConstructorOption } from './base/BPTree';
2
2
  import { SerializeStrategyAsync } from './SerializeStrategyAsync';
3
3
  import { ValueComparator } from './base/ValueComparator';
4
4
  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
- constructor(strategy: SerializeStrategyAsync<K, V>, comparator: ValueComparator<V>);
7
+ protected readonly nodes: ReturnType<BPTreeAsync<K, V>['_createCachedNode']>;
8
+ constructor(strategy: SerializeStrategyAsync<K, V>, comparator: ValueComparator<V>, option?: BPTreeConstructorOption);
9
+ private _createCachedNode;
8
10
  protected getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean): Promise<BPTreePair<K, V>>;
9
11
  protected getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean): Promise<BPTreePair<K, V>>;
10
12
  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>>;
@@ -1,10 +1,12 @@
1
- import { BPTree, BPTreeCondition, BPTreeLeafNode, BPTreePair, BPTreeNodeKey, BPTreeUnknownNode } from './base/BPTree';
1
+ import { BPTree, BPTreeCondition, BPTreeLeafNode, BPTreePair, BPTreeNodeKey, BPTreeUnknownNode, BPTreeConstructorOption } from './base/BPTree';
2
2
  import { SerializeStrategySync } from './SerializeStrategySync';
3
3
  import { ValueComparator } from './base/ValueComparator';
4
4
  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
- constructor(strategy: SerializeStrategySync<K, V>, comparator: ValueComparator<V>);
7
+ protected readonly nodes: ReturnType<BPTreeSync<K, V>['_createCachedNode']>;
8
+ constructor(strategy: SerializeStrategySync<K, V>, comparator: ValueComparator<V>, option?: BPTreeConstructorOption);
9
+ private _createCachedNode;
8
10
  protected getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean): BPTreePair<K, V>;
9
11
  protected getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean): BPTreePair<K, V>;
10
12
  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>;