serializable-bptree 1.0.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -92,6 +92,7 @@ var BPTree = class {
92
92
  search;
93
93
  order;
94
94
  nodes;
95
+ data;
95
96
  root;
96
97
  _creates;
97
98
  _updates;
@@ -131,14 +132,16 @@ var BPTree = class {
131
132
  this.comparator = comparator;
132
133
  if (head === null) {
133
134
  this.order = strategy.order;
135
+ this.data = {};
134
136
  this.root = this._createNode([], [], true);
135
137
  this._setHeadUpdate(this._headState);
136
138
  this._setCreates(this.root);
137
139
  this._emitHeadUpdates();
138
140
  this._emitCreates();
139
141
  } else {
140
- const { root, order } = head;
142
+ const { root, order, data } = head;
141
143
  this.order = order;
144
+ this.data = data ?? {};
142
145
  this.root = this.getNode(root);
143
146
  }
144
147
  if (this.order < 3) {
@@ -148,9 +151,11 @@ var BPTree = class {
148
151
  get _headState() {
149
152
  const root = this.root.id;
150
153
  const order = this.order;
154
+ const data = this.data;
151
155
  return {
152
156
  root,
153
- order
157
+ order,
158
+ data
154
159
  };
155
160
  }
156
161
  _setHeadUpdate(head) {
@@ -321,6 +326,124 @@ var BPTree = class {
321
326
  _rangeCondition(condition) {
322
327
  return Object.prototype.hasOwnProperty.call(condition, "gt") && Object.prototype.hasOwnProperty.call(condition, "lt");
323
328
  }
329
+ _getKeysFromValue(value) {
330
+ const keys = /* @__PURE__ */ new Set();
331
+ const node = this._insertableNode(value);
332
+ const [start, end] = this.search.range(node.values, value);
333
+ if (start === -1) {
334
+ return keys;
335
+ }
336
+ for (let i = start; i < end; i++) {
337
+ const pairKeys = node.keys[i];
338
+ for (const key of pairKeys) {
339
+ keys.add(key);
340
+ }
341
+ }
342
+ return keys;
343
+ }
344
+ _getKeysFromNEValue(value) {
345
+ const keys = /* @__PURE__ */ new Set();
346
+ let node = this.leftestNode();
347
+ let done = false;
348
+ while (!done) {
349
+ for (let i = 0, len = node.values.length; i < len; i++) {
350
+ const nValue = node.values[i];
351
+ const pairKeys = node.keys[i];
352
+ if (this.comparator.isSame(nValue, value) === false) {
353
+ for (const key of pairKeys) {
354
+ keys.add(key);
355
+ }
356
+ }
357
+ }
358
+ if (!node.next) {
359
+ done = true;
360
+ break;
361
+ }
362
+ node = this.getNode(node.next);
363
+ }
364
+ return keys;
365
+ }
366
+ _getKeysFromRange(gt, lt) {
367
+ const keys = /* @__PURE__ */ new Set();
368
+ let node = this._insertableNode(gt);
369
+ let done = false;
370
+ let found = false;
371
+ while (!done) {
372
+ for (let i = 0, len = node.values.length; i < len; i++) {
373
+ const nValue = node.values[i];
374
+ const localKeys = node.keys[i];
375
+ if (this.comparator.isHigher(nValue, gt) && this.comparator.isLower(nValue, lt)) {
376
+ found = true;
377
+ for (const key of localKeys) {
378
+ keys.add(key);
379
+ }
380
+ } else if (found) {
381
+ done = true;
382
+ break;
383
+ }
384
+ }
385
+ if (!node.next) {
386
+ done = true;
387
+ break;
388
+ }
389
+ node = this.getNode(node.next);
390
+ }
391
+ return keys;
392
+ }
393
+ _getKeysFromGt(gt) {
394
+ const keys = /* @__PURE__ */ new Set();
395
+ let node = this._insertableNode(gt);
396
+ let done = false;
397
+ let found = false;
398
+ while (!done) {
399
+ for (let i = 0, len = node.values.length; i < len; i++) {
400
+ const nValue = node.values[i];
401
+ const localKeys = node.keys[i];
402
+ if (this.comparator.isHigher(nValue, gt)) {
403
+ found = true;
404
+ for (const key of localKeys) {
405
+ keys.add(key);
406
+ }
407
+ } else if (found) {
408
+ done = true;
409
+ break;
410
+ }
411
+ }
412
+ if (!node.next) {
413
+ done = true;
414
+ break;
415
+ }
416
+ node = this.getNode(node.next);
417
+ }
418
+ return keys;
419
+ }
420
+ _getKeysFromLt(lt) {
421
+ const keys = /* @__PURE__ */ new Set();
422
+ let node = this.leftestNode();
423
+ let done = false;
424
+ let found = false;
425
+ while (!done) {
426
+ for (let i = 0, len = node.values.length; i < len; i++) {
427
+ const nValue = node.values[i];
428
+ const localKeys = node.keys[i];
429
+ if (this.comparator.isLower(nValue, lt)) {
430
+ found = true;
431
+ for (const key of localKeys) {
432
+ keys.add(key);
433
+ }
434
+ } else if (found) {
435
+ done = true;
436
+ break;
437
+ }
438
+ }
439
+ if (!node.next) {
440
+ done = true;
441
+ break;
442
+ }
443
+ node = this.getNode(node.next);
444
+ }
445
+ return keys;
446
+ }
324
447
  _getPairsFromValue(value) {
325
448
  const node = this._insertableNode(value);
326
449
  const [start, end] = this.search.range(node.values, value);
@@ -439,6 +562,28 @@ var BPTree = class {
439
562
  }
440
563
  return pairs;
441
564
  }
565
+ /**
566
+ * It searches for a key within the tree. The result is returned as an array sorted in ascending order based on the value.
567
+ * The result is key set instance, and you can use the `gt`, `lt`, `equal`, `notEqual` condition statements.
568
+ * This method operates much faster than first searching with `where` and then retrieving only the key list.
569
+ * @param condition You can use the `gt`, `lt`, `equal`, `notEqual` condition statements.
570
+ */
571
+ keys(condition) {
572
+ if (this._equalCondition(condition)) {
573
+ return this._getKeysFromValue(condition.equal);
574
+ } else if (this._notEqualCondition(condition)) {
575
+ return this._getKeysFromNEValue(condition.notEqual);
576
+ } else if (this._rangeCondition(condition)) {
577
+ const { gt, lt } = condition;
578
+ return this._getKeysFromRange(gt, lt);
579
+ } else if (this._onlyGtCondition(condition)) {
580
+ return this._getKeysFromGt(condition.gt);
581
+ } else if (this._onlyLtCondition(condition)) {
582
+ return this._getKeysFromLt(condition.lt);
583
+ } else {
584
+ throw new Error(`The 'condition' parameter is invalid.`);
585
+ }
586
+ }
442
587
  /**
443
588
  * It searches for a value within the tree. The result is returned as an array sorted in ascending order based on the value.
444
589
  * The result includes the key and value attributes, and you can use the `gt`, `lt`, `equal`, `notEqual` condition statements.
@@ -709,6 +854,25 @@ var BPTree = class {
709
854
  }
710
855
  }
711
856
  }
857
+ /**
858
+ * Returns the user-defined data stored in the head of the tree.
859
+ * 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 `{}`.
860
+ * @returns User-defined data stored in the head of the tree.
861
+ */
862
+ getHeadData() {
863
+ return this.data;
864
+ }
865
+ /**
866
+ * Inserts user-defined data into the head of the tree.
867
+ * This feature is useful when you need to store separate, non-volatile information in the tree.
868
+ * For example, you can store information such as the last update time and the number of insertions.
869
+ * @param data User-defined data to be stored in the head of the tree.
870
+ */
871
+ setHeadData(data) {
872
+ this.data = data;
873
+ this._updatedHead = this._headState;
874
+ this._emitHeadUpdates();
875
+ }
712
876
  };
713
877
 
714
878
  // src/SerializeStrategy.ts
package/dist/esm/index.js CHANGED
@@ -61,6 +61,7 @@ var BPTree = class {
61
61
  search;
62
62
  order;
63
63
  nodes;
64
+ data;
64
65
  root;
65
66
  _creates;
66
67
  _updates;
@@ -100,14 +101,16 @@ var BPTree = class {
100
101
  this.comparator = comparator;
101
102
  if (head === null) {
102
103
  this.order = strategy.order;
104
+ this.data = {};
103
105
  this.root = this._createNode([], [], true);
104
106
  this._setHeadUpdate(this._headState);
105
107
  this._setCreates(this.root);
106
108
  this._emitHeadUpdates();
107
109
  this._emitCreates();
108
110
  } else {
109
- const { root, order } = head;
111
+ const { root, order, data } = head;
110
112
  this.order = order;
113
+ this.data = data ?? {};
111
114
  this.root = this.getNode(root);
112
115
  }
113
116
  if (this.order < 3) {
@@ -117,9 +120,11 @@ var BPTree = class {
117
120
  get _headState() {
118
121
  const root = this.root.id;
119
122
  const order = this.order;
123
+ const data = this.data;
120
124
  return {
121
125
  root,
122
- order
126
+ order,
127
+ data
123
128
  };
124
129
  }
125
130
  _setHeadUpdate(head) {
@@ -290,6 +295,124 @@ var BPTree = class {
290
295
  _rangeCondition(condition) {
291
296
  return Object.prototype.hasOwnProperty.call(condition, "gt") && Object.prototype.hasOwnProperty.call(condition, "lt");
292
297
  }
298
+ _getKeysFromValue(value) {
299
+ const keys = /* @__PURE__ */ new Set();
300
+ const node = this._insertableNode(value);
301
+ const [start, end] = this.search.range(node.values, value);
302
+ if (start === -1) {
303
+ return keys;
304
+ }
305
+ for (let i = start; i < end; i++) {
306
+ const pairKeys = node.keys[i];
307
+ for (const key of pairKeys) {
308
+ keys.add(key);
309
+ }
310
+ }
311
+ return keys;
312
+ }
313
+ _getKeysFromNEValue(value) {
314
+ const keys = /* @__PURE__ */ new Set();
315
+ let node = this.leftestNode();
316
+ let done = false;
317
+ while (!done) {
318
+ for (let i = 0, len = node.values.length; i < len; i++) {
319
+ const nValue = node.values[i];
320
+ const pairKeys = node.keys[i];
321
+ if (this.comparator.isSame(nValue, value) === false) {
322
+ for (const key of pairKeys) {
323
+ keys.add(key);
324
+ }
325
+ }
326
+ }
327
+ if (!node.next) {
328
+ done = true;
329
+ break;
330
+ }
331
+ node = this.getNode(node.next);
332
+ }
333
+ return keys;
334
+ }
335
+ _getKeysFromRange(gt, lt) {
336
+ const keys = /* @__PURE__ */ new Set();
337
+ let node = this._insertableNode(gt);
338
+ let done = false;
339
+ let found = false;
340
+ while (!done) {
341
+ for (let i = 0, len = node.values.length; i < len; i++) {
342
+ const nValue = node.values[i];
343
+ const localKeys = node.keys[i];
344
+ if (this.comparator.isHigher(nValue, gt) && this.comparator.isLower(nValue, lt)) {
345
+ found = true;
346
+ for (const key of localKeys) {
347
+ keys.add(key);
348
+ }
349
+ } else if (found) {
350
+ done = true;
351
+ break;
352
+ }
353
+ }
354
+ if (!node.next) {
355
+ done = true;
356
+ break;
357
+ }
358
+ node = this.getNode(node.next);
359
+ }
360
+ return keys;
361
+ }
362
+ _getKeysFromGt(gt) {
363
+ const keys = /* @__PURE__ */ new Set();
364
+ let node = this._insertableNode(gt);
365
+ let done = false;
366
+ let found = false;
367
+ while (!done) {
368
+ for (let i = 0, len = node.values.length; i < len; i++) {
369
+ const nValue = node.values[i];
370
+ const localKeys = node.keys[i];
371
+ if (this.comparator.isHigher(nValue, gt)) {
372
+ found = true;
373
+ for (const key of localKeys) {
374
+ keys.add(key);
375
+ }
376
+ } else if (found) {
377
+ done = true;
378
+ break;
379
+ }
380
+ }
381
+ if (!node.next) {
382
+ done = true;
383
+ break;
384
+ }
385
+ node = this.getNode(node.next);
386
+ }
387
+ return keys;
388
+ }
389
+ _getKeysFromLt(lt) {
390
+ const keys = /* @__PURE__ */ new Set();
391
+ let node = this.leftestNode();
392
+ let done = false;
393
+ let found = false;
394
+ while (!done) {
395
+ for (let i = 0, len = node.values.length; i < len; i++) {
396
+ const nValue = node.values[i];
397
+ const localKeys = node.keys[i];
398
+ if (this.comparator.isLower(nValue, lt)) {
399
+ found = true;
400
+ for (const key of localKeys) {
401
+ keys.add(key);
402
+ }
403
+ } else if (found) {
404
+ done = true;
405
+ break;
406
+ }
407
+ }
408
+ if (!node.next) {
409
+ done = true;
410
+ break;
411
+ }
412
+ node = this.getNode(node.next);
413
+ }
414
+ return keys;
415
+ }
293
416
  _getPairsFromValue(value) {
294
417
  const node = this._insertableNode(value);
295
418
  const [start, end] = this.search.range(node.values, value);
@@ -408,6 +531,28 @@ var BPTree = class {
408
531
  }
409
532
  return pairs;
410
533
  }
534
+ /**
535
+ * It searches for a key within the tree. The result is returned as an array sorted in ascending order based on the value.
536
+ * The result is key set instance, and you can use the `gt`, `lt`, `equal`, `notEqual` condition statements.
537
+ * This method operates much faster than first searching with `where` and then retrieving only the key list.
538
+ * @param condition You can use the `gt`, `lt`, `equal`, `notEqual` condition statements.
539
+ */
540
+ keys(condition) {
541
+ if (this._equalCondition(condition)) {
542
+ return this._getKeysFromValue(condition.equal);
543
+ } else if (this._notEqualCondition(condition)) {
544
+ return this._getKeysFromNEValue(condition.notEqual);
545
+ } else if (this._rangeCondition(condition)) {
546
+ const { gt, lt } = condition;
547
+ return this._getKeysFromRange(gt, lt);
548
+ } else if (this._onlyGtCondition(condition)) {
549
+ return this._getKeysFromGt(condition.gt);
550
+ } else if (this._onlyLtCondition(condition)) {
551
+ return this._getKeysFromLt(condition.lt);
552
+ } else {
553
+ throw new Error(`The 'condition' parameter is invalid.`);
554
+ }
555
+ }
411
556
  /**
412
557
  * It searches for a value within the tree. The result is returned as an array sorted in ascending order based on the value.
413
558
  * The result includes the key and value attributes, and you can use the `gt`, `lt`, `equal`, `notEqual` condition statements.
@@ -678,6 +823,25 @@ var BPTree = class {
678
823
  }
679
824
  }
680
825
  }
826
+ /**
827
+ * Returns the user-defined data stored in the head of the tree.
828
+ * 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 `{}`.
829
+ * @returns User-defined data stored in the head of the tree.
830
+ */
831
+ getHeadData() {
832
+ return this.data;
833
+ }
834
+ /**
835
+ * Inserts user-defined data into the head of the tree.
836
+ * This feature is useful when you need to store separate, non-volatile information in the tree.
837
+ * For example, you can store information such as the last update time and the number of insertions.
838
+ * @param data User-defined data to be stored in the head of the tree.
839
+ */
840
+ setHeadData(data) {
841
+ this.data = data;
842
+ this._updatedHead = this._headState;
843
+ this._emitHeadUpdates();
844
+ }
681
845
  };
682
846
 
683
847
  // src/SerializeStrategy.ts
@@ -1,3 +1,4 @@
1
+ import type { Json } from './utils/types';
1
2
  import { BinarySearch } from './utils/BinarySearch';
2
3
  import { ValueComparator } from './ValueComparator';
3
4
  import { SerializeStrategy } from './SerializeStrategy';
@@ -36,6 +37,7 @@ export declare class BPTree<K, V> {
36
37
  protected readonly search: BinarySearch<V>;
37
38
  protected readonly order: number;
38
39
  protected readonly nodes: Map<number, BPTreeUnknownNode<K, V>>;
40
+ protected data: Record<string, Json>;
39
41
  protected root: BPTreeUnknownNode<K, V>;
40
42
  private readonly _creates;
41
43
  private readonly _updates;
@@ -70,11 +72,23 @@ export declare class BPTree<K, V> {
70
72
  private _onlyGtCondition;
71
73
  private _onlyLtCondition;
72
74
  private _rangeCondition;
75
+ private _getKeysFromValue;
76
+ private _getKeysFromNEValue;
77
+ private _getKeysFromRange;
78
+ private _getKeysFromGt;
79
+ private _getKeysFromLt;
73
80
  private _getPairsFromValue;
74
81
  private _getPairsFromNEValue;
75
82
  private _getPairsFromRange;
76
83
  private _getPairsFromGt;
77
84
  private _getPairsFromLt;
85
+ /**
86
+ * It searches for a key within the tree. The result is returned as an array sorted in ascending order based on the value.
87
+ * The result is key set instance, and you can use the `gt`, `lt`, `equal`, `notEqual` condition statements.
88
+ * This method operates much faster than first searching with `where` and then retrieving only the key list.
89
+ * @param condition You can use the `gt`, `lt`, `equal`, `notEqual` condition statements.
90
+ */
91
+ keys(condition: BPTreeCondition<V>): Set<K>;
78
92
  /**
79
93
  * It searches for a value within the tree. The result is returned as an array sorted in ascending order based on the value.
80
94
  * The result includes the key and value attributes, and you can use the `gt`, `lt`, `equal`, `notEqual` condition statements.
@@ -95,5 +109,18 @@ export declare class BPTree<K, V> {
95
109
  */
96
110
  delete(key: K, value: V): void;
97
111
  private _deleteEntry;
112
+ /**
113
+ * Returns the user-defined data stored in the head of the tree.
114
+ * 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 `{}`.
115
+ * @returns User-defined data stored in the head of the tree.
116
+ */
117
+ getHeadData(): Record<string, Json>;
118
+ /**
119
+ * Inserts user-defined data into the head of the tree.
120
+ * This feature is useful when you need to store separate, non-volatile information in the tree.
121
+ * For example, you can store information such as the last update time and the number of insertions.
122
+ * @param data User-defined data to be stored in the head of the tree.
123
+ */
124
+ setHeadData(data: Record<string, Json>): void;
98
125
  }
99
126
  export {};
@@ -1,7 +1,9 @@
1
1
  import { BPTreeNode } from './BPTree';
2
+ import type { Json } from './utils/types';
2
3
  export interface SerializeStrategyHead {
3
4
  root: number;
4
5
  order: number;
6
+ data: Record<string, Json>;
5
7
  }
6
8
  export declare abstract class SerializeStrategy<K, V> {
7
9
  readonly order: number;
@@ -0,0 +1,5 @@
1
+ type Primitive = string | number | null | boolean;
2
+ type Json = Primitive | Primitive[] | Json[] | {
3
+ [key: string]: Json;
4
+ };
5
+ export type { Json };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "serializable-bptree",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "description": "Store the B+tree flexibly, not only in-memory.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",