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 +52 -42
- package/dist/cjs/index.cjs +17 -17
- package/dist/esm/index.mjs +17 -17
- package/dist/typings/BPTreeAsync.d.ts +3 -3
- package/dist/typings/BPTreeSync.d.ts +3 -3
- package/dist/typings/SerializeStrategyAsync.d.ts +9 -9
- package/dist/typings/SerializeStrategySync.d.ts +9 -9
- package/dist/typings/base/BPTree.d.ts +14 -14
- package/dist/typings/base/SerializeStrategy.d.ts +7 -7
- package/package.json +1 -1
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():
|
|
18
|
-
return this.autoIncrement('index', 1)
|
|
17
|
+
id(): string {
|
|
18
|
+
return this.autoIncrement('index', 1).toString()
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
read(id:
|
|
22
|
-
const raw = readFileSync(id
|
|
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:
|
|
26
|
+
write(id: string, node: BPTreeNode<K, V>): void {
|
|
27
27
|
const stringify = JSON.stringify(node)
|
|
28
|
-
writeFileSync(id
|
|
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@
|
|
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():
|
|
181
|
-
read(id:
|
|
182
|
-
write(id:
|
|
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`): `
|
|
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
|
-
|
|
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):
|
|
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
|
|
209
|
+
Additionally, there is a more dev-friendly usage of this code.
|
|
215
210
|
|
|
216
211
|
```typescript
|
|
217
|
-
id(isLeaf: boolean):
|
|
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: `
|
|
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:
|
|
232
|
-
const filePath = `./my-store/${id
|
|
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: `
|
|
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:
|
|
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
|
|
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:
|
|
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<
|
|
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:
|
|
374
|
-
const raw = await readFile(id
|
|
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:
|
|
384
|
+
async write(id: string, node: BPTreeNode<K, V>): Promise<void> {
|
|
379
385
|
const stringify = JSON.stringify(node)
|
|
380
|
-
await writeFile(id
|
|
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> {
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -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 ===
|
|
613
|
-
throw new Error(`The node's id should never be
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 ===
|
|
1164
|
-
throw new Error(`The node's id should never be
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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:
|
|
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
|
-
|
|
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 ===
|
|
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
|
-
|
|
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 ===
|
|
1747
|
+
if (this.head.root === null) {
|
|
1748
1748
|
return null;
|
|
1749
1749
|
}
|
|
1750
1750
|
return this.head;
|
package/dist/esm/index.mjs
CHANGED
|
@@ -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 ===
|
|
579
|
-
throw new Error(`The node's id should never be
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 ===
|
|
1130
|
-
throw new Error(`The node's id should never be
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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:
|
|
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
|
-
|
|
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 ===
|
|
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
|
-
|
|
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 ===
|
|
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<
|
|
12
|
-
protected _createNode(isLeaf: boolean, keys:
|
|
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:
|
|
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):
|
|
12
|
-
protected _createNode(isLeaf: boolean, keys:
|
|
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:
|
|
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<
|
|
6
|
-
abstract read(id:
|
|
7
|
-
abstract write(id:
|
|
8
|
-
abstract delete(id:
|
|
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<
|
|
16
|
+
protected readonly node: Record<string, BPTreeNode<K, V>>;
|
|
17
17
|
constructor(order: number);
|
|
18
|
-
id(isLeaf: boolean): Promise<
|
|
19
|
-
read(id:
|
|
20
|
-
write(id:
|
|
21
|
-
delete(id:
|
|
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):
|
|
6
|
-
abstract read(id:
|
|
7
|
-
abstract write(id:
|
|
8
|
-
abstract delete(id:
|
|
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<
|
|
16
|
+
protected readonly node: Record<string, BPTreeNode<K, V>>;
|
|
17
17
|
constructor(order: number);
|
|
18
|
-
id(isLeaf: boolean):
|
|
19
|
-
read(id:
|
|
20
|
-
write(id:
|
|
21
|
-
delete(id:
|
|
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> =
|
|
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:
|
|
30
|
-
keys:
|
|
29
|
+
id: string;
|
|
30
|
+
keys: string[] | K[][];
|
|
31
31
|
values: V[];
|
|
32
32
|
leaf: boolean;
|
|
33
|
-
parent:
|
|
34
|
-
next:
|
|
35
|
-
prev:
|
|
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:
|
|
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<
|
|
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<
|
|
53
|
-
protected readonly _nodeUpdateBuffer: Map<
|
|
54
|
-
protected readonly _nodeDeleteBuffer: Map<
|
|
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<
|
|
64
|
-
protected abstract _createNode(isLeaf: boolean, keys:
|
|
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:
|
|
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:
|
|
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 `
|
|
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):
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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>;
|