serializable-bptree 3.4.0-alpha.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  This is a B+tree that's totally okay with duplicate values. If you need to keep track of the B+ tree's state, don't just leave it in memory - make sure you write it down.
7
7
 
8
8
  ```typescript
9
- import { readFileSync, writeFileSync, existsSync } from 'fs'
9
+ import { readFileSync, writeFileSync, unlinkSync, existsSync } from 'fs'
10
10
  import {
11
11
  BPTreeSync,
12
12
  SerializeStrategySync,
@@ -14,18 +14,22 @@ import {
14
14
  } from 'serializable-bptree'
15
15
 
16
16
  class FileStoreStrategySync extends SerializeStrategySync<K, V> {
17
- id(): number {
18
- return this.autoIncrement('index', 1)
17
+ id(): string {
18
+ return this.autoIncrement('index', 1).toString()
19
19
  }
20
20
 
21
- read(id: number): BPTreeNode<K, V> {
22
- const raw = readFileSync(id.toString(), 'utf8')
21
+ read(id: string): BPTreeNode<K, V> {
22
+ const raw = readFileSync(id, 'utf8')
23
23
  return JSON.parse(raw)
24
24
  }
25
25
 
26
- write(id: number, node: BPTreeNode<K, V>): void {
26
+ write(id: string, node: BPTreeNode<K, V>): void {
27
27
  const stringify = JSON.stringify(node)
28
- writeFileSync(id.toString(), stringify, 'utf8')
28
+ writeFileSync(id, stringify, 'utf8')
29
+ }
30
+
31
+ delete(id: string): void {
32
+ unlinkSync(id)
29
33
  }
30
34
 
31
35
  readHead(): SerializeStrategyHead|null {
@@ -98,7 +102,7 @@ import {
98
102
  ValueComparator,
99
103
  NumericComparator,
100
104
  StringComparator
101
- } from 'https://cdn.jsdelivr.net/npm/serializable-bptree@3.x.x/dist/esm/index.min.js'
105
+ } from 'https://cdn.jsdelivr.net/npm/serializable-bptree@4.x.x/dist/esm/index.min.js'
102
106
  </script>
103
107
  ```
104
108
 
@@ -177,9 +181,10 @@ You need to construct a logic for input/output from the file by inheriting the S
177
181
  import { SerializeStrategySync } from 'serializable-bptree'
178
182
 
179
183
  class MyFileIOStrategySync extends SerializeStrategySync {
180
- id(): number
181
- read(id: number): BPTreeNode<K, V>
182
- write(id: number, node: BPTreeNode<K, V>): void
184
+ id(): string
185
+ read(id: string): BPTreeNode<K, V>
186
+ write(id: string, node: BPTreeNode<K, V>): void
187
+ delete(id: string): void
183
188
  readHead(): SerializeStrategyHead|null
184
189
  writeHead(head: SerializeStrategyHead): void
185
190
  }
