serializable-bptree 4.0.5 → 5.0.1

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 CHANGED
@@ -59,10 +59,10 @@ tree.insert('c', 3)
59
59
 
60
60
  tree.delete('b', 2)
61
61
 
62
- tree.where({ equal: 1 }) // [{ key: 'a', value: 1 }]
63
- tree.where({ gt: 1 }) // [{ key: 'c', value: 3 }]
64
- tree.where({ lt: 2 }) // [{ key: 'a', value: 1 }]
65
- tree.where({ gt: 0, lt: 4 }) // [{ key: 'a', value: 1 }, { key: 'c', value: 3 }]
62
+ tree.where({ equal: 1 }) // Map([{ key: 'a', value: 1 }])
63
+ tree.where({ gt: 1 }) // Map([{ key: 'c', value: 3 }])
64
+ tree.where({ lt: 2 }) // Map([{ key: 'a', value: 1 }])
65
+ tree.where({ gt: 0, lt: 4 }) // Map([{ key: 'a', value: 1 }, { key: 'c', value: 3 }])
66
66
  ```
67
67
 
68
68
  ## Why use a `serializable-bptree`?
@@ -102,7 +102,7 @@ import {
102
102
  ValueComparator,
103
103
  NumericComparator,
104
104
  StringComparator
105
- } from 'https://cdn.jsdelivr.net/npm/serializable-bptree@4.x.x/dist/esm/index.min.js'
105
+ } from 'https://cdn.jsdelivr.net/npm/serializable-bptree@5.x.x/dist/esm/index.min.js'
106
106
  </script>
107
107
  ```
108
108
 
@@ -417,10 +417,10 @@ await tree.insert('c', 3)
417
417
 
418
418
  await tree.delete('b', 2)
419
419
 
