serializable-bptree 6.2.3 → 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/cjs/index.cjs +1109 -658
- package/dist/esm/index.mjs +1109 -658
- package/dist/types/BPTreeAsync.d.ts +9 -44
- package/dist/types/BPTreeSync.d.ts +7 -41
- package/dist/types/SerializeStrategyAsync.d.ts +3 -3
- package/dist/types/SerializeStrategySync.d.ts +3 -3
- package/dist/types/base/BPTree.d.ts +19 -79
- package/dist/types/base/BPTreeAsyncBase.d.ts +41 -0
- package/dist/types/base/BPTreeSyncBase.d.ts +39 -0
- package/dist/types/base/SerializeStrategy.d.ts +9 -8
- package/dist/types/index.d.ts +3 -2
- package/dist/types/transaction/BPTreeAsyncSnapshotStrategy.d.ts +17 -0
- package/dist/types/transaction/BPTreeAsyncTransaction.d.ts +45 -0
- package/dist/types/transaction/BPTreeSyncSnapshotStrategy.d.ts +17 -0
- package/dist/types/transaction/BPTreeSyncTransaction.d.ts +43 -0
- package/dist/types/types/index.d.ts +91 -0
- package/package.json +1 -1
- package/dist/types/utils/types.d.ts +0 -5
|
@@ -1,52 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { BPTreeConstructorOption } from './types';
|
|
2
2
|
import { SerializeStrategyAsync } from './SerializeStrategyAsync';
|
|
3
3
|
import { ValueComparator } from './base/ValueComparator';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
protected readonly nodes: ReturnType<typeof this._createCachedNode>;
|
|
8
|
-
private readonly lock;
|
|
4
|
+
import { BPTreeAsyncBase } from './base/BPTreeAsyncBase';
|
|
5
|
+
import { BPTreeAsyncTransaction } from './transaction/BPTreeAsyncTransaction';
|
|
6
|
+
export declare class BPTreeAsync<K, V> extends BPTreeAsyncBase<K, V> {
|
|
9
7
|
constructor(strategy: SerializeStrategyAsync<K, V>, comparator: ValueComparator<V>, option?: BPTreeConstructorOption);
|
|
10
|
-
private _createCachedNode;
|
|
11
|
-
protected readLock<T>(callback: () => Promise<T>): Promise<T>;
|
|
12
|
-
protected writeLock<T>(callback: () => Promise<T>): Promise<T>;
|
|
13
|
-
protected getPairsGenerator(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean, direction: 1 | -1, earlyTerminate: boolean): AsyncGenerator<[K, V]>;
|
|
14
|
-
protected _createNodeId(isLeaf: boolean): Promise<string>;
|
|
15
|
-
protected _createNode(isLeaf: boolean, keys: string[] | K[][], values: V[], leaf?: boolean, parent?: string | null, next?: string | null, prev?: string | null): Promise<BPTreeUnknownNode<K, V>>;
|
|
16
|
-
protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>, value: V): Promise<void>;
|
|
17
|
-
protected _insertInParent(node: BPTreeUnknownNode<K, V>, value: V, pointer: BPTreeUnknownNode<K, V>): Promise<void>;
|
|
18
|
-
init(): Promise<void>;
|
|
19
|
-
protected getNode(id: string): Promise<BPTreeUnknownNode<K, V>>;
|
|
20
|
-
protected insertableNode(value: V): Promise<BPTreeLeafNode<K, V>>;
|
|
21
8
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
9
|
+
* Creates a new asynchronous transaction.
|
|
10
|
+
* @returns A promise that resolves to a new BPTreeAsyncTransaction.
|
|
24
11
|
*/
|
|
25
|
-
|
|
26
|
-
protected insertableRightestNodeByPrimary(value: V): Promise<BPTreeLeafNode<K, V>>;
|
|
27
|
-
protected insertableRightestEndNodeByPrimary(value: V): Promise<BPTreeLeafNode<K, V> | null>;
|
|
28
|
-
protected insertableEndNode(value: V, direction: 1 | -1): Promise<BPTreeLeafNode<K, V> | null>;
|
|
29
|
-
protected leftestNode(): Promise<BPTreeLeafNode<K, V>>;
|
|
30
|
-
protected rightestNode(): Promise<BPTreeLeafNode<K, V>>;
|
|
31
|
-
protected commitHeadBuffer(): Promise<void>;
|
|
32
|
-
protected commitNodeCreateBuffer(): Promise<void>;
|
|
33
|
-
protected commitNodeUpdateBuffer(): Promise<void>;
|
|
34
|
-
protected commitNodeDeleteBuffer(): Promise<void>;
|
|
35
|
-
/**
|
|
36
|
-
* Retrieves the value associated with the given key (PK).
|
|
37
|
-
* Note: This method performs a full scan of leaf nodes as the tree is ordered by Value, not Key.
|
|
38
|
-
*
|
|
39
|
-
* @param key The key to search for.
|
|
40
|
-
* @returns The value associated with the key, or undefined if not found.
|
|
41
|
-
*/
|
|
42
|
-
get(key: K): Promise<V | undefined>;
|
|
43
|
-
keysStream(condition: BPTreeCondition<V>, filterValues?: Set<K>, limit?: number): AsyncGenerator<K>;
|
|
44
|
-
whereStream(condition: BPTreeCondition<V>, limit?: number): AsyncGenerator<[K, V]>;
|
|
45
|
-
keys(condition: BPTreeCondition<V>, filterValues?: Set<K>): Promise<Set<K>>;
|
|
46
|
-
where(condition: BPTreeCondition<V>): Promise<BPTreePair<K, V>>;
|
|
12
|
+
createTransaction(): Promise<BPTreeAsyncTransaction<K, V>>;
|
|
47
13
|
insert(key: K, value: V): Promise<void>;
|
|
48
14
|
delete(key: K, value: V): Promise<void>;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
forceUpdate(): Promise<number>;
|
|
15
|
+
protected readLock<T>(fn: () => Promise<T>): Promise<T>;
|
|
16
|
+
protected writeLock<T>(fn: () => Promise<T>): Promise<T>;
|
|
52
17
|
}
|
|
@@ -1,49 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { BPTreeConstructorOption } from './types';
|
|
2
2
|
import { SerializeStrategySync } from './SerializeStrategySync';
|
|
3
3
|
import { ValueComparator } from './base/ValueComparator';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
protected readonly nodes: ReturnType<typeof this._createCachedNode>;
|
|
4
|
+
import { BPTreeSyncBase } from './base/BPTreeSyncBase';
|
|
5
|
+
import { BPTreeSyncTransaction } from './transaction/BPTreeSyncTransaction';
|
|
6
|
+
export declare class BPTreeSync<K, V> extends BPTreeSyncBase<K, V> {
|
|
8
7
|
constructor(strategy: SerializeStrategySync<K, V>, comparator: ValueComparator<V>, option?: BPTreeConstructorOption);
|
|
9
|
-
private _createCachedNode;
|
|
10
|
-
protected getPairsGenerator(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean, direction: 1 | -1, earlyTerminate: boolean): Generator<[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
|
-
protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>, value: V): void;
|
|
14
|
-
protected _insertInParent(node: BPTreeUnknownNode<K, V>, value: V, pointer: BPTreeUnknownNode<K, V>): void;
|
|
15
|
-
init(): void;
|
|
16
|
-
protected getNode(id: string): BPTreeUnknownNode<K, V>;
|
|
17
|
-
protected insertableNode(value: V): BPTreeLeafNode<K, V>;
|
|
18
8
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
9
|
+
* Creates a new synchronous transaction.
|
|
10
|
+
* @returns A new BPTreeSyncTransaction.
|
|
21
11
|
*/
|
|
22
|
-
|
|
23
|
-
protected insertableRightestNodeByPrimary(value: V): BPTreeLeafNode<K, V>;
|
|
24
|
-
protected insertableRightestEndNodeByPrimary(value: V): BPTreeLeafNode<K, V> | null;
|
|
25
|
-
protected insertableEndNode(value: V, direction: 1 | -1): BPTreeLeafNode<K, V> | null;
|
|
26
|
-
protected leftestNode(): BPTreeLeafNode<K, V>;
|
|
27
|
-
protected rightestNode(): BPTreeLeafNode<K, V>;
|
|
28
|
-
protected commitHeadBuffer(): void;
|
|
29
|
-
protected commitNodeCreateBuffer(): void;
|
|
30
|
-
protected commitNodeUpdateBuffer(): void;
|
|
31
|
-
protected commitNodeDeleteBuffer(): void;
|
|
32
|
-
/**
|
|
33
|
-
* Retrieves the value associated with the given key (PK).
|
|
34
|
-
* Note: This method performs a full scan of leaf nodes as the tree is ordered by Value, not Key.
|
|
35
|
-
*
|
|
36
|
-
* @param key The key to search for.
|
|
37
|
-
* @returns The value associated with the key, or undefined if not found.
|
|
38
|
-
*/
|
|
39
|
-
get(key: K): V | undefined;
|
|
40
|
-
keysStream(condition: BPTreeCondition<V>, filterValues?: Set<K>, limit?: number): Generator<K>;
|
|
41
|
-
whereStream(condition: BPTreeCondition<V>, limit?: number): Generator<[K, V]>;
|
|
42
|
-
keys(condition: BPTreeCondition<V>, filterValues?: Set<K>): Set<K>;
|
|
43
|
-
where(condition: BPTreeCondition<V>): BPTreePair<K, V>;
|
|
12
|
+
createTransaction(): BPTreeSyncTransaction<K, V>;
|
|
44
13
|
insert(key: K, value: V): void;
|
|
45
14
|
delete(key: K, value: V): void;
|
|
46
|
-
exists(key: K, value: V): boolean;
|
|
47
|
-
setHeadData(data: SerializableData): void;
|
|
48
|
-
forceUpdate(): number;
|
|
49
15
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { BPTreeNode } from './
|
|
2
|
-
import { SerializeStrategy
|
|
3
|
-
import { Json } from './utils/types';
|
|
1
|
+
import { BPTreeNode, SerializeStrategyHead, Json } from './types';
|
|
2
|
+
import { SerializeStrategy } from './base/SerializeStrategy';
|
|
4
3
|
export declare abstract class SerializeStrategyAsync<K, V> extends SerializeStrategy<K, V> {
|
|
5
4
|
abstract id(isLeaf: boolean): Promise<string>;
|
|
6
5
|
abstract read(id: string): Promise<BPTreeNode<K, V>>;
|
|
@@ -11,6 +10,7 @@ export declare abstract class SerializeStrategyAsync<K, V> extends SerializeStra
|
|
|
11
10
|
getHeadData(key: string, defaultValue: Json): Promise<Json>;
|
|
12
11
|
setHeadData(key: string, data: Json): Promise<void>;
|
|
13
12
|
autoIncrement(key: string, defaultValue: number): Promise<number>;
|
|
13
|
+
compareAndSwapHead(oldRoot: string | null, newRoot: string): Promise<boolean>;
|
|
14
14
|
}
|
|
15
15
|
export declare class InMemoryStoreStrategyAsync<K, V> extends SerializeStrategyAsync<K, V> {
|
|
16
16
|
protected readonly node: Record<string, BPTreeNode<K, V>>;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { BPTreeNode } from './
|
|
2
|
-
import { SerializeStrategy
|
|
3
|
-
import { Json } from './utils/types';
|
|
1
|
+
import { BPTreeNode, SerializeStrategyHead, Json } from './types';
|
|
2
|
+
import { SerializeStrategy } from './base/SerializeStrategy';
|
|
4
3
|
export declare abstract class SerializeStrategySync<K, V> extends SerializeStrategy<K, V> {
|
|
5
4
|
abstract id(isLeaf: boolean): string;
|
|
6
5
|
abstract read(id: string): BPTreeNode<K, V>;
|
|
@@ -11,6 +10,7 @@ export declare abstract class SerializeStrategySync<K, V> extends SerializeStrat
|
|
|
11
10
|
getHeadData(key: string, defaultValue: Json): Json;
|
|
12
11
|
setHeadData(key: string, data: Json): void;
|
|
13
12
|
autoIncrement(key: string, defaultValue: number): number;
|
|
13
|
+
compareAndSwapHead(oldRoot: string | null, newRoot: string): boolean;
|
|
14
14
|
}
|
|
15
15
|
export declare class InMemoryStoreStrategySync<K, V> extends SerializeStrategySync<K, V> {
|
|
16
16
|
protected readonly node: Record<string, BPTreeNode<K, V>>;
|
|
@@ -1,78 +1,7 @@
|
|
|
1
|
+
import type { BPTreeCondition, BPTreeConstructorOption, BPTreeUnknownNode, Deferred, BPTreeLeafNode, BPTreeNodeKey, BPTreePair, SerializableData } from '../types';
|
|
1
2
|
import { CacheEntanglementSync, CacheEntanglementAsync } from 'cache-entanglement';
|
|
2
3
|
import { ValueComparator } from './ValueComparator';
|
|
3
|
-
import {
|
|
4
|
-
type Sync<T> = T;
|
|
5
|
-
type Async<T> = Promise<T>;
|
|
6
|
-
type Deferred<T> = Sync<T> | Async<T>;
|
|
7
|
-
export type BPTreeNodeKey<K> = string | K;
|
|
8
|
-
export type BPTreeCondition<V> = Partial<{
|
|
9
|
-
/** Searches for pairs greater than the given value. */
|
|
10
|
-
gt: Partial<V>;
|
|
11
|
-
/** Searches for pairs less than the given value. */
|
|
12
|
-
lt: Partial<V>;
|
|
13
|
-
/** Searches for pairs greater than or equal to the given value. */
|
|
14
|
-
gte: Partial<V>;
|
|
15
|
-
/** Searches for pairs less than or equal to the given value. */
|
|
16
|
-
lte: Partial<V>;
|
|
17
|
-
/** "Searches for pairs equal to the given value. */
|
|
18
|
-
equal: Partial<V>;
|
|
19
|
-
/** Searches for pairs not equal to the given value. */
|
|
20
|
-
notEqual: Partial<V>;
|
|
21
|
-
/** Searches for pairs that satisfy at least one of the conditions. */
|
|
22
|
-
or: Partial<V>[];
|
|
23
|
-
/** Searches for values matching the given pattern. '%' matches zero or more characters, and '_' matches exactly one character. */
|
|
24
|
-
/**
|
|
25
|
-
* Searches for pairs where the primary field equals the given value.
|
|
26
|
-
* Uses `primaryAsc` method for comparison, which compares only the primary sorting field.
|
|
27
|
-
* Useful for composite values where you want to find all entries with the same primary value.
|
|
28
|
-
*/
|
|
29
|
-
primaryEqual: Partial<V>;
|
|
30
|
-
/** Searches for pairs where the primary field is greater than the given value. */
|
|
31
|
-
primaryGt: Partial<V>;
|
|
32
|
-
/** Searches for pairs where the primary field is greater than or equal to the given value. */
|
|
33
|
-
primaryGte: Partial<V>;
|
|
34
|
-
/** Searches for pairs where the primary field is less than the given value. */
|
|
35
|
-
primaryLt: Partial<V>;
|
|
36
|
-
/** Searches for pairs where the primary field is less than or equal to the given value. */
|
|
37
|
-
primaryLte: Partial<V>;
|
|
38
|
-
/** Searches for pairs where the primary field is not equal to the given value. */
|
|
39
|
-
primaryNotEqual: Partial<V>;
|
|
40
|
-
/** Searches for pairs where the primary field matches at least one of the given values. */
|
|
41
|
-
primaryOr: Partial<V>[];
|
|
42
|
-
/**
|
|
43
|
-
* Searches for values matching the given pattern on the primary field.
|
|
44
|
-
* Uses `match` method for getting string representation.
|
|
45
|
-
* '%' matches zero or more characters, and '_' matches exactly one character.
|
|
46
|
-
*/
|
|
47
|
-
like: string;
|
|
48
|
-
}>;
|
|
49
|
-
export type BPTreePair<K, V> = Map<K, V>;
|
|
50
|
-
export type BPTreeUnknownNode<K, V> = BPTreeInternalNode<K, V> | BPTreeLeafNode<K, V>;
|
|
51
|
-
export interface BPTreeConstructorOption {
|
|
52
|
-
/**
|
|
53
|
-
* The capacity of the cache.
|
|
54
|
-
* This value is used to determine how many nodes can be cached.
|
|
55
|
-
* If not specified, the default value is 1000.
|
|
56
|
-
*/
|
|
57
|
-
capacity?: number;
|
|
58
|
-
}
|
|
59
|
-
export interface BPTreeNode<K, V> {
|
|
60
|
-
id: string;
|
|
61
|
-
keys: string[] | K[][];
|
|
62
|
-
values: V[];
|
|
63
|
-
leaf: boolean;
|
|
64
|
-
parent: string | null;
|
|
65
|
-
next: string | null;
|
|
66
|
-
prev: string | null;
|
|
67
|
-
}
|
|
68
|
-
export interface BPTreeInternalNode<K, V> extends BPTreeNode<K, V> {
|
|
69
|
-
leaf: false;
|
|
70
|
-
keys: string[];
|
|
71
|
-
}
|
|
72
|
-
export interface BPTreeLeafNode<K, V> extends BPTreeNode<K, V> {
|
|
73
|
-
leaf: true;
|
|
74
|
-
keys: K[][];
|
|
75
|
-
}
|
|
4
|
+
import { SerializeStrategy } from './SerializeStrategy';
|
|
76
5
|
export declare abstract class BPTree<K, V> {
|
|
77
6
|
private readonly _cachedRegexp;
|
|
78
7
|
protected abstract readonly nodes: CacheEntanglementSync<any, any> | CacheEntanglementAsync<any, any>;
|
|
@@ -81,6 +10,16 @@ export declare abstract class BPTree<K, V> {
|
|
|
81
10
|
protected readonly option: BPTreeConstructorOption;
|
|
82
11
|
protected order: number;
|
|
83
12
|
protected rootId: string;
|
|
13
|
+
/**
|
|
14
|
+
* Returns the ID of the root node.
|
|
15
|
+
* @returns The root node ID.
|
|
16
|
+
*/
|
|
17
|
+
getRootId(): string;
|
|
18
|
+
/**
|
|
19
|
+
* Returns the order of the B+Tree.
|
|
20
|
+
* @returns The order of the tree.
|
|
21
|
+
*/
|
|
22
|
+
getOrder(): number;
|
|
84
23
|
protected _strategyDirty: boolean;
|
|
85
24
|
protected readonly _nodeCreateBuffer: Map<string, BPTreeUnknownNode<K, V>>;
|
|
86
25
|
protected readonly _nodeUpdateBuffer: Map<string, BPTreeUnknownNode<K, V>>;
|
|
@@ -200,18 +139,20 @@ export declare abstract class BPTree<K, V> {
|
|
|
200
139
|
/**
|
|
201
140
|
* This method deletes nodes cached in-memory and caches new nodes from the stored nodes.
|
|
202
141
|
* Typically, there's no need to use this method, but it can be used to synchronize data in scenarios where the remote storage and the client are in a 1:n relationship.
|
|
142
|
+
* If you do not specify an ID, all nodes will be updated.
|
|
143
|
+
* @param id The ID of the node to update.
|
|
203
144
|
* @returns The return value is the total number of nodes updated.
|
|
204
145
|
*/
|
|
205
|
-
abstract forceUpdate(): Deferred<number>;
|
|
146
|
+
abstract forceUpdate(id?: string): Deferred<number>;
|
|
206
147
|
protected ensureValues(v: V | V[]): V[];
|
|
207
148
|
protected lowestValue(v: V[]): V;
|
|
208
149
|
protected highestValue(v: V[]): V;
|
|
209
150
|
protected lowestPrimaryValue(v: V[]): V;
|
|
210
151
|
protected highestPrimaryValue(v: V[]): V;
|
|
211
|
-
protected _insertAtLeaf(node: BPTreeLeafNode<K, V>, key: K, value: V): void
|
|
212
|
-
protected bufferForNodeCreate(node: BPTreeUnknownNode<K, V>): void
|
|
213
|
-
protected bufferForNodeUpdate(node: BPTreeUnknownNode<K, V>): void
|
|
214
|
-
protected bufferForNodeDelete(node: BPTreeUnknownNode<K, V>): void
|
|
152
|
+
protected _insertAtLeaf(node: BPTreeLeafNode<K, V>, key: K, value: V): Deferred<void>;
|
|
153
|
+
protected bufferForNodeCreate(node: BPTreeUnknownNode<K, V>): Deferred<void>;
|
|
154
|
+
protected bufferForNodeUpdate(node: BPTreeUnknownNode<K, V>): Deferred<void>;
|
|
155
|
+
protected bufferForNodeDelete(node: BPTreeUnknownNode<K, V>): Deferred<void>;
|
|
215
156
|
/**
|
|
216
157
|
* Returns the user-defined data stored in the head of the tree.
|
|
217
158
|
* 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 `{}`.
|
|
@@ -224,4 +165,3 @@ export declare abstract class BPTree<K, V> {
|
|
|
224
165
|
*/
|
|
225
166
|
clear(): void;
|
|
226
167
|
}
|
|
227
|
-
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { BPTreeCondition, BPTreeConstructorOption, BPTreeUnknownNode, BPTreeLeafNode, BPTreeNodeKey, SerializableData, BPTreePair } from '../types';
|
|
2
|
+
import { SerializeStrategyAsync } from '../SerializeStrategyAsync';
|
|
3
|
+
import { BPTree } from './BPTree';
|
|
4
|
+
import { ValueComparator } from './ValueComparator';
|
|
5
|
+
export declare abstract class BPTreeAsyncBase<K, V> extends BPTree<K, V> {
|
|
6
|
+
protected readonly strategy: SerializeStrategyAsync<K, V>;
|
|
7
|
+
protected readonly nodes: ReturnType<typeof this._createCachedNode>;
|
|
8
|
+
constructor(strategy: SerializeStrategyAsync<K, V>, comparator: ValueComparator<V>, option?: BPTreeConstructorOption);
|
|
9
|
+
private _createCachedNode;
|
|
10
|
+
protected getPairsGenerator(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean, direction: 1 | -1, earlyTerminate: boolean): AsyncGenerator<[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
|
+
protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>, value: V): Promise<void>;
|
|
14
|
+
protected _insertInParent(node: BPTreeUnknownNode<K, V>, value: V, pointer: BPTreeUnknownNode<K, V>): Promise<void>;
|
|
15
|
+
init(): Promise<void>;
|
|
16
|
+
protected getNode(id: string): Promise<BPTreeUnknownNode<K, V>>;
|
|
17
|
+
protected insertableNode(value: V): Promise<BPTreeLeafNode<K, V>>;
|
|
18
|
+
protected insertableNodeByPrimary(value: V): Promise<BPTreeLeafNode<K, V>>;
|
|
19
|
+
protected insertableRightestNodeByPrimary(value: V): Promise<BPTreeLeafNode<K, V>>;
|
|
20
|
+
protected insertableRightestEndNodeByPrimary(value: V): Promise<BPTreeLeafNode<K, V> | null>;
|
|
21
|
+
protected insertableEndNode(value: V, direction: 1 | -1): Promise<BPTreeLeafNode<K, V> | null>;
|
|
22
|
+
protected leftestNode(): Promise<BPTreeLeafNode<K, V>>;
|
|
23
|
+
protected rightestNode(): Promise<BPTreeLeafNode<K, V>>;
|
|
24
|
+
exists(key: K, value: V): Promise<boolean>;
|
|
25
|
+
forceUpdate(id?: string): Promise<number>;
|
|
26
|
+
protected commitHeadBuffer(): Promise<void>;
|
|
27
|
+
protected commitNodeCreateBuffer(): Promise<void>;
|
|
28
|
+
protected commitNodeUpdateBuffer(): Promise<void>;
|
|
29
|
+
protected commitNodeDeleteBuffer(): Promise<void>;
|
|
30
|
+
get(key: K): Promise<V | undefined>;
|
|
31
|
+
keysStream(condition: BPTreeCondition<V>, filterValues?: Set<K>, limit?: number): AsyncGenerator<K>;
|
|
32
|
+
whereStream(condition: BPTreeCondition<V>, limit?: number): AsyncGenerator<[K, V]>;
|
|
33
|
+
keys(condition: BPTreeCondition<V>, filterValues?: Set<K>): Promise<Set<K>>;
|
|
34
|
+
where(condition: BPTreeCondition<V>): Promise<BPTreePair<K, V>>;
|
|
35
|
+
insert(key: K, value: V): Promise<void>;
|
|
36
|
+
delete(key: K, value: V): Promise<void>;
|
|
37
|
+
getHeadData(): SerializableData;
|
|
38
|
+
setHeadData(data: SerializableData): Promise<void>;
|
|
39
|
+
protected abstract readLock<T>(fn: () => Promise<T>): Promise<T>;
|
|
40
|
+
protected abstract writeLock<T>(fn: () => Promise<T>): Promise<T>;
|
|
41
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { BPTreeCondition, BPTreeConstructorOption, BPTreeUnknownNode, BPTreeLeafNode, BPTreeNodeKey, BPTreePair, SerializableData } from '../types';
|
|
2
|
+
import { SerializeStrategySync } from '../SerializeStrategySync';
|
|
3
|
+
import { BPTree } from './BPTree';
|
|
4
|
+
import { ValueComparator } from './ValueComparator';
|
|
5
|
+
export declare abstract class BPTreeSyncBase<K, V> extends BPTree<K, V> {
|
|
6
|
+
protected readonly strategy: SerializeStrategySync<K, V>;
|
|
7
|
+
protected readonly nodes: ReturnType<typeof this._createCachedNode>;
|
|
8
|
+
constructor(strategy: SerializeStrategySync<K, V>, comparator: ValueComparator<V>, option?: BPTreeConstructorOption);
|
|
9
|
+
private _createCachedNode;
|
|
10
|
+
protected getPairsGenerator(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean, direction: 1 | -1, earlyTerminate: boolean): Generator<[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
|
+
protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>, value: V): void;
|
|
14
|
+
protected _insertInParent(node: BPTreeUnknownNode<K, V>, value: V, pointer: BPTreeUnknownNode<K, V>): void;
|
|
15
|
+
init(): void;
|
|
16
|
+
protected getNode(id: string): BPTreeUnknownNode<K, V>;
|
|
17
|
+
protected insertableNode(value: V): BPTreeLeafNode<K, V>;
|
|
18
|
+
protected insertableNodeByPrimary(value: V): BPTreeLeafNode<K, V>;
|
|
19
|
+
protected insertableRightestNodeByPrimary(value: V): BPTreeLeafNode<K, V>;
|
|
20
|
+
protected insertableRightestEndNodeByPrimary(value: V): BPTreeLeafNode<K, V> | null;
|
|
21
|
+
protected insertableEndNode(value: V, direction: 1 | -1): BPTreeLeafNode<K, V> | null;
|
|
22
|
+
protected leftestNode(): BPTreeLeafNode<K, V>;
|
|
23
|
+
protected rightestNode(): BPTreeLeafNode<K, V>;
|
|
24
|
+
exists(key: K, value: V): boolean;
|
|
25
|
+
forceUpdate(id?: string): number;
|
|
26
|
+
protected commitHeadBuffer(): void;
|
|
27
|
+
protected commitNodeCreateBuffer(): void;
|
|
28
|
+
protected commitNodeUpdateBuffer(): void;
|
|
29
|
+
protected commitNodeDeleteBuffer(): void;
|
|
30
|
+
get(key: K): V | undefined;
|
|
31
|
+
keysStream(condition: BPTreeCondition<V>, filterValues?: Set<K>, limit?: number): Generator<K>;
|
|
32
|
+
whereStream(condition: BPTreeCondition<V>, limit?: number): Generator<[K, V]>;
|
|
33
|
+
keys(condition: BPTreeCondition<V>, filterValues?: Set<K>): Set<K>;
|
|
34
|
+
where(condition: BPTreeCondition<V>): BPTreePair<K, V>;
|
|
35
|
+
insert(key: K, value: V): void;
|
|
36
|
+
delete(key: K, value: V): void;
|
|
37
|
+
getHeadData(): SerializableData;
|
|
38
|
+
setHeadData(data: SerializableData): void;
|
|
39
|
+
}
|
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
import { BPTreeNode } from '
|
|
2
|
-
import type { Json } from '../utils/types';
|
|
3
|
-
export type SerializableData = Record<string, Json>;
|
|
4
|
-
export interface SerializeStrategyHead {
|
|
5
|
-
root: string | null;
|
|
6
|
-
order: number;
|
|
7
|
-
data: SerializableData;
|
|
8
|
-
}
|
|
1
|
+
import type { BPTreeNode, Json, SerializeStrategyHead } from '../types';
|
|
9
2
|
export declare abstract class SerializeStrategy<K, V> {
|
|
10
3
|
readonly order: number;
|
|
11
4
|
head: SerializeStrategyHead;
|
|
@@ -50,6 +43,14 @@ export declare abstract class SerializeStrategy<K, V> {
|
|
|
50
43
|
* @param head This is the current state of the tree.
|
|
51
44
|
*/
|
|
52
45
|
abstract writeHead(head: SerializeStrategyHead): void | Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Atomically updates the head if the current root matches the expected value.
|
|
48
|
+
* Required for Optimistic Concurrency Control (CoW).
|
|
49
|
+
* @param oldRoot The expected current root ID.
|
|
50
|
+
* @param newRoot The new root ID to set.
|
|
51
|
+
* @returns True if successful, False if the root has changed.
|
|
52
|
+
*/
|
|
53
|
+
abstract compareAndSwapHead(oldRoot: string | null, newRoot: string): boolean | Promise<boolean>;
|
|
53
54
|
/**
|
|
54
55
|
* Retrieves the data stored in the tree.
|
|
55
56
|
* If no value is stored in the tree, it stores a `defaultValue` and then returns that value.
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export type { BPTreeNode, BPTreeInternalNode, BPTreeLeafNode, BPTreeNodeKey, BPTreePair, BPTreeUnknownNode, BPTreeCondition } from './
|
|
2
|
-
export type { SerializeStrategyHead, SerializableData } from './base/SerializeStrategy';
|
|
1
|
+
export type { BPTreeNode, BPTreeInternalNode, BPTreeLeafNode, BPTreeNodeKey, BPTreePair, BPTreeUnknownNode, BPTreeCondition, SerializeStrategyHead, SerializableData } from './types';
|
|
3
2
|
export { ValueComparator, NumericComparator, StringComparator } from './base/ValueComparator';
|
|
4
3
|
export { BPTreeSync } from './BPTreeSync';
|
|
4
|
+
export { BPTreeSyncTransaction } from './transaction/BPTreeSyncTransaction';
|
|
5
5
|
export { BPTreeAsync } from './BPTreeAsync';
|
|
6
|
+
export { BPTreeAsyncTransaction } from './transaction/BPTreeAsyncTransaction';
|
|
6
7
|
export { SerializeStrategySync, InMemoryStoreStrategySync } from './SerializeStrategySync';
|
|
7
8
|
export { SerializeStrategyAsync, InMemoryStoreStrategyAsync } from './SerializeStrategyAsync';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SerializeStrategyHead, BPTreeNode, Json } from '../types';
|
|
2
|
+
import { SerializeStrategyAsync } from '../SerializeStrategyAsync';
|
|
3
|
+
export declare class BPTreeAsyncSnapshotStrategy<K, V> extends SerializeStrategyAsync<K, V> {
|
|
4
|
+
private readonly baseStrategy;
|
|
5
|
+
private readonly snapshotHead;
|
|
6
|
+
constructor(baseStrategy: SerializeStrategyAsync<K, V>, root: string);
|
|
7
|
+
id(isLeaf: boolean): Promise<string>;
|
|
8
|
+
read(id: string): Promise<BPTreeNode<K, V>>;
|
|
9
|
+
write(id: string, node: BPTreeNode<K, V>): Promise<void>;
|
|
10
|
+
delete(id: string): Promise<void>;
|
|
11
|
+
readHead(): Promise<SerializeStrategyHead | null>;
|
|
12
|
+
writeHead(head: SerializeStrategyHead): Promise<void>;
|
|
13
|
+
compareAndSwapHead(oldRoot: string | null, newRoot: string): Promise<boolean>;
|
|
14
|
+
getHeadData(key: string, defaultValue: Json): Promise<Json>;
|
|
15
|
+
setHeadData(key: string, data: Json): Promise<void>;
|
|
16
|
+
autoIncrement(key: string, defaultValue: number): Promise<number>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { BPTreeUnknownNode, BPTreeTransactionResult } from '../types';
|
|
2
|
+
import { BPTreeAsyncBase } from '../base/BPTreeAsyncBase';
|
|
3
|
+
/**
|
|
4
|
+
* Represents an asynchronous transaction for a B+ Tree.
|
|
5
|
+
* Provides Snapshot Isolation using MVCC and Copy-on-Write techniques.
|
|
6
|
+
*/
|
|
7
|
+
export declare class BPTreeAsyncTransaction<K, V> extends BPTreeAsyncBase<K, V> {
|
|
8
|
+
private readonly realBaseTree;
|
|
9
|
+
private readonly realBaseStrategy;
|
|
10
|
+
private txNodes;
|
|
11
|
+
protected readonly dirtyIds: Set<string>;
|
|
12
|
+
protected readonly createdInTx: Set<string>;
|
|
13
|
+
protected readonly deletedIds: Set<string>;
|
|
14
|
+
private initialRootId;
|
|
15
|
+
private transactionRootId;
|
|
16
|
+
constructor(baseTree: BPTreeAsyncBase<K, V>);
|
|
17
|
+
/**
|
|
18
|
+
* Initializes the transaction by capturing the current state of the tree.
|
|
19
|
+
*/
|
|
20
|
+
initTransaction(): Promise<void>;
|
|
21
|
+
protected getNode(id: string): Promise<BPTreeUnknownNode<K, V>>;
|
|
22
|
+
protected bufferForNodeUpdate(node: BPTreeUnknownNode<K, V>): Promise<void>;
|
|
23
|
+
protected bufferForNodeCreate(node: BPTreeUnknownNode<K, V>): Promise<void>;
|
|
24
|
+
protected bufferForNodeDelete(node: BPTreeUnknownNode<K, V>): Promise<void>;
|
|
25
|
+
private markPathDirty;
|
|
26
|
+
protected _createNode(isLeaf: boolean, keys: string[] | K[][], values: V[], leaf?: boolean, parent?: string | null, next?: string | null, prev?: string | null): Promise<BPTreeUnknownNode<K, V>>;
|
|
27
|
+
/**
|
|
28
|
+
* Attempts to commit the transaction.
|
|
29
|
+
* Uses Optimistic Locking (Compare-And-Swap) on the root node ID to detect conflicts.
|
|
30
|
+
*
|
|
31
|
+
* @returns A promise that resolves to the transaction result.
|
|
32
|
+
*/
|
|
33
|
+
commit(): Promise<BPTreeTransactionResult>;
|
|
34
|
+
/**
|
|
35
|
+
* Rolls back the transaction by clearing all buffered changes.
|
|
36
|
+
* Internal use only.
|
|
37
|
+
*/
|
|
38
|
+
protected rollback(): Promise<void>;
|
|
39
|
+
protected readLock<T>(fn: () => Promise<T>): Promise<T>;
|
|
40
|
+
protected writeLock<T>(fn: () => Promise<T>): Promise<T>;
|
|
41
|
+
protected commitHeadBuffer(): Promise<void>;
|
|
42
|
+
protected commitNodeCreateBuffer(): Promise<void>;
|
|
43
|
+
protected commitNodeUpdateBuffer(): Promise<void>;
|
|
44
|
+
protected commitNodeDeleteBuffer(): Promise<void>;
|
|
45
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SerializeStrategyHead, BPTreeNode, Json } from '../types';
|
|
2
|
+
import { SerializeStrategySync } from '../SerializeStrategySync';
|
|
3
|
+
export declare class BPTreeSyncSnapshotStrategy<K, V> extends SerializeStrategySync<K, V> {
|
|
4
|
+
private readonly baseStrategy;
|
|
5
|
+
private readonly snapshotHead;
|
|
6
|
+
constructor(baseStrategy: SerializeStrategySync<K, V>, root: string);
|
|
7
|
+
id(isLeaf: boolean): string;
|
|
8
|
+
read(id: string): BPTreeNode<K, V>;
|
|
9
|
+
write(id: string, node: BPTreeNode<K, V>): void;
|
|
10
|
+
delete(id: string): void;
|
|
11
|
+
readHead(): SerializeStrategyHead | null;
|
|
12
|
+
writeHead(head: SerializeStrategyHead): void;
|
|
13
|
+
compareAndSwapHead(oldRoot: string | null, newRoot: string): boolean;
|
|
14
|
+
getHeadData(key: string, defaultValue: Json): Json;
|
|
15
|
+
setHeadData(key: string, data: Json): void;
|
|
16
|
+
autoIncrement(key: string, defaultValue: number): number;
|
|
17
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { BPTreeUnknownNode, BPTreeTransactionResult } from '../types';
|
|
2
|
+
import { BPTreeSyncBase } from '../base/BPTreeSyncBase';
|
|
3
|
+
/**
|
|
4
|
+
* Represents a synchronous transaction for a B+ Tree.
|
|
5
|
+
* Provides Snapshot Isolation using MVCC and Copy-on-Write techniques.
|
|
6
|
+
*/
|
|
7
|
+
export declare class BPTreeSyncTransaction<K, V> extends BPTreeSyncBase<K, V> {
|
|
8
|
+
private readonly realBaseTree;
|
|
9
|
+
private readonly realBaseStrategy;
|
|
10
|
+
private txNodes;
|
|
11
|
+
protected readonly dirtyIds: Set<string>;
|
|
12
|
+
protected readonly createdInTx: Set<string>;
|
|
13
|
+
protected readonly deletedIds: Set<string>;
|
|
14
|
+
private initialRootId;
|
|
15
|
+
private transactionRootId;
|
|
16
|
+
constructor(baseTree: BPTreeSyncBase<K, V>);
|
|
17
|
+
/**
|
|
18
|
+
* Initializes the transaction by capturing the current state of the tree.
|
|
19
|
+
*/
|
|
20
|
+
initTransaction(): void;
|
|
21
|
+
protected getNode(id: string): BPTreeUnknownNode<K, V>;
|
|
22
|
+
protected bufferForNodeUpdate(node: BPTreeUnknownNode<K, V>): void;
|
|
23
|
+
protected bufferForNodeCreate(node: BPTreeUnknownNode<K, V>): void;
|
|
24
|
+
protected bufferForNodeDelete(node: BPTreeUnknownNode<K, V>): void;
|
|
25
|
+
private markPathDirty;
|
|
26
|
+
protected _createNode(isLeaf: boolean, keys: string[] | K[][], values: V[], leaf?: boolean, parent?: string | null, next?: string | null, prev?: string | null): BPTreeUnknownNode<K, V>;
|
|
27
|
+
/**
|
|
28
|
+
* Attempts to commit the transaction.
|
|
29
|
+
* Uses Optimistic Locking (Compare-And-Swap) on the root node ID to detect conflicts.
|
|
30
|
+
*
|
|
31
|
+
* @returns The transaction result.
|
|
32
|
+
*/
|
|
33
|
+
commit(): BPTreeTransactionResult;
|
|
34
|
+
/**
|
|
35
|
+
* Rolls back the transaction by clearing all buffered changes.
|
|
36
|
+
* Internal use only.
|
|
37
|
+
*/
|
|
38
|
+
protected rollback(): void;
|
|
39
|
+
protected commitHeadBuffer(): void;
|
|
40
|
+
protected commitNodeCreateBuffer(): void;
|
|
41
|
+
protected commitNodeUpdateBuffer(): void;
|
|
42
|
+
protected commitNodeDeleteBuffer(): void;
|
|
43
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
export type Sync<T> = T;
|
|
2
|
+
export type Async<T> = Promise<T>;
|
|
3
|
+
export type Deferred<T> = Sync<T> | Async<T>;
|
|
4
|
+
export type BPTreeNodeKey<K> = string | K;
|
|
5
|
+
export type BPTreeCondition<V> = Partial<{
|
|
6
|
+
/** Searches for pairs greater than the given value. */
|
|
7
|
+
gt: Partial<V>;
|
|
8
|
+
/** Searches for pairs less than the given value. */
|
|
9
|
+
lt: Partial<V>;
|
|
10
|
+
/** Searches for pairs greater than or equal to the given value. */
|
|
11
|
+
gte: Partial<V>;
|
|
12
|
+
/** Searches for pairs less than or equal to the given value. */
|
|
13
|
+
lte: Partial<V>;
|
|
14
|
+
/** "Searches for pairs equal to the given value. */
|
|
15
|
+
equal: Partial<V>;
|
|
16
|
+
/** Searches for pairs not equal to the given value. */
|
|
17
|
+
notEqual: Partial<V>;
|
|
18
|
+
/** Searches for pairs that satisfy at least one of the conditions. */
|
|
19
|
+
or: Partial<V>[];
|
|
20
|
+
/** Searches for values matching the given pattern. '%' matches zero or more characters, and '_' matches exactly one character. */
|
|
21
|
+
/**
|
|
22
|
+
* Searches for pairs where the primary field equals the given value.
|
|
23
|
+
* Uses `primaryAsc` method for comparison, which compares only the primary sorting field.
|
|
24
|
+
* Useful for composite values where you want to find all entries with the same primary value.
|
|
25
|
+
*/
|
|
26
|
+
primaryEqual: Partial<V>;
|
|
27
|
+
/** Searches for pairs where the primary field is greater than the given value. */
|
|
28
|
+
primaryGt: Partial<V>;
|
|
29
|
+
/** Searches for pairs where the primary field is greater than or equal to the given value. */
|
|
30
|
+
primaryGte: Partial<V>;
|
|
31
|
+
/** Searches for pairs where the primary field is less than the given value. */
|
|
32
|
+
primaryLt: Partial<V>;
|
|
33
|
+
/** Searches for pairs where the primary field is less than or equal to the given value. */
|
|
34
|
+
primaryLte: Partial<V>;
|
|
35
|
+
/** Searches for pairs where the primary field is not equal to the given value. */
|
|
36
|
+
primaryNotEqual: Partial<V>;
|
|
37
|
+
/** Searches for pairs where the primary field matches at least one of the given values. */
|
|
38
|
+
primaryOr: Partial<V>[];
|
|
39
|
+
/**
|
|
40
|
+
* Searches for values matching the given pattern on the primary field.
|
|
41
|
+
* Uses `match` method for getting string representation.
|
|
42
|
+
* '%' matches zero or more characters, and '_' matches exactly one character.
|
|
43
|
+
*/
|
|
44
|
+
like: string;
|
|
45
|
+
}>;
|
|
46
|
+
export type BPTreePair<K, V> = Map<K, V>;
|
|
47
|
+
export type BPTreeUnknownNode<K, V> = BPTreeInternalNode<K, V> | BPTreeLeafNode<K, V>;
|
|
48
|
+
export interface BPTreeConstructorOption {
|
|
49
|
+
/**
|
|
50
|
+
* The capacity of the cache.
|
|
51
|
+
* This value is used to determine how many nodes can be cached.
|
|
52
|
+
* If not specified, the default value is 1000.
|
|
53
|
+
*/
|
|
54
|
+
capacity?: number;
|
|
55
|
+
}
|
|
56
|
+
export interface BPTreeNode<K, V> {
|
|
57
|
+
id: string;
|
|
58
|
+
keys: string[] | K[][];
|
|
59
|
+
values: V[];
|
|
60
|
+
leaf: boolean;
|
|
61
|
+
parent: string | null;
|
|
62
|
+
next: string | null;
|
|
63
|
+
prev: string | null;
|
|
64
|
+
}
|
|
65
|
+
export interface BPTreeInternalNode<K, V> extends BPTreeNode<K, V> {
|
|
66
|
+
leaf: false;
|
|
67
|
+
keys: string[];
|
|
68
|
+
}
|
|
69
|
+
export interface BPTreeLeafNode<K, V> extends BPTreeNode<K, V> {
|
|
70
|
+
leaf: true;
|
|
71
|
+
keys: K[][];
|
|
72
|
+
}
|
|
73
|
+
/** Result of a transaction commit operation. */
|
|
74
|
+
export interface BPTreeTransactionResult {
|
|
75
|
+
/** Whether the transaction was successfully committed. */
|
|
76
|
+
success: boolean;
|
|
77
|
+
/** IDs of new nodes created and written to storage during the transaction. */
|
|
78
|
+
createdIds: string[];
|
|
79
|
+
/** IDs of nodes that became obsolete and can be deleted after a successful commit. */
|
|
80
|
+
obsoleteIds: string[];
|
|
81
|
+
}
|
|
82
|
+
export type SerializableData = Record<string, Json>;
|
|
83
|
+
export interface SerializeStrategyHead {
|
|
84
|
+
root: string | null;
|
|
85
|
+
order: number;
|
|
86
|
+
data: SerializableData;
|
|
87
|
+
}
|
|
88
|
+
export type Primitive = string | number | null | boolean;
|
|
89
|
+
export type Json = Primitive | Primitive[] | Json[] | {
|
|
90
|
+
[key: string]: Json;
|
|
91
|
+
};
|
package/package.json
CHANGED