@@ -187,49 +192,39 @@ class MyFileIOStrategySync extends SerializeStrategySync {
187
192
 
188
193
  What does this method mean? And why do we need to construct such a method?
189
194
 
190
- #### id(isLeaf: `boolean`): `number`
191
-
192
- When a node is created in the B+tree, the node needs a unique value to represent itself. This is the **node.id** attribute, and you can specify this attribute yourself. For example, it could be implemented like this.
193
-
194
- ```typescript
195
- id(isLeaf: boolean): number {
196
- const current = before + 1
197
- before = current
198
- return current
199
- }
200
- ```
195
+ #### id(isLeaf: `boolean`): `string`
201
196
 
202
- Or, you could use file input/output to save and load the value of the **before** variable.
197
+ When a node is created in the B+tree, the node needs a unique value to represent itself. This is the **node.id** attribute, and you can specify this attribute yourself.
203
198
 
204
199
  Typically, such an **id** value increases sequentially, and it would be beneficial to store such a value separately within the tree. For that purpose, the **setHeadData** and **getHeadData** methods are available. These methods are responsible for storing arbitrary data in the tree's header or retrieving stored data. Below is an example of usage:
205
200
 
206
201
  ```typescript
207
- id(isLeaf: boolean): number {
202
+ id(isLeaf: boolean): string {
208
203
  const current = this.getHeadData('index', 1) as number
209
204
  this.setHeadData('index', current+1)
210
- return current
205
+ return current.toString()
211
206
  }
212
207
  ```
213
208
 
214
- Additionally, there is a more user-friendly usage of this code.
209
+ Additionally, there is a more dev-friendly usage of this code.
215
210
 
216
211
  ```typescript
217
- id(isLeaf: boolean): number {
218
- return this.autoIncrement('index', 1)
212
+ id(isLeaf: boolean): string {
213
+ return this.autoIncrement('index', 1).toString()
219
214
  }
220
215
  ```
221
216
 
222
217
  The **id** method is called before a node is created in the tree. Therefore, it can also be used to allocate space for storing the node.
223
218
 
224
- #### read(id: `number`): `BPTreeNode<K, V>`
219
+ #### read(id: `string`): `BPTreeNode<K, V>`
225
220
 
226
221
  This is a method to load the saved value as a tree instance. If you have previously saved the node as a file, you should use this method to convert it back to JavaScript JSON format and return it.
227
222
 
228
223
  Please refer to the example below:
229
224
 
230
225
  ```typescript
231
- read(id: number): BPTreeNode<K, V> {
232
- const filePath = `./my-store/${id.toString()}`
226
+ read(id: string): BPTreeNode<K, V> {
227
+ const filePath = `./my-store/${id}`
233
228
  const raw = fs.readFileSync(filePath, 'utf8')
234
229
  return JSON.parse(raw)
235
230
  }
@@ -237,7 +232,7 @@ read(id: number): BPTreeNode<K, V> {
237
232
 
238
233
  This method is called only once when loading a node from a tree instance. The loaded node is loaded into memory, and subsequently, when the tree references the node, it operates based on the values in memory **without** re-invoking this method.
239
234
 
240
- #### write(id: `number`, node: `BPTreeNode<K, V>`): `void`
235
+ #### write(id: `string`, node: `BPTreeNode<K, V>`): `void`
241
236
 
242
237
  This method is called when there are changes in the internal nodes due to the insert or delete operations of the tree instance. In other words, it's a necessary method for synchronizing the in-memory nodes into a file.
243
238
 
@@ -247,17 +242,17 @@ Please refer to the example below:
247
242
 
248
243
  ```typescript
249
244
  let queue = 0
250
- function writeBack(id: number, node: BPTreeNode<K, V>, timer: number) {
245
+ function writeBack(id: string, node: BPTreeNode<K, V>, timer: number) {
251
246
  clearTimeout(queue)
252
247
  queue = setTimeout(() => {
253
- const filePath = `./my-store/${id.toString()}`
248
+ const filePath = `./my-store/${id}`
254
249
  const stringify = JSON.stringify(node)
255
250
  writeFileSync(filePath, stringify, 'utf8')
256
251
  }, timer)
257
252
  }
258
253
 
259
254
  ...
260
- write(id: number, node: BPTreeNode<K, V>): void {
255
+ write(id: string, node: BPTreeNode<K, V>): void {
261
256
  const writeBackInterval = 10
262
257
  writeBack(id, node, writeBackInterval)
263
258
  }
@@ -265,6 +260,17 @@ write(id: number, node: BPTreeNode<K, V>): void {
265
260
 
266
261
  This kind of delay writing should ideally occur within a few milliseconds. If this is not feasible, consider other approaches.
267
262
 
263
+ #### delete(id: `string`): `void`
264
+
265
+ This method is called when previously created nodes become no longer needed due to deletion or other processes. It can be used to free up space by deleting existing stored nodes.
266
+
267
+ ```typescript
268
+ delete(id: string): void {
269
+ const filePath = `./my-store/${id}`
270
+ fs.unlinkSync(filePath)
271
+ }
272
+ ```
273
+
268
274
  #### readHead(): `SerializeStrategyHead`|`null`
269
275
 
270
276
  This method is called only once when the tree is created. It's a method to restore the saved tree information. If it is the initial creation and there is no stored root node, it should return **null**.
@@ -357,7 +363,7 @@ Support for asynchronous trees has been available since version 3.0.0. Asynchron
357
363
 
358
364
  ```typescript
359
365
  import { existsSync } from 'fs'
360
- import { readFile, writeFile } from 'fs/promises'
366
+ import { readFile, writeFile, unlink } from 'fs/promises'
361
367
  import {
362
368
  BPTreeAsync,
363
369
  SerializeStrategyAsync,
@@ -366,18 +372,22 @@ import {
366
372
  } from 'serializable-bptree'
367
373
 
368
374
  class FileStoreStrategyAsync extends SerializeStrategyAsync<K, V> {
369
- async id(isLeaf: boolean): Promise<number> {
370
- return await this.autoIncrement('index', 1)
375
+ async id(isLeaf: boolean): Promise<string> {
376
+ return await this.autoIncrement('index', 1).toString()
371
377
  }
372
378
 
373
- async read(id: number): Promise<BPTreeNode<K, V>> {
374
- const raw = await readFile(id.toString(), 'utf8')
379
+ async read(id: string): Promise<BPTreeNode<K, V>> {
380
+ const raw = await readFile(id, 'utf8')
375
381
  return JSON.parse(raw)
376
382
  }
377
383
 
378
- async write(id: number, node: BPTreeNode<K, V>): Promise<void> {
384
+ async write(id: string, node: BPTreeNode<K, V>): Promise<void> {
379
385
  const stringify = JSON.stringify(node)
380
- await writeFile(id.toString(), stringify, 'utf8')
386
+ await writeFile(id, stringify, 'utf8')
387
+ }
388
+
389
+ async delete(id: string): Promise<void> {
390
+ await unlink(id)
381
391
  }
382
392
 
383
393
  async readHead(): Promise<SerializeStrategyHead|null> {
@@ -609,12 +609,12 @@ var BPTreeSync = class extends BPTree {
609
609
  }
610
610
  _createNodeId(isLeaf) {
611
611
  const id = this.strategy.id(isLeaf);
612
- if (id === 0) {
613
- throw new Error(`The node's id should never be 0.`);
612
+ if (id === null) {
613
+ throw new Error(`The node's id should never be null.`);
614
614
  }
615
615
  return id;
616
616
  }
617
- _createNode(isLeaf, keys2, values, leaf = false, parent = 0, next = 0, prev = 0) {
617
+ _createNode(isLeaf, keys2, values, leaf = false, parent = null, next = null, prev = null) {
618
618
  const id = this._createNodeId(isLeaf);
619
619
  const node = {
620
620
  id,
@@ -651,7 +651,7 @@ var BPTreeSync = class extends BPTree {
651
651
  const keys2 = node.keys;
652
652
  this.bufferForNodeDelete(this.root);
653
653
  this.root = this.getNode(keys2[0]);
654
- this.root.parent = 0;
654
+ this.root.parent = null;
655
655
  this.strategy.head.root = this.root.id;
656
656
  this.bufferForNodeUpdate(this.root);
657
657
  return;
@@ -719,7 +719,7 @@ var BPTreeSync = class extends BPTree {
719
719
  this.bufferForNodeUpdate(n);
720
720
  }
721
721
  if (isPredecessor) {
722
- pointer.prev = 0;
722
+ pointer.prev = null;
723
723
  }
724
724
  }
725
725
  pointer.values.push(...node.values);
@@ -1160,12 +1160,12 @@ var BPTreeAsync = class extends BPTree {
1160
1160
  }
1161
1161
  async _createNodeId(isLeaf) {
1162
1162
  const id = await this.strategy.id(isLeaf);
1163
- if (id === 0) {
1164
- throw new Error(`The node's id should never be 0.`);
1163
+ if (id === null) {
1164
+ throw new Error(`The node's id should never be null.`);
1165
1165
  }
1166
1166
  return id;
1167
1167
  }
1168
- async _createNode(isLeaf, keys2, values, leaf = false, parent = 0, next = 0, prev = 0) {
1168
+ async _createNode(isLeaf, keys2, values, leaf = false, parent = null, next = null, prev = null) {
1169
1169
  const id = await this._createNodeId(isLeaf);
1170
1170
  const node = {
1171
1171
  id,
@@ -1202,7 +1202,7 @@ var BPTreeAsync = class extends BPTree {
1202
1202
  const keys2 = node.keys;
1203
1203
  this.bufferForNodeDelete(this.root);
1204
1204
  this.root = await this.getNode(keys2[0]);
1205
- this.root.parent = 0;
1205
+ this.root.parent = null;
1206
1206
  this.strategy.head.root = this.root.id;
1207
1207
  this.bufferForNodeUpdate(this.root);
1208
1208
  return;
@@ -1270,7 +1270,7 @@ var BPTreeAsync = class extends BPTree {
1270
1270
  this.bufferForNodeUpdate(n);
1271
1271
  }
1272
1272
  if (isPredecessor) {
1273
- pointer.prev = 0;
1273
+ pointer.prev = null;
1274
1274
  }
1275
1275
  }
1276
1276
  pointer.values.push(...node.values);
@@ -1646,7 +1646,7 @@ var SerializeStrategy = class {
1646
1646
  this.order = order;
1647
1647
  this.head = {
1648
1648
  order,
1649
- root: 0,
1649
+ root: null,
1650
1650
  data: {}
1651
1651
  };
1652
1652
  }
@@ -1656,7 +1656,7 @@ var SerializeStrategy = class {
1656
1656
  var SerializeStrategySync = class extends SerializeStrategy {
1657
1657
  getHeadData(key, defaultValue) {
1658
1658
  if (!Object.hasOwn(this.head.data, key)) {
1659
- return defaultValue;
1659
+ this.setHeadData(key, defaultValue);
1660
1660
  }
1661
1661
  return this.head.data[key];
1662
1662
  }
@@ -1678,7 +1678,7 @@ var InMemoryStoreStrategySync = class extends SerializeStrategySync {
1678
1678
  this.node = {};
1679
1679
  }
1680
1680
  id(isLeaf) {
1681
- return this.autoIncrement("index", 1);
1681
+ return this.autoIncrement("index", 1).toString();
1682
1682
  }
1683
1683
  read(id) {
1684
1684
  if (!Object.hasOwn(this.node, id)) {
@@ -1693,7 +1693,7 @@ var InMemoryStoreStrategySync = class extends SerializeStrategySync {
1693
1693
  delete this.node[id];
1694
1694
  }
1695
1695
  readHead() {
1696
- if (this.head.root === 0) {
1696
+ if (this.head.root === null) {
1697
1697
  return null;
1698
1698
  }
1699
1699
  return this.head;
@@ -1707,7 +1707,7 @@ var InMemoryStoreStrategySync = class extends SerializeStrategySync {
1707
1707
  var SerializeStrategyAsync = class extends SerializeStrategy {
1708
1708
  async getHeadData(key, defaultValue) {
1709
1709
  if (!Object.hasOwn(this.head.data, key)) {
1710
- return defaultValue;
1710
+ await this.setHeadData(key, defaultValue);
1711
1711
  }
1712
1712
  return this.head.data[key];
1713
1713
  }
@@ -1729,7 +1729,7 @@ var InMemoryStoreStrategyAsync = class extends SerializeStrategyAsync {
1729
1729
  this.node = {};
1730
1730
  }
1731
1731
  async id(isLeaf) {
1732
- return await this.autoIncrement("index", 1);
1732
+ return (await this.autoIncrement("index", 1)).toString();
1733
1733
  }
1734
1734
  async read(id) {
1735
1735
  if (!Object.hasOwn(this.node, id)) {
@@ -1744,7 +1744,7 @@ var InMemoryStoreStrategyAsync = class extends SerializeStrategyAsync {
1744
1744
  delete this.node[id];
1745
1745
  }
1746
1746
  async readHead() {
1747
- if (this.head.root === 0) {
1747
+ if (this.head.root === null) {
1748
1748
  return null;
1749
1749
  }
1750
1750
  return this.head;
@@ -575,12 +575,12 @@ var BPTreeSync = class extends BPTree {
575
575
  }
576
576
  _createNodeId(isLeaf) {
577
577
  const id = this.strategy.id(isLeaf);
578
- if (id === 0) {
579
- throw new Error(`The node's id should never be 0.`);
578
+ if (id === null) {
579
+ throw new Error(`The node's id should never be null.`);
580
580
  }
581
581
  return id;
582
582
  }
583
- _createNode(isLeaf, keys2, values, leaf = false, parent = 0, next = 0, prev = 0) {
583
+ _createNode(isLeaf, keys2, values, leaf = false, parent = null, next = null, prev = null) {
584
584
  const id = this._createNodeId(isLeaf);
585
585
  const node = {
586
586
  id,
@@ -617,7 +617,7 @@ var BPTreeSync = class extends BPTree {
617
617
  const keys2 = node.keys;
618
618
  this.bufferForNodeDelete(this.root);
619
619
  this.root = this.getNode(keys2[0]);
620
- this.root.parent = 0;
620
+ this.root.parent = null;
621
621
  this.strategy.head.root = this.root.id;
622
622
  this.bufferForNodeUpdate(this.root);
623
623
  return;
@@ -685,7 +685,7 @@ var BPTreeSync = class extends BPTree {
685
685
  this.bufferForNodeUpdate(n);
686
686
  }
687
687
  if (isPredecessor) {
688
- pointer.prev = 0;
688
+ pointer.prev = null;
689
689
  }
690
690
  }
691
691
  pointer.values.push(...node.values);
@@ -1126,12 +1126,12 @@ var BPTreeAsync = class extends BPTree {
1126
1126
  }
1127
1127
  async _createNodeId(isLeaf) {
1128
1128
  const id = await this.strategy.id(isLeaf);
1129
- if (id === 0) {
1130
- throw new Error(`The node's id should never be 0.`);
1129
+ if (id === null) {
1130
+ throw new Error(`The node's id should never be null.`);
1131
1131
  }
1132
1132
  return id;
1133
1133
  }
1134
- async _createNode(isLeaf, keys2, values, leaf = false, parent = 0, next = 0, prev = 0) {
1134
+ async _createNode(isLeaf, keys2, values, leaf = false, parent = null, next = null, prev = null) {
1135
1135
  const id = await this._createNodeId(isLeaf);
1136
1136
  const node = {
1137
1137
  id,
@@ -1168,7 +1168,7 @@ var BPTreeAsync = class extends BPTree {
1168
1168
  const keys2 = node.keys;
1169
1169
  this.bufferForNodeDelete(this.root);
1170
1170
  this.root = await this.getNode(keys2[0]);
1171
- this.root.parent = 0;
1171
+ this.root.parent = null;
1172
1172
  this.strategy.head.root = this.root.id;
1173
1173
  this.bufferForNodeUpdate(this.root);
1174
1174
  return;
@@ -1236,7 +1236,7 @@ var BPTreeAsync = class extends BPTree {
1236
1236
  this.bufferForNodeUpdate(n);
1237
1237
  }
1238
1238
  if (isPredecessor) {
1239
- pointer.prev = 0;
1239
+ pointer.prev = null;
1240
1240
  }
1241
1241
  }
1242
1242
  pointer.values.push(...node.values);
@@ -1612,7 +1612,7 @@ var SerializeStrategy = class {
1612
1612
  this.order = order;
1613
1613
  this.head = {
1614
1614
  order,
1615
- root: 0,
1615
+ root: null,
1616
1616
  data: {}
1617
1617
  };
1618
1618
  }
@@ -1622,7 +1622,7 @@ var SerializeStrategy = class {
1622
1622
  var SerializeStrategySync = class extends SerializeStrategy {
1623
1623
  getHeadData(key, defaultValue) {
1624
1624
  if (!Object.hasOwn(this.head.data, key)) {
1625
- return defaultValue;
1625
+ this.setHeadData(key, defaultValue);
1626
1626
  }
1627
1627
  return this.head.data[key];
1628
1628
  }
@@ -1644,7 +1644,7 @@ var InMemoryStoreStrategySync = class extends SerializeStrategySync {
1644
1644
  this.node = {};
1645
1645
  }
1646
1646
  id(isLeaf) {
1647
- return this.autoIncrement("index", 1);
1647
+ return this.autoIncrement("index", 1).toString();
1648
1648
  }
1649
1649
  read(id) {
1650
1650
  if (!Object.hasOwn(this.node, id)) {
@@ -1659,7 +1659,7 @@ var InMemoryStoreStrategySync = class extends SerializeStrategySync {
1659
1659
  delete this.node[id];
1660
1660
  }
1661
1661
  readHead() {
1662
- if (this.head.root === 0) {
1662
+ if (this.head.root === null) {
1663
1663
  return null;
1664
1664
  }
1665
1665
  return this.head;
@@ -1673,7 +1673,7 @@ var InMemoryStoreStrategySync = class extends SerializeStrategySync {
1673
1673
  var SerializeStrategyAsync = class extends SerializeStrategy {
1674
1674
  async getHeadData(key, defaultValue) {
1675
1675
  if (!Object.hasOwn(this.head.data, key)) {
1676
- return defaultValue;
1676
+ await this.setHeadData(key, defaultValue);
1677
1677
  }
1678
1678
  return this.head.data[key];
1679
1679
  }
@@ -1695,7 +1695,7 @@ var InMemoryStoreStrategyAsync = class extends SerializeStrategyAsync {
1695
1695
  this.node = {};
1696
1696
  }
1697
1697
  async id(isLeaf) {
1698
- return await this.autoIncrement("index", 1);
1698
+ return (await this.autoIncrement("index", 1)).toString();
1699
1699
  }
1700
1700
  async read(id) {
1701
1701
  if (!Object.hasOwn(this.node, id)) {
@@ -1710,7 +1710,7 @@ var InMemoryStoreStrategyAsync = class extends SerializeStrategyAsync {
1710
1710
  delete this.node[id];
1711
1711
  }
1712
1712
  async readHead() {
1713
- if (this.head.root === 0) {
1713
+ if (this.head.root === null) {
1714
1714
  return null;
1715
1715
  }
1716
1716
  return this.head;
@@ -8,12 +8,12 @@ export declare class BPTreeAsync<K, V> extends BPTree<K, V> {
8
8
  protected _getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): Promise<BPTreePair<K, V>[]>;
9
9
  protected _getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): Promise<BPTreePair<K, V>[]>;
10
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
- protected _createNodeId(isLeaf: boolean): Promise<number>;
12
- protected _createNode(isLeaf: boolean, keys: number[] | K[][], values: V[], leaf?: boolean, parent?: number, next?: number, prev?: number): Promise<BPTreeUnknownNode<K, V>>;
11
+ protected _createNodeId(isLeaf: boolean): Promise<string>;
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>;
14
14
  protected _insertInParent(node: BPTreeUnknownNode<K, V>, value: V, pointer: BPTreeUnknownNode<K, V>): Promise<void>;
15
15
  init(): Promise<void>;
16
- protected getNode(id: number): Promise<BPTreeUnknownNode<K, V>>;
16
+ protected getNode(id: string): Promise<BPTreeUnknownNode<K, V>>;
17
17
  protected insertableNode(value: V): Promise<BPTreeLeafNode<K, V>>;
18
18
  protected leftestNode(): Promise<BPTreeLeafNode<K, V>>;
19
19
  protected commitHeadBuffer(): Promise<void>;
@@ -8,12 +8,12 @@ export declare class BPTreeSync<K, V> extends BPTree<K, V> {
8
8
  protected _getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): BPTreePair<K, V>[];
9
9
  protected _getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): BPTreePair<K, V>[];
10
10
  protected getPairs(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean, direction: 1 | -1): BPTreePair<K, V>[];
11
- protected _createNodeId(isLeaf: boolean): number;
12
- protected _createNode(isLeaf: boolean, keys: number[] | K[][], values: V[], leaf?: boolean, parent?: number, next?: number, prev?: number): BPTreeUnknownNode<K, V>;
11
+ protected _createNodeId(isLeaf: boolean): string;
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;
14
14
  protected _insertInParent(node: BPTreeUnknownNode<K, V>, value: V, pointer: BPTreeUnknownNode<K, V>): void;
15
15
  init(): void;
16
- protected getNode(id: number): BPTreeUnknownNode<K, V>;
16
+ protected getNode(id: string): BPTreeUnknownNode<K, V>;
17
17
  protected insertableNode(value: V): BPTreeLeafNode<K, V>;
18
18
  protected leftestNode(): BPTreeLeafNode<K, V>;
19
19
  protected commitHeadBuffer(): void;
@@ -2,10 +2,10 @@ import { BPTreeNode } from './base/BPTree';
2
2
  import { SerializeStrategy, SerializeStrategyHead } from './base/SerializeStrategy';
3
3
  import { Json } from './utils/types';
4
4
  export declare abstract class SerializeStrategyAsync<K, V> extends SerializeStrategy<K, V> {
5
- abstract id(isLeaf: boolean): Promise<number>;
6
- abstract read(id: number): Promise<BPTreeNode<K, V>>;
7
- abstract write(id: number, node: BPTreeNode<K, V>): Promise<void>;
8
- abstract delete(id: number): Promise<void>;
5
+ abstract id(isLeaf: boolean): Promise<string>;
6
+ abstract read(id: string): Promise<BPTreeNode<K, V>>;
7
+ abstract write(id: string, node: BPTreeNode<K, V>): Promise<void>;
8
+ abstract delete(id: string): Promise<void>;
9
9
  abstract readHead(): Promise<SerializeStrategyHead | null>;
10
10
  abstract writeHead(head: SerializeStrategyHead): Promise<void>;
11
11
  getHeadData(key: string, defaultValue: Json): Promise<Json>;
@@ -13,12 +13,12 @@ export declare abstract class SerializeStrategyAsync<K, V> extends SerializeStra
13
13
  autoIncrement(key: string, defaultValue: number): Promise<number>;
14
14
  }
15
15
  export declare class InMemoryStoreStrategyAsync<K, V> extends SerializeStrategyAsync<K, V> {
16
- protected readonly node: Record<number, BPTreeNode<K, V>>;
16
+ protected readonly node: Record<string, BPTreeNode<K, V>>;
17
17
  constructor(order: number);
18
- id(isLeaf: boolean): Promise<number>;
19
- read(id: number): Promise<BPTreeNode<K, V>>;
20
- write(id: number, node: BPTreeNode<K, V>): Promise<void>;
21
- delete(id: number): Promise<void>;
18
+ id(isLeaf: boolean): Promise<string>;
19
+ read(id: string): Promise<BPTreeNode<K, V>>;
20
+ write(id: string, node: BPTreeNode<K, V>): Promise<void>;
21
+ delete(id: string): Promise<void>;
22
22
  readHead(): Promise<SerializeStrategyHead | null>;
23
23
  writeHead(head: SerializeStrategyHead): Promise<void>;
24
24
  }
@@ -2,10 +2,10 @@ import { BPTreeNode } from './base/BPTree';
2
2
  import { SerializeStrategy, SerializeStrategyHead } from './base/SerializeStrategy';
3
3
  import { Json } from './utils/types';
4
4
  export declare abstract class SerializeStrategySync<K, V> extends SerializeStrategy<K, V> {
5
- abstract id(isLeaf: boolean): number;
6
- abstract read(id: number): BPTreeNode<K, V>;
7
- abstract write(id: number, node: BPTreeNode<K, V>): void;
8
- abstract delete(id: number): void;
5
+ abstract id(isLeaf: boolean): string;
6
+ abstract read(id: string): BPTreeNode<K, V>;
7
+ abstract write(id: string, node: BPTreeNode<K, V>): void;
8
+ abstract delete(id: string): void;
9
9
  abstract readHead(): SerializeStrategyHead | null;
10
10
  abstract writeHead(head: SerializeStrategyHead): void;
11
11
  getHeadData(key: string, defaultValue: Json): Json;
@@ -13,12 +13,12 @@ export declare abstract class SerializeStrategySync<K, V> extends SerializeStrat
13
13
  autoIncrement(key: string, defaultValue: number): number;
14
14
  }
15
15
  export declare class InMemoryStoreStrategySync<K, V> extends SerializeStrategySync<K, V> {
16
- protected readonly node: Record<number, BPTreeNode<K, V>>;
16
+ protected readonly node: Record<string, BPTreeNode<K, V>>;
17
17
  constructor(order: number);
18
- id(isLeaf: boolean): number;
19
- read(id: number): BPTreeNode<K, V>;
20
- write(id: number, node: BPTreeNode<K, V>): void;
21
- delete(id: number): void;
18
+ id(isLeaf: boolean): string;
19
+ read(id: string): BPTreeNode<K, V>;
20
+ write(id: string, node: BPTreeNode<K, V>): void;
21
+ delete(id: string): void;
22
22
  readHead(): SerializeStrategyHead | null;
23
23
  writeHead(head: SerializeStrategyHead): void;
24
24
  }
@@ -3,7 +3,7 @@ import { SerializableData, SerializeStrategy } from './SerializeStrategy';
3
3
  type Sync<T> = T;
4
4
  type Async<T> = Promise<T>;
5
5
  type Deferred<T> = Sync<T> | Async<T>;
6
- export type BPTreeNodeKey<K> = number | K;
6
+ export type BPTreeNodeKey<K> = string | K;
7
7
  export type BPTreeCondition<V> = Partial<{
8
8
  /** Searches for pairs greater than the given value. */
9
9
  gt: Partial<V>;
@@ -26,17 +26,17 @@ export type BPTreePair<K, V> = {
26
26
  };
27
27
  export type BPTreeUnknownNode<K, V> = BPTreeInternalNode<K, V> | BPTreeLeafNode<K, V>;
28
28
  export interface BPTreeNode<K, V> {
29
- id: number;
30
- keys: number[] | K[][];
29
+ id: string;
30
+ keys: string[] | K[][];
31
31
  values: V[];
32
32
  leaf: boolean;
33
- parent: number;
34
- next: number;
35
- prev: number;
33
+ parent: string | null;
34
+ next: string | null;
35
+ prev: string | null;
36
36
  }
37
37
  export interface BPTreeInternalNode<K, V> extends BPTreeNode<K, V> {
38
38
  leaf: false;
39
- keys: number[];
39
+ keys: string[];
40
40
  }
41
41
  export interface BPTreeLeafNode<K, V> extends BPTreeNode<K, V> {
42
42
  leaf: true;
@@ -46,12 +46,12 @@ export declare abstract class BPTree<K, V> {
46
46
  private readonly _cachedRegexp;
47
47
  protected readonly strategy: SerializeStrategy<K, V>;
48
48
  protected readonly comparator: ValueComparator<V>;
49
- protected readonly nodes: Map<number, BPTreeUnknownNode<K, V>>;
49
+ protected readonly nodes: Map<string, BPTreeUnknownNode<K, V>>;
50
50
  protected order: number;
51
51
  protected root: BPTreeUnknownNode<K, V>;
52
- protected readonly _nodeCreateBuffer: Map<number, BPTreeUnknownNode<K, V>>;
53
- protected readonly _nodeUpdateBuffer: Map<number, BPTreeUnknownNode<K, V>>;
54
- protected readonly _nodeDeleteBuffer: Map<number, BPTreeUnknownNode<K, V>>;
52
+ protected readonly _nodeCreateBuffer: Map<string, BPTreeUnknownNode<K, V>>;
53
+ protected readonly _nodeUpdateBuffer: Map<string, BPTreeUnknownNode<K, V>>;
54
+ protected readonly _nodeDeleteBuffer: Map<string, BPTreeUnknownNode<K, V>>;
55
55
  protected readonly verifierMap: Record<keyof BPTreeCondition<V>, (nodeValue: V, value: V) => boolean>;
56
56
  protected readonly verifierStartNode: Record<keyof BPTreeCondition<V>, (value: V) => Deferred<BPTreeLeafNode<K, V>>>;
57
57
  protected readonly verifierDirection: Record<keyof BPTreeCondition<V>, -1 | 1>;
@@ -60,11 +60,11 @@ export declare abstract class BPTree<K, V> {
60
60
  protected abstract _getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): Deferred<BPTreePair<K, V>[]>;
61
61
  protected abstract _getPairsLeftToRight(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean): Deferred<BPTreePair<K, V>[]>;
62
62
  protected abstract getPairs(value: V, startNode: BPTreeLeafNode<K, V>, fullScan: boolean, comparator: (nodeValue: V, value: V) => boolean, direction: -1 | 1): Deferred<BPTreePair<K, V>[]>;
63
- protected abstract _createNodeId(isLeaf: boolean): Deferred<number>;
64
- protected abstract _createNode(isLeaf: boolean, keys: number[] | K[][], values: V[], leaf?: boolean, parent?: number, next?: number, prev?: number): Deferred<BPTreeUnknownNode<K, V>>;
63
+ protected abstract _createNodeId(isLeaf: boolean): Deferred<string>;
64
+ 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>>;
65
65
  protected abstract _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>, value: V): Deferred<void>;
66
66
  protected abstract _insertInParent(node: BPTreeUnknownNode<K, V>, value: V, pointer: BPTreeUnknownNode<K, V>): Deferred<void>;
67
- protected abstract getNode(id: number): Deferred<BPTreeUnknownNode<K, V>>;
67
+ protected abstract getNode(id: string): Deferred<BPTreeUnknownNode<K, V>>;
68
68
  protected abstract insertableNode(value: V): Deferred<BPTreeLeafNode<K, V>>;
69
69
  protected abstract leftestNode(): Deferred<BPTreeLeafNode<K, V>>;
70
70
  protected abstract commitHeadBuffer(): Deferred<void>;
@@ -2,7 +2,7 @@ import { BPTreeNode } from './BPTree';
2
2
  import type { Json } from '../utils/types';
3
3
  export type SerializableData = Record<string, Json>;
4
4
  export interface SerializeStrategyHead {
5
- root: number;
5
+ root: string | null;
6
6
  order: number;
7
7
  data: SerializableData;
8
8
  }
@@ -14,29 +14,29 @@ export declare abstract class SerializeStrategy<K, V> {
14
14
  * The rule for generating node IDs is set.
15
15
  * When a new node is created within the tree, the value returned by this method becomes the node's ID.
16
16
  *
17
- * **WARNING!** The return value should never be `0`.
17
+ * **WARNING!** The return value should never be `null`.
18
18
  * @param isLeaf This is a flag that indicates whether the node is a leaf node or not.
19
19
  */
20
- abstract id(isLeaf: boolean): number | Promise<number>;
20
+ abstract id(isLeaf: boolean): string | Promise<string>;
21
21
  /**
22
22
  * Read the stored node from the ID.
23
23
  * The JSON object of the read node should be returned.
24
24
  * @param id This is the ID of the node to be read.
25
25
  */
26
- abstract read(id: number): BPTreeNode<K, V> | Promise<BPTreeNode<K, V>>;
26
+ abstract read(id: string): BPTreeNode<K, V> | Promise<BPTreeNode<K, V>>;
27
27
  /**
28
28
  * It is called when a node is created or updated and needs to be stored.
29
29
  * The node ID and the node JSON object are passed as parameters. Use this to store the data.
30
30
  * @param id This is the ID of the node to be stored.
31
31
  * @param node This is the JSON object of the node to be stored.
32
32
  */
33
- abstract write(id: number, node: BPTreeNode<K, V>): void | Promise<void>;
33
+ abstract write(id: string, node: BPTreeNode<K, V>): void | Promise<void>;
34
34
  /**
35
35
  * This method is called when previously created nodes become no longer needed due to deletion or other processes.
36
36
  * It can be used to free up space by deleting existing stored nodes.
37
37
  * @param id This is the ID of the node to be deleted.
38
38
  */
39
- abstract delete(id: number): void | Promise<void>;
39
+ abstract delete(id: string): void | Promise<void>;
40
40
  /**
41
41
  * It is called when the `init` method of the tree instance is called.
42
42
  * This method should return the information needed to initialize the tree. This information refers to the values stored in the `writeHead` method.
@@ -53,7 +53,7 @@ export declare abstract class SerializeStrategy<K, V> {
53
53
  abstract writeHead(head: SerializeStrategyHead): void | Promise<void>;
54
54
  /**
55
55
  * Retrieves the data stored in the tree.
56
- * If there are no values stored in the tree, it returns the `defaultValue`.
56
+ * If no value is stored in the tree, it stores a `defaultValue` and then returns that value.
57
57
  * @param key The key of the data stored in the tree.
58
58
  */
59
59
  abstract getHeadData(key: string, defaultValue: Json): Json | Promise<Json>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "serializable-bptree",
3
- "version": "3.4.0-alpha.0",
3
+ "version": "4.0.0",
4
4
  "description": "Store the B+tree flexibly, not only in-memory.",
5
5
  "main": "dist/cjs/index.cjs",
6
6
  "module": "dist/esm/index.mjs",