serializable-bptree 8.1.6 → 8.1.7
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 +3 -1
- package/dist/cjs/index.cjs +47 -18
- package/dist/esm/index.mjs +47 -18
- package/dist/types/BPTreeAsync.d.ts +1 -1
- package/dist/types/BPTreeSync.d.ts +1 -1
- package/dist/types/base/BPTreeTransaction.d.ts +11 -1
- package/dist/types/transaction/BPTreeAsyncTransaction.d.ts +1 -1
- package/dist/types/transaction/BPTreeSyncTransaction.d.ts +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
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.
|
|
8
8
|
|
|
9
9
|
```typescript
|
|
10
|
-
import { readFileSync, writeFileSync, unlinkSync, existsSync } from 'fs'
|
|
10
|
+
import { readFileSync, writeFileSync, unlinkSync, existsSync } from 'node:fs'
|
|
11
11
|
import {
|
|
12
12
|
BPTreeSync,
|
|
13
13
|
SerializeStrategySync,
|
|
@@ -91,6 +91,8 @@ Additionally, this library supports asynchronous operations and rule-based query
|
|
|
91
91
|
|
|
92
92
|
```bash
|
|
93
93
|
npm i serializable-bptree
|
|
94
|
+
# or
|
|
95
|
+
npx jsr add @izure/serializable-bptree
|
|
94
96
|
```
|
|
95
97
|
|
|
96
98
|
```typescript
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -343,6 +343,30 @@ var MVCCTransaction = class {
|
|
|
343
343
|
deleted
|
|
344
344
|
};
|
|
345
345
|
}
|
|
346
|
+
/**
|
|
347
|
+
* Checks for conflicts among multiple transactions.
|
|
348
|
+
* A conflict occurs if two or more transactions modify (write or delete) the same key.
|
|
349
|
+
* @param transactions Array of transactions to check.
|
|
350
|
+
* @returns An array of keys that are in conflict.
|
|
351
|
+
*/
|
|
352
|
+
static CheckConflicts(transactions) {
|
|
353
|
+
const modifiedKeys = /* @__PURE__ */ new Map();
|
|
354
|
+
const conflicts = /* @__PURE__ */ new Set();
|
|
355
|
+
for (const tx of transactions) {
|
|
356
|
+
const txModified = /* @__PURE__ */ new Set([
|
|
357
|
+
...tx.writeBuffer.keys(),
|
|
358
|
+
...tx.deleteBuffer
|
|
359
|
+
]);
|
|
360
|
+
for (const key of txModified) {
|
|
361
|
+
const count = modifiedKeys.get(key) ?? 0;
|
|
362
|
+
if (count > 0) {
|
|
363
|
+
conflicts.add(key);
|
|
364
|
+
}
|
|
365
|
+
modifiedKeys.set(key, count + 1);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return Array.from(conflicts);
|
|
369
|
+
}
|
|
346
370
|
/**
|
|
347
371
|
* Cleans up both deletedCache and versionIndex based on minActiveVersion.
|
|
348
372
|
* Root transactions call this after commit to reclaim memory.
|
|
@@ -1632,6 +1656,15 @@ var BPTreeTransaction = class _BPTreeTransaction {
|
|
|
1632
1656
|
}
|
|
1633
1657
|
return best;
|
|
1634
1658
|
}
|
|
1659
|
+
/**
|
|
1660
|
+
* Checks for conflicts between multiple transactions.
|
|
1661
|
+
*
|
|
1662
|
+
* @param transactions Array of BPTreeTransaction instances to check
|
|
1663
|
+
* @returns An array of keys that are in conflict. Empty array if no conflicts.
|
|
1664
|
+
*/
|
|
1665
|
+
static CheckConflicts(transactions) {
|
|
1666
|
+
return MVCCTransaction.CheckConflicts(transactions.map((tx) => tx.mvcc));
|
|
1667
|
+
}
|
|
1635
1668
|
/**
|
|
1636
1669
|
* Returns the ID of the root node.
|
|
1637
1670
|
* @returns The root node ID.
|
|
@@ -2084,11 +2117,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2084
2117
|
const { root, order } = head;
|
|
2085
2118
|
this.strategy.head = head;
|
|
2086
2119
|
this.order = order;
|
|
2087
|
-
this.
|
|
2088
|
-
root,
|
|
2089
|
-
order: this.order,
|
|
2090
|
-
data: this.strategy.head.data
|
|
2091
|
-
});
|
|
2120
|
+
this.rootId = root;
|
|
2092
2121
|
}
|
|
2093
2122
|
if (this.order < 3) {
|
|
2094
2123
|
throw new Error(`The 'order' parameter must be greater than 2. but got a '${this.order}'.`);
|
|
@@ -2414,6 +2443,12 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2414
2443
|
return node;
|
|
2415
2444
|
}
|
|
2416
2445
|
delete(key, value) {
|
|
2446
|
+
if (value === void 0) {
|
|
2447
|
+
value = this.get(key);
|
|
2448
|
+
}
|
|
2449
|
+
if (value === void 0) {
|
|
2450
|
+
return;
|
|
2451
|
+
}
|
|
2417
2452
|
let node = this.insertableNodeByPrimary(value);
|
|
2418
2453
|
let found = false;
|
|
2419
2454
|
while (true) {
|
|
@@ -2865,14 +2900,6 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
2865
2900
|
next,
|
|
2866
2901
|
prev
|
|
2867
2902
|
};
|
|
2868
|
-
const head = await this._readHead();
|
|
2869
|
-
if (head) {
|
|
2870
|
-
await this._writeHead({
|
|
2871
|
-
root: head.root,
|
|
2872
|
-
order: head.order,
|
|
2873
|
-
data: this.strategy.head.data
|
|
2874
|
-
});
|
|
2875
|
-
}
|
|
2876
2903
|
await this.mvcc.create(id, node);
|
|
2877
2904
|
return node;
|
|
2878
2905
|
}
|
|
@@ -3165,11 +3192,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3165
3192
|
const { root, order } = head;
|
|
3166
3193
|
this.strategy.head = head;
|
|
3167
3194
|
this.order = order;
|
|
3168
|
-
|
|
3169
|
-
root,
|
|
3170
|
-
order: this.order,
|
|
3171
|
-
data: this.strategy.head.data
|
|
3172
|
-
});
|
|
3195
|
+
this.rootId = root;
|
|
3173
3196
|
}
|
|
3174
3197
|
if (this.order < 3) {
|
|
3175
3198
|
throw new Error(`The 'order' parameter must be greater than 2. but got a '${this.order}'.`);
|
|
@@ -3498,6 +3521,12 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3498
3521
|
}
|
|
3499
3522
|
async delete(key, value) {
|
|
3500
3523
|
return this.writeLock(0, async () => {
|
|
3524
|
+
if (value === void 0) {
|
|
3525
|
+
value = await this.get(key);
|
|
3526
|
+
}
|
|
3527
|
+
if (value === void 0) {
|
|
3528
|
+
return;
|
|
3529
|
+
}
|
|
3501
3530
|
let node = await this.insertableNodeByPrimary(value);
|
|
3502
3531
|
let found = false;
|
|
3503
3532
|
while (true) {
|
package/dist/esm/index.mjs
CHANGED
|
@@ -307,6 +307,30 @@ var MVCCTransaction = class {
|
|
|
307
307
|
deleted
|
|
308
308
|
};
|
|
309
309
|
}
|
|
310
|
+
/**
|
|
311
|
+
* Checks for conflicts among multiple transactions.
|
|
312
|
+
* A conflict occurs if two or more transactions modify (write or delete) the same key.
|
|
313
|
+
* @param transactions Array of transactions to check.
|
|
314
|
+
* @returns An array of keys that are in conflict.
|
|
315
|
+
*/
|
|
316
|
+
static CheckConflicts(transactions) {
|
|
317
|
+
const modifiedKeys = /* @__PURE__ */ new Map();
|
|
318
|
+
const conflicts = /* @__PURE__ */ new Set();
|
|
319
|
+
for (const tx of transactions) {
|
|
320
|
+
const txModified = /* @__PURE__ */ new Set([
|
|
321
|
+
...tx.writeBuffer.keys(),
|
|
322
|
+
...tx.deleteBuffer
|
|
323
|
+
]);
|
|
324
|
+
for (const key of txModified) {
|
|
325
|
+
const count = modifiedKeys.get(key) ?? 0;
|
|
326
|
+
if (count > 0) {
|
|
327
|
+
conflicts.add(key);
|
|
328
|
+
}
|
|
329
|
+
modifiedKeys.set(key, count + 1);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return Array.from(conflicts);
|
|
333
|
+
}
|
|
310
334
|
/**
|
|
311
335
|
* Cleans up both deletedCache and versionIndex based on minActiveVersion.
|
|
312
336
|
* Root transactions call this after commit to reclaim memory.
|
|
@@ -1596,6 +1620,15 @@ var BPTreeTransaction = class _BPTreeTransaction {
|
|
|
1596
1620
|
}
|
|
1597
1621
|
return best;
|
|
1598
1622
|
}
|
|
1623
|
+
/**
|
|
1624
|
+
* Checks for conflicts between multiple transactions.
|
|
1625
|
+
*
|
|
1626
|
+
* @param transactions Array of BPTreeTransaction instances to check
|
|
1627
|
+
* @returns An array of keys that are in conflict. Empty array if no conflicts.
|
|
1628
|
+
*/
|
|
1629
|
+
static CheckConflicts(transactions) {
|
|
1630
|
+
return MVCCTransaction.CheckConflicts(transactions.map((tx) => tx.mvcc));
|
|
1631
|
+
}
|
|
1599
1632
|
/**
|
|
1600
1633
|
* Returns the ID of the root node.
|
|
1601
1634
|
* @returns The root node ID.
|
|
@@ -2048,11 +2081,7 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2048
2081
|
const { root, order } = head;
|
|
2049
2082
|
this.strategy.head = head;
|
|
2050
2083
|
this.order = order;
|
|
2051
|
-
this.
|
|
2052
|
-
root,
|
|
2053
|
-
order: this.order,
|
|
2054
|
-
data: this.strategy.head.data
|
|
2055
|
-
});
|
|
2084
|
+
this.rootId = root;
|
|
2056
2085
|
}
|
|
2057
2086
|
if (this.order < 3) {
|
|
2058
2087
|
throw new Error(`The 'order' parameter must be greater than 2. but got a '${this.order}'.`);
|
|
@@ -2378,6 +2407,12 @@ var BPTreeSyncTransaction = class extends BPTreeTransaction {
|
|
|
2378
2407
|
return node;
|
|
2379
2408
|
}
|
|
2380
2409
|
delete(key, value) {
|
|
2410
|
+
if (value === void 0) {
|
|
2411
|
+
value = this.get(key);
|
|
2412
|
+
}
|
|
2413
|
+
if (value === void 0) {
|
|
2414
|
+
return;
|
|
2415
|
+
}
|
|
2381
2416
|
let node = this.insertableNodeByPrimary(value);
|
|
2382
2417
|
let found = false;
|
|
2383
2418
|
while (true) {
|
|
@@ -2829,14 +2864,6 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
2829
2864
|
next,
|
|
2830
2865
|
prev
|
|
2831
2866
|
};
|
|
2832
|
-
const head = await this._readHead();
|
|
2833
|
-
if (head) {
|
|
2834
|
-
await this._writeHead({
|
|
2835
|
-
root: head.root,
|
|
2836
|
-
order: head.order,
|
|
2837
|
-
data: this.strategy.head.data
|
|
2838
|
-
});
|
|
2839
|
-
}
|
|
2840
2867
|
await this.mvcc.create(id, node);
|
|
2841
2868
|
return node;
|
|
2842
2869
|
}
|
|
@@ -3129,11 +3156,7 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3129
3156
|
const { root, order } = head;
|
|
3130
3157
|
this.strategy.head = head;
|
|
3131
3158
|
this.order = order;
|
|
3132
|
-
|
|
3133
|
-
root,
|
|
3134
|
-
order: this.order,
|
|
3135
|
-
data: this.strategy.head.data
|
|
3136
|
-
});
|
|
3159
|
+
this.rootId = root;
|
|
3137
3160
|
}
|
|
3138
3161
|
if (this.order < 3) {
|
|
3139
3162
|
throw new Error(`The 'order' parameter must be greater than 2. but got a '${this.order}'.`);
|
|
@@ -3462,6 +3485,12 @@ var BPTreeAsyncTransaction = class extends BPTreeTransaction {
|
|
|
3462
3485
|
}
|
|
3463
3486
|
async delete(key, value) {
|
|
3464
3487
|
return this.writeLock(0, async () => {
|
|
3488
|
+
if (value === void 0) {
|
|
3489
|
+
value = await this.get(key);
|
|
3490
|
+
}
|
|
3491
|
+
if (value === void 0) {
|
|
3492
|
+
return;
|
|
3493
|
+
}
|
|
3465
3494
|
let node = await this.insertableNodeByPrimary(value);
|
|
3466
3495
|
let found = false;
|
|
3467
3496
|
while (true) {
|
|
@@ -10,5 +10,5 @@ export declare class BPTreeAsync<K, V> extends BPTreeAsyncTransaction<K, V> {
|
|
|
10
10
|
*/
|
|
11
11
|
createTransaction(): Promise<BPTreeAsyncTransaction<K, V>>;
|
|
12
12
|
insert(key: K, value: V): Promise<void>;
|
|
13
|
-
delete(key: K, value
|
|
13
|
+
delete(key: K, value?: V): Promise<void>;
|
|
14
14
|
}
|
|
@@ -55,6 +55,13 @@ export declare abstract class BPTreeTransaction<K, V> {
|
|
|
55
55
|
tree: T;
|
|
56
56
|
condition: BPTreeCondition<unknown>;
|
|
57
57
|
} | null;
|
|
58
|
+
/**
|
|
59
|
+
* Checks for conflicts between multiple transactions.
|
|
60
|
+
*
|
|
61
|
+
* @param transactions Array of BPTreeTransaction instances to check
|
|
62
|
+
* @returns An array of keys that are in conflict. Empty array if no conflicts.
|
|
63
|
+
*/
|
|
64
|
+
static CheckConflicts<K, V>(transactions: BPTreeTransaction<K, V>[]): string[];
|
|
58
65
|
/**
|
|
59
66
|
* Returns the ID of the root node.
|
|
60
67
|
* @returns The root node ID.
|
|
@@ -131,10 +138,13 @@ export declare abstract class BPTreeTransaction<K, V> {
|
|
|
131
138
|
abstract insert(key: K, value: V): Deferred<void>;
|
|
132
139
|
/**
|
|
133
140
|
* Deletes the pair that matches the key and value.
|
|
141
|
+
*
|
|
134
142
|
* @param key The key of the pair. This key must be unique.
|
|
135
143
|
* @param value The value of the pair.
|
|
144
|
+
*
|
|
145
|
+
* @warning If the 'value' is not specified, a full scan will be performed to find the value associated with the key, which may lead to performance degradation.
|
|
136
146
|
*/
|
|
137
|
-
abstract delete(key: K, value
|
|
147
|
+
abstract delete(key: K, value?: V): Deferred<void>;
|
|
138
148
|
/**
|
|
139
149
|
* It returns whether there is a value in the tree.
|
|
140
150
|
* @param key The key value to search for. This key must be unique.
|
|
@@ -43,7 +43,7 @@ export declare class BPTreeAsyncTransaction<K, V> extends BPTreeTransaction<K, V
|
|
|
43
43
|
where(condition: BPTreeCondition<V>, order?: BPTreeOrder): Promise<BPTreePair<K, V>>;
|
|
44
44
|
insert(key: K, value: V): Promise<void>;
|
|
45
45
|
protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>): Promise<BPTreeUnknownNode<K, V>>;
|
|
46
|
-
delete(key: K, value
|
|
46
|
+
delete(key: K, value?: V): Promise<void>;
|
|
47
47
|
getHeadData(): Promise<SerializableData>;
|
|
48
48
|
setHeadData(data: SerializableData): Promise<void>;
|
|
49
49
|
commit(label?: string): Promise<TransactionResult<string, BPTreeNode<K, V>>>;
|
|
@@ -40,7 +40,7 @@ export declare class BPTreeSyncTransaction<K, V> extends BPTreeTransaction<K, V>
|
|
|
40
40
|
where(condition: BPTreeCondition<V>, order?: BPTreeOrder): BPTreePair<K, V>;
|
|
41
41
|
insert(key: K, value: V): void;
|
|
42
42
|
protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>): BPTreeUnknownNode<K, V>;
|
|
43
|
-
delete(key: K, value
|
|
43
|
+
delete(key: K, value?: V): void;
|
|
44
44
|
getHeadData(): SerializableData;
|
|
45
45
|
setHeadData(data: SerializableData): void;
|
|
46
46
|
commit(label?: string): TransactionResult<string, BPTreeNode<K, V>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "serializable-bptree",
|
|
3
|
-
"version": "8.1.
|
|
3
|
+
"version": "8.1.7",
|
|
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",
|
|
@@ -38,13 +38,13 @@
|
|
|
38
38
|
"license": "MIT",
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/jest": "^30.0.0",
|
|
41
|
-
"esbuild": "^0.27.
|
|
41
|
+
"esbuild": "^0.27.3",
|
|
42
42
|
"jest": "^30.2.0",
|
|
43
43
|
"ts-jest": "^29.4.6",
|
|
44
44
|
"typescript": "^5.9.3"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"mvcc-api": "^1.3.
|
|
47
|
+
"mvcc-api": "^1.3.4",
|
|
48
48
|
"ryoiki": "^1.2.0"
|
|
49
49
|
}
|
|
50
50
|
}
|