420
- await tree.where({ equal: 1 }) // [{ key: 'a', value: 1 }]
421
- await tree.where({ gt: 1 }) // [{ key: 'c', value: 3 }]
422
- await tree.where({ lt: 2 }) // [{ key: 'a', value: 1 }]
423
- await tree.where({ gt: 0, lt: 4 }) // [{ key: 'a', value: 1 }, { key: 'c', value: 3 }]
420
+ await tree.where({ equal: 1 }) // Map([{ key: 'a', value: 1 }])
421
+ await tree.where({ gt: 1 }) // Map([{ key: 'c', value: 3 }])
422
+ await tree.where({ lt: 2 }) // Map([{ key: 'a', value: 1 }])
423
+ await tree.where({ gt: 0, lt: 4 }) // Map([{ key: 'a', value: 1 }, { key: 'c', value: 3 }])
424
424
  ```
425
425
 
426
426
  The implementation method for asynchronous operations is not significantly different. The **-Async** suffix is used instead of the **-Sync** suffix in the **BPTree** and **SerializeStrategy** classes. The only difference is that the methods become asynchronous. The **ValueComparator** class and similar value comparators do not use asynchronous operations.
@@ -102,6 +102,7 @@ var BPTree = class {
102
102
  nodes;
103
103
  order;
104
104
  root;
105
+ _strategyDirty;
105
106
  _nodeCreateBuffer;
106
107
  _nodeUpdateBuffer;
107
108
  _nodeDeleteBuffer;
@@ -152,6 +153,7 @@ var BPTree = class {
152
153
  like: true
153
154
  };
154
155
  constructor(strategy, comparator) {
156
+ this._strategyDirty = false;
155
157
  this._cachedRegexp = new InvertedWeakMap();
156
158
  this._nodeCreateBuffer = /* @__PURE__ */ new Map();
157
159
  this._nodeUpdateBuffer = /* @__PURE__ */ new Map();
@@ -211,7 +213,7 @@ var BPTreeSync = class extends BPTree {
211
213
  constructor(strategy, comparator) {
212
214
  super(strategy, comparator);
213
215
  }
214
- _getPairsRightToLeft(value, startNode, fullScan, comparator) {
216
+ getPairsRightToLeft(value, startNode, fullScan, comparator) {
215
217
  const pairs = [];
216
218
  let node = startNode;
217
219
  let done = false;
@@ -225,7 +227,7 @@ var BPTreeSync = class extends BPTree {
225
227
  found = true;
226
228
  let j = keys.length;
227
229
  while (j--) {
228
- pairs.push({ key: keys[j], value: nValue });
230
+ pairs.push([keys[j], nValue]);
229
231
  }
230
232
  } else if (found && !fullScan) {
231
233
  done = true;
@@ -238,9 +240,9 @@ var BPTreeSync = class extends BPTree {
238
240
  }
239
241
  node = this.getNode(node.prev);
240
242
  }
241
- return pairs.reverse();
243
+ return new Map(pairs.reverse());
242
244
  }
243
- _getPairsLeftToRight(value, startNode, fullScan, comparator) {
245
+ getPairsLeftToRight(value, startNode, fullScan, comparator) {
244
246
  const pairs = [];
245
247
  let node = startNode;
246
248
  let done = false;
@@ -251,8 +253,9 @@ var BPTreeSync = class extends BPTree {
251
253
  const keys = node.keys[i];
252
254
  if (comparator(nValue, value)) {
253
255
  found = true;
254
- for (const key of keys) {
255
- pairs.push({ key, value: nValue });
256
+ for (let j = 0, len2 = keys.length; j < len2; j++) {
257
+ const key = keys[j];
258
+ pairs.push([key, nValue]);
256
259
  }
257
260
  } else if (found && !fullScan) {
258
261
  done = true;
@@ -265,14 +268,14 @@ var BPTreeSync = class extends BPTree {
265
268
  }
266
269
  node = this.getNode(node.next);
267
270
  }
268
- return pairs;
271
+ return new Map(pairs);
269
272
  }
270
273
  getPairs(value, startNode, fullScan, comparator, direction) {
271
274
  switch (direction) {
272
275
  case -1:
273
- return this._getPairsRightToLeft(value, startNode, fullScan, comparator);
276
+ return this.getPairsRightToLeft(value, startNode, fullScan, comparator);
274
277
  case 1:
275
- return this._getPairsLeftToRight(value, startNode, fullScan, comparator);
278
+ return this.getPairsLeftToRight(value, startNode, fullScan, comparator);
276
279
  default:
277
280
  throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
278
281
  }
@@ -323,6 +326,7 @@ var BPTreeSync = class extends BPTree {
323
326
  this.root = this.getNode(keys[0]);
324
327
  this.root.parent = null;
325
328
  this.strategy.head.root = this.root.id;
329
+ this._strategyDirty = true;
326
330
  this.bufferForNodeUpdate(this.root);
327
331
  return;
328
332
  } else if (this.root === node) {
@@ -506,6 +510,7 @@ var BPTreeSync = class extends BPTree {
506
510
  const root = this._createNode(false, [node.id, pointer.id], [value]);
507
511
  this.root = root;
508
512
  this.strategy.head.root = root.id;
513
+ this._strategyDirty = true;
509
514
  node.parent = root.id;
510
515
  pointer.parent = root.id;
511
516
  this.bufferForNodeCreate(root);
@@ -604,6 +609,10 @@ var BPTreeSync = class extends BPTree {
604
609
  return node;
605
610
  }
606
611
  commitHeadBuffer() {
612
+ if (!this._strategyDirty) {
613
+ return;
614
+ }
615
+ this._strategyDirty = false;
607
616
  this.strategy.writeHead(this.strategy.head);
608
617
  }
609
618
  commitNodeCreateBuffer() {
@@ -634,11 +643,11 @@ var BPTreeSync = class extends BPTree {
634
643
  const comparator = this.verifierMap[key];
635
644
  const pairs = this.getPairs(value, startNode, fullScan, comparator, direction);
636
645
  if (!filterValues) {
637
- filterValues = new Set(pairs.map((pair) => pair.key));
646
+ filterValues = new Set(pairs.keys());
638
647
  } else {
639
648
  const intersections = /* @__PURE__ */ new Set();
640
649
  for (const key2 of filterValues) {
641
- const has = pairs.some((pair) => pair.key === key2);
650
+ const has = pairs.has(key2);
642
651
  if (has) {
643
652
  intersections.add(key2);
644
653
  }
@@ -661,16 +670,16 @@ var BPTreeSync = class extends BPTree {
661
670
  if (result === null) {
662
671
  result = pairs;
663
672
  } else {
664
- const intersection = [];
665
- for (const pair of pairs) {
666
- if (result.find((p) => p.key === pair.key)) {
667
- intersection.push(pair);
673
+ const intersection = /* @__PURE__ */ new Map();
674
+ for (const [k2, v] of pairs) {
675
+ if (result.has(k2)) {
676
+ intersection.set(k2, v);
668
677
  }
669
678
  }
670
679
  result = intersection;
671
680
  }
672
681
  }
673
- return result ?? [];
682
+ return result ?? /* @__PURE__ */ new Map();
674
683
  }
675
684
  insert(key, value) {
676
685
  const before = this.insertableNode(value);
@@ -748,6 +757,7 @@ var BPTreeSync = class extends BPTree {
748
757
  }
749
758
  setHeadData(data) {
750
759
  this.strategy.head.data = data;
760
+ this._strategyDirty = true;
751
761
  this.commitHeadBuffer();
752
762
  }
753
763
  forceUpdate() {
@@ -766,7 +776,7 @@ var BPTreeAsync = class extends BPTree {
766
776
  constructor(strategy, comparator) {
767
777
  super(strategy, comparator);
768
778
  }
769
- async _getPairsRightToLeft(value, startNode, fullScan, comparator) {
779
+ async getPairsRightToLeft(value, startNode, fullScan, comparator) {
770
780
  const pairs = [];
771
781
  let node = startNode;
772
782
  let done = false;
@@ -780,7 +790,7 @@ var BPTreeAsync = class extends BPTree {
780
790
  found = true;
781
791
  let j = keys.length;
782
792
  while (j--) {
783
- pairs.push({ key: keys[j], value: nValue });
793
+ pairs.push([keys[j], nValue]);
784
794
  }
785
795
  } else if (found && !fullScan) {
786
796
  done = true;
@@ -793,9 +803,9 @@ var BPTreeAsync = class extends BPTree {
793
803
  }
794
804
  node = await this.getNode(node.prev);
795
805
  }
796
- return pairs.reverse();
806
+ return new Map(pairs.reverse());
797
807
  }
798
- async _getPairsLeftToRight(value, startNode, fullScan, comparator) {
808
+ async getPairsLeftToRight(value, startNode, fullScan, comparator) {
799
809
  const pairs = [];
800
810
  let node = startNode;
801
811
  let done = false;
@@ -806,8 +816,9 @@ var BPTreeAsync = class extends BPTree {
806
816
  const keys = node.keys[i];
807
817
  if (comparator(nValue, value)) {
808
818
  found = true;
809
- for (const key of keys) {
810
- pairs.push({ key, value: nValue });
819
+ for (let j = 0, len2 = keys.length; j < len2; j++) {
820
+ const key = keys[j];
821
+ pairs.push([key, nValue]);
811
822
  }
812
823
  } else if (found && !fullScan) {
813
824
  done = true;
@@ -820,14 +831,14 @@ var BPTreeAsync = class extends BPTree {
820
831
  }
821
832
  node = await this.getNode(node.next);
822
833
  }
823
- return pairs;
834
+ return new Map(pairs);
824
835
  }
825
836
  async getPairs(value, startNode, fullScan, comparator, direction) {
826
837
  switch (direction) {
827
838
  case -1:
828
- return await this._getPairsRightToLeft(value, startNode, fullScan, comparator);
839
+ return await this.getPairsRightToLeft(value, startNode, fullScan, comparator);
829
840
  case 1:
830
- return await this._getPairsLeftToRight(value, startNode, fullScan, comparator);
841
+ return await this.getPairsLeftToRight(value, startNode, fullScan, comparator);
831
842
  default:
832
843
  throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
833
844
  }
@@ -878,6 +889,7 @@ var BPTreeAsync = class extends BPTree {
878
889
  this.root = await this.getNode(keys[0]);
879
890
  this.root.parent = null;
880
891
  this.strategy.head.root = this.root.id;
892
+ this._strategyDirty = true;
881
893
  this.bufferForNodeUpdate(this.root);
882
894
  return;
883
895
  } else if (this.root === node) {
@@ -1061,6 +1073,7 @@ var BPTreeAsync = class extends BPTree {
1061
1073
  const root = await this._createNode(false, [node.id, pointer.id], [value]);
1062
1074
  this.root = root;
1063
1075
  this.strategy.head.root = root.id;
1076
+ this._strategyDirty = true;
1064
1077
  node.parent = root.id;
1065
1078
  pointer.parent = root.id;
1066
1079
  this.bufferForNodeCreate(root);
@@ -1159,6 +1172,10 @@ var BPTreeAsync = class extends BPTree {
1159
1172
  return node;
1160
1173
  }
1161
1174
  async commitHeadBuffer() {
1175
+ if (!this._strategyDirty) {
1176
+ return;
1177
+ }
1178
+ this._strategyDirty = false;
1162
1179
  await this.strategy.writeHead(this.strategy.head);
1163
1180
  }
1164
1181
  async commitNodeCreateBuffer() {
@@ -1189,11 +1206,11 @@ var BPTreeAsync = class extends BPTree {
1189
1206
  const comparator = this.verifierMap[key];
1190
1207
  const pairs = await this.getPairs(value, startNode, fullScan, comparator, direction);
1191
1208
  if (!filterValues) {
1192
- filterValues = new Set(pairs.map((pair) => pair.key));
1209
+ filterValues = new Set(pairs.keys());
1193
1210
  } else {
1194
1211
  const intersections = /* @__PURE__ */ new Set();
1195
1212
  for (const key2 of filterValues) {
1196
- const has = pairs.some((pair) => pair.key === key2);
1213
+ const has = pairs.has(key2);
1197
1214
  if (has) {
1198
1215
  intersections.add(key2);
1199
1216
  }
@@ -1216,16 +1233,16 @@ var BPTreeAsync = class extends BPTree {
1216
1233
  if (result === null) {
1217
1234
  result = pairs;
1218
1235
  } else {
1219
- const intersection = [];
1220
- for (const pair of pairs) {
1221
- if (result.find((p) => p.key === pair.key)) {
1222
- intersection.push(pair);
1236
+ const intersection = /* @__PURE__ */ new Map();
1237
+ for (const [k2, v] of pairs) {
1238
+ if (result.has(k2)) {
1239
+ intersection.set(k2, v);
1223
1240
  }
1224
1241
  }
1225
1242
  result = intersection;
1226
1243
  }
1227
1244
  }
1228
- return result ?? [];
1245
+ return result ?? /* @__PURE__ */ new Map();
1229
1246
  }
1230
1247
  async insert(key, value) {
1231
1248
  const before = await this.insertableNode(value);
@@ -1303,6 +1320,7 @@ var BPTreeAsync = class extends BPTree {
1303
1320
  }
1304
1321
  async setHeadData(data) {
1305
1322
  this.strategy.head.data = data;
1323
+ this._strategyDirty = true;
1306
1324
  await this.commitHeadBuffer();
1307
1325
  }
1308
1326
  async forceUpdate() {
@@ -68,6 +68,7 @@ var BPTree = class {
68
68
  nodes;
69
69
  order;
70
70
  root;
71
+ _strategyDirty;
71
72
  _nodeCreateBuffer;
72
73
  _nodeUpdateBuffer;
73
74
  _nodeDeleteBuffer;
@@ -118,6 +119,7 @@ var BPTree = class {
118
119
  like: true
119
120
  };
120
121
  constructor(strategy, comparator) {
122
+ this._strategyDirty = false;
121
123
  this._cachedRegexp = new InvertedWeakMap();
122
124
  this._nodeCreateBuffer = /* @__PURE__ */ new Map();
123
125
  this._nodeUpdateBuffer = /* @__PURE__ */ new Map();
@@ -177,7 +179,7 @@ var BPTreeSync = class extends BPTree {
177
179
  constructor(strategy, comparator) {
178
180
  super(strategy, comparator);
179
181
  }
180
- _getPairsRightToLeft(value, startNode, fullScan, comparator) {
182
+ getPairsRightToLeft(value, startNode, fullScan, comparator) {
181
183
  const pairs = [];
182
184
  let node = startNode;
183
185
  let done = false;
@@ -191,7 +193,7 @@ var BPTreeSync = class extends BPTree {
191
193
  found = true;
192
194
  let j = keys.length;
193
195
  while (j--) {
194
- pairs.push({ key: keys[j], value: nValue });
196
+ pairs.push([keys[j], nValue]);
195
197
  }
196
198
  } else if (found && !fullScan) {
197
199
  done = true;
@@ -204,9 +206,9 @@ var BPTreeSync = class extends BPTree {
204
206
  }
205
207
  node = this.getNode(node.prev);
206
208
  }
207
- return pairs.reverse();
209
+ return new Map(pairs.reverse());
208
210
  }
209
- _getPairsLeftToRight(value, startNode, fullScan, comparator) {
211
+ getPairsLeftToRight(value, startNode, fullScan, comparator) {
210
212
  const pairs = [];
211
213
  let node = startNode;
212
214
  let done = false;
@@ -217,8 +219,9 @@ var BPTreeSync = class extends BPTree {
217
219
  const keys = node.keys[i];
218
220
  if (comparator(nValue, value)) {
219
221
  found = true;
220
- for (const key of keys) {
221
- pairs.push({ key, value: nValue });
222
+ for (let j = 0, len2 = keys.length; j < len2; j++) {
223
+ const key = keys[j];
224
+ pairs.push([key, nValue]);
222
225
  }
223
226
  } else if (found && !fullScan) {
224
227
  done = true;
@@ -231,14 +234,14 @@ var BPTreeSync = class extends BPTree {
231
234
  }
232
235
  node = this.getNode(node.next);
233
236
  }
234
- return pairs;
237
+ return new Map(pairs);
235
238
  }
236
239
  getPairs(value, startNode, fullScan, comparator, direction) {
237
240
  switch (direction) {
238
241
  case -1:
239
- return this._getPairsRightToLeft(value, startNode, fullScan, comparator);
242
+ return this.getPairsRightToLeft(value, startNode, fullScan, comparator);
240
243
  case 1:
241
- return this._getPairsLeftToRight(value, startNode, fullScan, comparator);
244
+ return this.getPairsLeftToRight(value, startNode, fullScan, comparator);
242
245
  default:
243
246
  throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
244
247
  }
@@ -289,6 +292,7 @@ var BPTreeSync = class extends BPTree {
289
292
  this.root = this.getNode(keys[0]);
290
293
  this.root.parent = null;
291
294
  this.strategy.head.root = this.root.id;
295
+ this._strategyDirty = true;
292
296
  this.bufferForNodeUpdate(this.root);
293
297
  return;
294
298
  } else if (this.root === node) {
@@ -472,6 +476,7 @@ var BPTreeSync = class extends BPTree {
472
476
  const root = this._createNode(false, [node.id, pointer.id], [value]);
473
477
  this.root = root;
474
478
  this.strategy.head.root = root.id;
479
+ this._strategyDirty = true;
475
480
  node.parent = root.id;
476
481
  pointer.parent = root.id;
477
482
  this.bufferForNodeCreate(root);
@@ -570,6 +575,10 @@ var BPTreeSync = class extends BPTree {
570
575
  return node;
571
576
  }
572
577
  commitHeadBuffer() {
578
+ if (!this._strategyDirty) {
579
+ return;
580
+ }
581
+ this._strategyDirty = false;
573
582
  this.strategy.writeHead(this.strategy.head);
574
583
  }
575
584
  commitNodeCreateBuffer() {
@@ -600,11 +609,11 @@ var BPTreeSync = class extends BPTree {
600
609
  const comparator = this.verifierMap[key];
601
610
  const pairs = this.getPairs(value, startNode, fullScan, comparator, direction);
602
611
  if (!filterValues) {
603
- filterValues = new Set(pairs.map((pair) => pair.key));
612
+ filterValues = new Set(pairs.keys());
604
613
  } else {
605
614
  const intersections = /* @__PURE__ */ new Set();
606
615
  for (const key2 of filterValues) {
607
- const has = pairs.some((pair) => pair.key === key2);
616
+ const has = pairs.has(key2);
608
617
  if (has) {
609
618
  intersections.add(key2);
610
619
  }
@@ -627,16 +636,16 @@ var BPTreeSync = class extends BPTree {
627
636
  if (result === null) {
628
637
  result = pairs;
629
638
  } else {
630
- const intersection = [];
631
- for (const pair of pairs) {
632
- if (result.find((p) => p.key === pair.key)) {
633
- intersection.push(pair);
639
+ const intersection = /* @__PURE__ */ new Map();
640
+ for (const [k2, v] of pairs) {
641
+ if (result.has(k2)) {
642
+ intersection.set(k2, v);
634
643
  }
635
644
  }
636
645
  result = intersection;
637
646
  }
638
647
  }
639
- return result ?? [];
648
+ return result ?? /* @__PURE__ */ new Map();
640
649
  }
641
650
  insert(key, value) {
642
651
  const before = this.insertableNode(value);
@@ -714,6 +723,7 @@ var BPTreeSync = class extends BPTree {
714
723
  }
715
724
  setHeadData(data) {
716
725
  this.strategy.head.data = data;
726
+ this._strategyDirty = true;
717
727
  this.commitHeadBuffer();
718
728
  }
719
729
  forceUpdate() {
@@ -732,7 +742,7 @@ var BPTreeAsync = class extends BPTree {
732
742
  constructor(strategy, comparator) {
733
743
  super(strategy, comparator);
734
744
  }
735
- async _getPairsRightToLeft(value, startNode, fullScan, comparator) {
745
+ async getPairsRightToLeft(value, startNode, fullScan, comparator) {
736
746
  const pairs = [];
737
747
  let node = startNode;
738
748
  let done = false;
@@ -746,7 +756,7 @@ var BPTreeAsync = class extends BPTree {
746
756
  found = true;
747
757
  let j = keys.length;
748
758
  while (j--) {
749
- pairs.push({ key: keys[j], value: nValue });
759
+ pairs.push([keys[j], nValue]);
750
760
  }
751
761
  } else if (found && !fullScan) {
752
762
  done = true;
@@ -759,9 +769,9 @@ var BPTreeAsync = class extends BPTree {
759
769
  }
760
770
  node = await this.getNode(node.prev);
761
771
  }
762
- return pairs.reverse();
772
+ return new Map(pairs.reverse());
763
773
  }
764
- async _getPairsLeftToRight(value, startNode, fullScan, comparator) {
774
+ async getPairsLeftToRight(value, startNode, fullScan, comparator) {
765
775
  const pairs = [];
766
776
  let node = startNode;
767
777
  let done = false;
@@ -772,8 +782,9 @@ var BPTreeAsync = class extends BPTree {
772
782
  const keys = node.keys[i];
773
783
  if (comparator(nValue, value)) {
774
784
  found = true;
775
- for (const key of keys) {
776
- pairs.push({ key, value: nValue });
785
+ for (let j = 0, len2 = keys.length; j < len2; j++) {
786
+ const key = keys[j];
787
+ pairs.push([key, nValue]);
777
788
  }
778
789
  } else if (found && !fullScan) {
779
790
  done = true;
@@ -786,14 +797,14 @@ var BPTreeAsync = class extends BPTree {
786
797
  }
787
798
  node = await this.getNode(node.next);
788
799
  }
789
- return pairs;
800
+ return new Map(pairs);
790
801
  }
791
802
  async getPairs(value, startNode, fullScan, comparator, direction) {
792
803
  switch (direction) {
793
804
  case -1:
794
- return await this._getPairsRightToLeft(value, startNode, fullScan, comparator);
805
+ return await this.getPairsRightToLeft(value, startNode, fullScan, comparator);
795
806
  case 1:
796
- return await this._getPairsLeftToRight(value, startNode, fullScan, comparator);
807
+ return await this.getPairsLeftToRight(value, startNode, fullScan, comparator);
797
808
  default:
798
809
  throw new Error(`Direction must be -1 or 1. but got a ${direction}`);
799
810
  }
@@ -844,6 +855,7 @@ var BPTreeAsync = class extends BPTree {
844
855
  this.root = await this.getNode(keys[0]);
845
856
  this.root.parent = null;
846
857
  this.strategy.head.root = this.root.id;
858
+ this._strategyDirty = true;
847
859
  this.bufferForNodeUpdate(this.root);
848
860
  return;
849
861
  } else if (this.root === node) {
@@ -1027,6 +1039,7 @@ var BPTreeAsync = class extends BPTree {
1027
1039
  const root = await this._createNode(false, [node.id, pointer.id], [value]);
1028
1040
  this.root = root;
1029
1041
  this.strategy.head.root = root.id;
1042
+ this._strategyDirty = true;
1030
1043
  node.parent = root.id;
1031
1044
  pointer.parent = root.id;
1032
1045
  this.bufferForNodeCreate(root);
@@ -1125,6 +1138,10 @@ var BPTreeAsync = class extends BPTree {
1125
1138
  return node;
1126
1139
  }
1127
1140
  async commitHeadBuffer() {
1141
+ if (!this._strategyDirty) {
1142
+ return;
1143
+ }
1144
+ this._strategyDirty = false;
1128
1145
  await this.strategy.writeHead(this.strategy.head);
1129
1146
  }
1130
1147
  async commitNodeCreateBuffer() {
@@ -1155,11 +1172,11 @@ var BPTreeAsync = class extends BPTree {
1155
1172
  const comparator = this.verifierMap[key];
1156
1173
  const pairs = await this.getPairs(value, startNode, fullScan, comparator, direction);
1157
1174
  if (!filterValues) {
1158
- filterValues = new Set(pairs.map((pair) => pair.key));
1175
+ filterValues = new Set(pairs.keys());
1159
1176
  } else {
1160
1177
  const intersections = /* @__PURE__ */ new Set();
1161
1178
  for (const key2 of filterValues) {
1162
- const has = pairs.some((pair) => pair.key === key2);
1179
+ const has = pairs.has(key2);
1163
1180
  if (has) {
1164
1181
  intersections.add(key2);
1165
1182
  }
@@ -1182,16 +1199,16 @@ var BPTreeAsync = class extends BPTree {
1182
1199
  if (result === null) {
1183
1200
  result = pairs;
1184
1201
  } else {
1185
- const intersection = [];
1186
- for (const pair of pairs) {
1187
- if (result.find((p) => p.key === pair.key)) {
1188
- intersection.push(pair);
1202
+ const intersection = /* @__PURE__ */ new Map();
1203
+ for (const [k2, v] of pairs) {
1204
+ if (result.has(k2)) {
1205
+ intersection.set(k2, v);
1189
1206
  }
1190
1207
  }
1191
1208
  result = intersection;
1192
1209
  }
1193
1210
  }
1194
- return result ?? [];
1211
+ return result ?? /* @__PURE__ */ new Map();
1195
1212
  }
1196
1213
  async insert(key, value) {
1197
1214
  const before = await this.insertableNode(value);
@@ -1269,6 +1286,7 @@ var BPTreeAsync = class extends BPTree {
1269
1286
  }
1270
1287
  async setHeadData(data) {
1271
1288
  this.strategy.head.data = data;
1289
+ this._strategyDirty = true;
1272
1290
  await this.commitHeadBuffer();
1273
1291
  }
1274
1292
  async forceUpdate() {
@@ -5,9 +5,9 @@ import { SerializableData } from './base/SerializeStrategy';
5
5
  export declare class BPTreeAsync<K, V> extends BPTree<K, V> {
6
6
  protected readonly strategy: SerializeStrategyAsync<K, V>;
7
7
  constructor(strategy: SerializeStrategyAsync<K, V>, comparator: ValueComparator<V>);
8
- protected _getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): Promise<BPTreePair<K, V>[]>;
9
- protected _getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): Promise<BPTreePair<K, V>[]>;
10
- protected getPairs(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean, direction: 1 | -1): Promise<BPTreePair<K, V>[]>;
8
+ protected getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): Promise<BPTreePair<K, V>>;
9
+ protected getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): Promise<BPTreePair<K, V>>;
10
+ protected getPairs(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean, direction: 1 | -1): Promise<BPTreePair<K, V>>;
11
11
  protected _createNodeId(isLeaf: boolean): Promise<string>;
12
12
  protected _createNode(isLeaf: boolean, keys: string[] | K[][], values: V[], leaf?: boolean, parent?: string | null, next?: string | null, prev?: string | null): Promise<BPTreeUnknownNode<K, V>>;
13
13
  protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>, value: V): Promise<void>;
@@ -21,7 +21,7 @@ export declare class BPTreeAsync<K, V> extends BPTree<K, V> {
21
21
  protected commitNodeUpdateBuffer(): Promise<void>;
22
22
  protected commitNodeDeleteBuffer(): Promise<void>;
23
23
  keys(condition: BPTreeCondition<V>, filterValues?: Set<K>): Promise<Set<K>>;
24
- where(condition: BPTreeCondition<V>): Promise<BPTreePair<K, V>[]>;
24
+ where(condition: BPTreeCondition<V>): Promise<BPTreePair<K, V>>;
25
25
  insert(key: K, value: V): Promise<void>;
26
26
  delete(key: K, value: V): Promise<void>;
27
27
  exists(key: K, value: V): Promise<boolean>;
@@ -5,9 +5,9 @@ import { SerializableData } from './base/SerializeStrategy';
5
5
  export declare class BPTreeSync<K, V> extends BPTree<K, V> {
6
6
  protected readonly strategy: SerializeStrategySync<K, V>;
7
7
  constructor(strategy: SerializeStrategySync<K, V>, comparator: ValueComparator<V>);
8
- protected _getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): BPTreePair<K, V>[];
9
- protected _getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): BPTreePair<K, V>[];
10
- protected getPairs(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean, direction: 1 | -1): BPTreePair<K, V>[];
8
+ protected getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): BPTreePair<K, V>;
9
+ protected getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): BPTreePair<K, V>;
10
+ protected getPairs(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean, direction: 1 | -1): BPTreePair<K, V>;
11
11
  protected _createNodeId(isLeaf: boolean): string;
12
12
  protected _createNode(isLeaf: boolean, keys: string[] | K[][], values: V[], leaf?: boolean, parent?: string | null, next?: string | null, prev?: string | null): BPTreeUnknownNode<K, V>;
13
13
  protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>, value: V): void;
@@ -21,7 +21,7 @@ export declare class BPTreeSync<K, V> extends BPTree<K, V> {
21
21
  protected commitNodeUpdateBuffer(): void;
22
22
  protected commitNodeDeleteBuffer(): void;
23
23
  keys(condition: BPTreeCondition<V>, filterValues?: Set<K>): Set<K>;
24
- where(condition: BPTreeCondition<V>): BPTreePair<K, V>[];
24
+ where(condition: BPTreeCondition<V>): BPTreePair<K, V>;
25
25
  insert(key: K, value: V): void;
26
26
  delete(key: K, value: V): void;
27
27
  exists(key: K, value: V): boolean;
@@ -21,10 +21,7 @@ export type BPTreeCondition<V> = Partial<{
21
21
  /** Searches for values matching the given pattern. '%' matches zero or more characters, and '_' matches exactly one character. */
22
22
  like: Partial<V>;
23
23
  }>;
24
- export type BPTreePair<K, V> = {
25
- key: K;
26
- value: V;
27
- };
24
+ export type BPTreePair<K, V> = Map<K, V>;
28
25
  export type BPTreeUnknownNode<K, V> = BPTreeInternalNode<K, V> | BPTreeLeafNode<K, V>;
29
26
  export interface BPTreeNode<K, V> {
30
27
  id: string;
@@ -50,6 +47,7 @@ export declare abstract class BPTree<K, V> {
50
47
  protected readonly nodes: InvertedWeakMap<string, BPTreeUnknownNode<K, V>>;
51
48
  protected order: number;
52
49
  protected root: BPTreeUnknownNode<K, V>;
50
+ protected _strategyDirty: boolean;
53
51
  protected readonly _nodeCreateBuffer: Map<string, BPTreeUnknownNode<K, V>>;
54
52
  protected readonly _nodeUpdateBuffer: Map<string, BPTreeUnknownNode<K, V>>;
55
53
  protected readonly _nodeDeleteBuffer: Map<string, BPTreeUnknownNode<K, V>>;
@@ -58,9 +56,9 @@ export declare abstract class BPTree<K, V> {
58
56
  protected readonly verifierDirection: Record<keyof BPTreeCondition<V>, -1 | 1>;
59
57
  protected readonly verifierFullScan: Record<keyof BPTreeCondition<V>, boolean>;
60
58
  protected constructor(strategy: SerializeStrategy<K, V>, comparator: ValueComparator<V>);
61
- protected abstract _getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): Deferred<BPTreePair<K, V>[]>;
62
- protected abstract _getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): Deferred<BPTreePair<K, V>[]>;
63
- protected abstract getPairs(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean, direction: -1 | 1): Deferred<BPTreePair<K, V>[]>;
59
+ protected abstract getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): Deferred<BPTreePair<K, V>>;
60
+ protected abstract getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): Deferred<BPTreePair<K, V>>;
61
+ protected abstract getPairs(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean, direction: -1 | 1): Deferred<BPTreePair<K, V>>;
64
62
  protected abstract _createNodeId(isLeaf: boolean): Deferred<string>;
65
63
  protected abstract _createNode(isLeaf: boolean, keys: string[] | K[][], values: V[], leaf?: boolean, parent?: string | null, next?: string | null, prev?: string | null): Deferred<BPTreeUnknownNode<K, V>>;
66
64
  protected abstract _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>, value: V): Deferred<void>;
@@ -92,7 +90,7 @@ export declare abstract class BPTree<K, V> {
92
90
  * The result includes the key and value attributes, and you can use the `gt`, `lt`, `gte`, `lte`, `equal`, `notEqual`, `like` condition statements.
93
91
  * @param condition You can use the `gt`, `lt`, `gte`, `lte`, `equal`, `notEqual`, `like` condition statements.
94
92
  */
95
- abstract where(condition: BPTreeCondition<V>): Deferred<BPTreePair<K, V>[]>;
93
+ abstract where(condition: BPTreeCondition<V>): Deferred<BPTreePair<K, V>>;
96
94
  /**
97
95
  * You enter the key and value as a pair. You can later search for the pair by value.
98
96
  * This data is stored in the tree, sorted in ascending order of value.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "serializable-bptree",
3
- "version": "4.0.5",
3
+ "version": "5.0.1",
4
4
  "description": "Store the B+tree flexibly, not only in-memory.",
5
5
  "types": "./dist/types/index.d.ts",
6
6
  "main": "./dist/cjs/index.cjs",