serializable-bptree 7.0.3 → 8.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.
@@ -1,17 +1,14 @@
1
1
  import type { BPTreeConstructorOption } from './types';
2
2
  import { SerializeStrategyAsync } from './SerializeStrategyAsync';
3
3
  import { ValueComparator } from './base/ValueComparator';
4
- import { BPTreeAsyncBase } from './base/BPTreeAsyncBase';
5
4
  import { BPTreeAsyncTransaction } from './transaction/BPTreeAsyncTransaction';
6
- export declare class BPTreeAsync<K, V> extends BPTreeAsyncBase<K, V> {
5
+ export declare class BPTreeAsync<K, V> extends BPTreeAsyncTransaction<K, V> {
7
6
  constructor(strategy: SerializeStrategyAsync<K, V>, comparator: ValueComparator<V>, option?: BPTreeConstructorOption);
8
7
  /**
9
8
  * Creates a new asynchronous transaction.
10
- * @returns A promise that resolves to a new BPTreeAsyncTransaction.
9
+ * @returns A new BPTreeAsyncTransaction.
11
10
  */
12
11
  createTransaction(): Promise<BPTreeAsyncTransaction<K, V>>;
13
12
  insert(key: K, value: V): Promise<void>;
14
13
  delete(key: K, value: V): Promise<void>;
15
- protected readLock<T>(fn: () => Promise<T>): Promise<T>;
16
- protected writeLock<T>(fn: () => Promise<T>): Promise<T>;
17
14
  }
@@ -1,9 +1,8 @@
1
1
  import type { BPTreeConstructorOption } from './types';
2
2
  import { SerializeStrategySync } from './SerializeStrategySync';
3
3
  import { ValueComparator } from './base/ValueComparator';
4
- import { BPTreeSyncBase } from './base/BPTreeSyncBase';
5
4
  import { BPTreeSyncTransaction } from './transaction/BPTreeSyncTransaction';
6
- export declare class BPTreeSync<K, V> extends BPTreeSyncBase<K, V> {
5
+ export declare class BPTreeSync<K, V> extends BPTreeSyncTransaction<K, V> {
7
6
  constructor(strategy: SerializeStrategySync<K, V>, comparator: ValueComparator<V>, option?: BPTreeConstructorOption);
8
7
  /**
9
8
  * Creates a new synchronous transaction.
@@ -12,8 +12,6 @@ export declare abstract class SerializeStrategyAsync<K, V> extends SerializeStra
12
12
  getHeadData(key: string, defaultValue: Json): Promise<Json>;
13
13
  setHeadData(key: string, data: Json): Promise<void>;
14
14
  autoIncrement(key: string, defaultValue: number): Promise<number>;
15
- getLastCommittedTransactionId(): Promise<number>;
16
- compareAndSwapHead(newRoot: string, newTxId: number): Promise<void>;
17
15
  }
18
16
  export declare class InMemoryStoreStrategyAsync<K, V> extends SerializeStrategyAsync<K, V> {
19
17
  protected readonly node: Record<string, BPTreeNode<K, V>>;
@@ -10,8 +10,6 @@ export declare abstract class SerializeStrategySync<K, V> extends SerializeStrat
10
10
  getHeadData(key: string, defaultValue: Json): Json;
11
11
  setHeadData(key: string, data: Json): void;
12
12
  autoIncrement(key: string, defaultValue: number): number;
13
- getLastCommittedTransactionId(): number;
14
- compareAndSwapHead(newRoot: string, newTxId: number): void;
15
13
  }
16
14
  export declare class InMemoryStoreStrategySync<K, V> extends SerializeStrategySync<K, V> {
17
15
  protected readonly node: Record<string, BPTreeNode<K, V>>;
@@ -1,25 +1,20 @@
1
- import type { BPTreeCondition, BPTreeConstructorOption, BPTreeUnknownNode, Deferred, BPTreeLeafNode, BPTreeNodeKey, BPTreePair, SerializableData } from '../types';
2
- import { CacheEntanglementSync, CacheEntanglementAsync } from 'cache-entanglement';
1
+ import type { BPTreeCondition, BPTreeConstructorOption, BPTreeUnknownNode, Deferred, BPTreeLeafNode, BPTreeNodeKey, BPTreePair, SerializableData, BPTreeNode, BPTreeMVCC } from '../types';
2
+ import { LRUMap } from 'cache-entanglement';
3
+ import { TransactionResult } from 'mvcc-api';
3
4
  import { ValueComparator } from './ValueComparator';
4
5
  import { SerializeStrategy } from './SerializeStrategy';
5
- export declare abstract class BPTree<K, V> {
6
+ export declare abstract class BPTreeTransaction<K, V> {
6
7
  private readonly _cachedRegexp;
7
- protected abstract readonly nodes: CacheEntanglementSync<any, any> | CacheEntanglementAsync<any, any>;
8
+ protected readonly nodes: LRUMap<string, BPTreeUnknownNode<K, V>>;
9
+ protected readonly deletedNodeBuffer: Map<string, BPTreeUnknownNode<K, V>>;
10
+ protected readonly rootTx: BPTreeTransaction<K, V>;
11
+ protected readonly mvccRoot: BPTreeMVCC<K, V>;
12
+ protected readonly mvcc: BPTreeMVCC<K, V>;
8
13
  protected readonly strategy: SerializeStrategy<K, V>;
9
14
  protected readonly comparator: ValueComparator<V>;
10
15
  protected readonly option: BPTreeConstructorOption;
11
16
  protected order: number;
12
17
  protected rootId: string;
13
- protected _strategyDirty: boolean;
14
- protected readonly _nodeCreateBuffer: Map<string, BPTreeUnknownNode<K, V>>;
15
- protected readonly _nodeUpdateBuffer: Map<string, BPTreeUnknownNode<K, V>>;
16
- protected readonly _nodeDeleteBuffer: Map<string, BPTreeUnknownNode<K, V>>;
17
- readonly sharedDeleteCache: Map<string, {
18
- node: BPTreeUnknownNode<K, V>;
19
- obsoleteAt: number;
20
- }>;
21
- protected readonly activeTransactions: Set<number>;
22
- private lastTransactionId;
23
18
  protected readonly verifierMap: Record<keyof BPTreeCondition<V>, (nodeValue: V, value: V | V[]) => boolean>;
24
19
  protected readonly verifierStartNode: Record<keyof BPTreeCondition<V>, (value: V) => Deferred<BPTreeLeafNode<K, V>>>;
25
20
  protected readonly verifierEndNode: Record<keyof BPTreeCondition<V>, (value: V) => Deferred<BPTreeLeafNode<K, V> | null>>;
@@ -77,12 +72,12 @@ export declare abstract class BPTree<K, V> {
77
72
  * @returns Returns true if the value satisfies the condition.
78
73
  */
79
74
  verify(nodeValue: V, condition: BPTreeCondition<V>): boolean;
80
- protected constructor(strategy: SerializeStrategy<K, V>, comparator: ValueComparator<V>, option?: BPTreeConstructorOption);
75
+ protected constructor(rootTx: BPTreeTransaction<K, V> | null, mvccRoot: BPTreeMVCC<K, V>, mvcc: BPTreeMVCC<K, V>, strategy: SerializeStrategy<K, V>, comparator: ValueComparator<V>, option?: BPTreeConstructorOption);
81
76
  private _createCachedRegexp;
82
- protected abstract _createNodeId(isLeaf: boolean): Deferred<string>;
83
- 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>>;
77
+ protected abstract _createNode(leaf: boolean, keys: string[] | K[][], values: V[], parent?: string | null, next?: string | null, prev?: string | null): Deferred<BPTreeUnknownNode<K, V>>;
84
78
  protected abstract _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>, value: V): Deferred<void>;
85
79
  protected abstract _insertInParent(node: BPTreeUnknownNode<K, V>, value: V, pointer: BPTreeUnknownNode<K, V>): Deferred<void>;
80
+ protected abstract _insertAtLeaf(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>, value: V): Deferred<void>;
86
81
  protected abstract getNode(id: string): Deferred<BPTreeUnknownNode<K, V>>;
87
82
  protected abstract insertableNode(value: V): Deferred<BPTreeLeafNode<K, V>>;
88
83
  protected abstract insertableNodeByPrimary(value: V): Deferred<BPTreeLeafNode<K, V>>;
@@ -91,9 +86,6 @@ export declare abstract class BPTree<K, V> {
91
86
  protected abstract insertableEndNode(value: V, direction: 1 | -1): Deferred<BPTreeLeafNode<K, V> | null>;
92
87
  protected abstract leftestNode(): Deferred<BPTreeLeafNode<K, V>>;
93
88
  protected abstract rightestNode(): Deferred<BPTreeLeafNode<K, V>>;
94
- protected abstract commitHeadBuffer(): Deferred<void>;
95
- protected abstract commitNodeCreateBuffer(): Deferred<void>;
96
- protected abstract commitNodeUpdateBuffer(): Deferred<void>;
97
89
  /**
98
90
  * After creating a tree instance, it must be called.
99
91
  * This method is used to initialize the stored tree and recover data.
@@ -150,30 +142,27 @@ export declare abstract class BPTree<K, V> {
150
142
  * @returns The return value is the total number of nodes updated.
151
143
  */
152
144
  abstract forceUpdate(id?: string): Deferred<number>;
145
+ /**
146
+ * Returns the user-defined data stored in the head of the tree.
147
+ */
148
+ abstract getHeadData(): Deferred<SerializableData>;
149
+ /**
150
+ * Commits the transaction and returns the result.
151
+ * @param label The label of the transaction.
152
+ */
153
+ abstract commit(label?: string): Deferred<TransactionResult<string, BPTreeNode<K, V>>>;
154
+ /**
155
+ * Rolls back the transaction and returns the result.
156
+ */
157
+ abstract rollback(): TransactionResult<string, BPTreeNode<K, V>>;
153
158
  protected ensureValues(v: V | V[]): V[];
154
159
  protected lowestValue(v: V[]): V;
155
160
  protected highestValue(v: V[]): V;
156
161
  protected lowestPrimaryValue(v: V[]): V;
157
162
  protected highestPrimaryValue(v: V[]): V;
158
- protected _insertAtLeaf(node: BPTreeLeafNode<K, V>, key: K, value: V): Deferred<void>;
159
- protected bufferForNodeCreate(node: BPTreeUnknownNode<K, V>): Deferred<void>;
160
- protected bufferForNodeUpdate(node: BPTreeUnknownNode<K, V>): Deferred<void>;
161
- protected bufferForNodeDelete(node: BPTreeUnknownNode<K, V>): Deferred<void>;
162
- /**
163
- * Returns the user-defined data stored in the head of the tree.
164
- * 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 `{}`.
165
- * @returns User-defined data stored in the head of the tree.
166
- */
167
- getHeadData(): SerializableData;
168
163
  /**
169
164
  * Clears all cached nodes.
170
165
  * This method is useful for freeing up memory when the tree is no longer needed.
171
166
  */
172
167
  clear(): void;
173
- registerTransaction(txId: number): void;
174
- unregisterTransaction(txId: number): void;
175
- pruneObsoleteNodes(): void;
176
- getObsoleteNode(id: string): BPTreeUnknownNode<K, V> | undefined;
177
- addObsoleteNode(node: BPTreeUnknownNode<K, V>, obsoleteAt: number): void;
178
- getNextTransactionId(): number;
179
168
  }
@@ -2,7 +2,6 @@ import type { BPTreeNode, Json, SerializeStrategyHead } from '../types';
2
2
  export declare abstract class SerializeStrategy<K, V> {
3
3
  readonly order: number;
4
4
  head: SerializeStrategyHead;
5
- protected lastCommittedTransactionId: number;
6
5
  constructor(order: number);
7
6
  /**
8
7
  * The rule for generating node IDs is set.
@@ -44,17 +43,6 @@ export declare abstract class SerializeStrategy<K, V> {
44
43
  * @param head This is the current state of the tree.
45
44
  */
46
45
  abstract writeHead(head: SerializeStrategyHead): void | Promise<void>;
47
- /**
48
- * Atomically updates the head with the new root and transaction ID.
49
- * Required for Optimistic Concurrency Control (CoW).
50
- * @param newRoot The new root ID to set.
51
- * @param newTxId The new transaction ID.
52
- */
53
- abstract compareAndSwapHead(newRoot: string, newTxId: number): void | Promise<void>;
54
- /**
55
- * Returns the last committed transaction ID (in-memory only).
56
- */
57
- abstract getLastCommittedTransactionId(): number | Promise<number>;
58
46
  /**
59
47
  * Retrieves the data stored in the tree.
60
48
  * If no value is stored in the tree, it stores a `defaultValue` and then returns that value.
@@ -1,4 +1,4 @@
1
- export type { BPTreeNode, BPTreeInternalNode, BPTreeLeafNode, BPTreeNodeKey, BPTreePair, BPTreeUnknownNode, BPTreeCondition, SerializeStrategyHead, SerializableData } from './types';
1
+ export type { BPTreeNode, BPTreeInternalNode, BPTreeLeafNode, BPTreeNodeKey, BPTreePair, BPTreeUnknownNode, BPTreeCondition, BPTreeTransactionResult, SerializeStrategyHead, SerializableData } from './types';
2
2
  export { ValueComparator, NumericComparator, StringComparator } from './base/ValueComparator';
3
3
  export { BPTreeSync } from './BPTreeSync';
4
4
  export { BPTreeSyncTransaction } from './transaction/BPTreeSyncTransaction';
@@ -1,52 +1,48 @@
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
- readonly obsoleteNodes: Map<string, BPTreeUnknownNode<K, V>>;
15
- private readonly originalNodes;
16
- private initialRootId;
17
- private transactionRootId;
18
- private transactionId;
19
- private initialLastCommittedTransactionId;
20
- constructor(baseTree: BPTreeAsyncBase<K, V>);
21
- /**
22
- * Initializes the transaction by capturing the current state of the tree.
23
- */
24
- initTransaction(): Promise<void>;
1
+ import type { AsyncBPTreeMVCC, BPTreeCondition, BPTreeConstructorOption, BPTreeLeafNode, BPTreeNode, BPTreeNodeKey, BPTreePair, BPTreeUnknownNode, SerializableData, SerializeStrategyHead } from '../types';
2
+ import { TransactionResult } from 'mvcc-api';
3
+ import { BPTreeTransaction } from '../base/BPTreeTransaction';
4
+ import { SerializeStrategyAsync } from '../SerializeStrategyAsync';
5
+ import { ValueComparator } from '../base/ValueComparator';
6
+ export declare class BPTreeAsyncTransaction<K, V> extends BPTreeTransaction<K, V> {
7
+ protected readonly rootTx: BPTreeAsyncTransaction<K, V>;
8
+ protected readonly mvccRoot: AsyncBPTreeMVCC<K, V>;
9
+ protected readonly mvcc: AsyncBPTreeMVCC<K, V>;
10
+ protected readonly strategy: SerializeStrategyAsync<K, V>;
11
+ protected readonly comparator: ValueComparator<V>;
12
+ protected readonly option: BPTreeConstructorOption;
13
+ constructor(rootTx: BPTreeAsyncTransaction<K, V> | null, mvccRoot: AsyncBPTreeMVCC<K, V>, mvcc: AsyncBPTreeMVCC<K, V>, strategy: SerializeStrategyAsync<K, V>, comparator: ValueComparator<V>, option?: BPTreeConstructorOption);
25
14
  protected getNode(id: string): Promise<BPTreeUnknownNode<K, V>>;
26
- protected bufferForNodeUpdate(node: BPTreeUnknownNode<K, V>): Promise<void>;
27
- protected bufferForNodeCreate(node: BPTreeUnknownNode<K, V>): Promise<void>;
28
- protected bufferForNodeDelete(node: BPTreeUnknownNode<K, V>): Promise<void>;
29
- private markPathDirty;
30
- protected _createNode(isLeaf: boolean, keys: string[] | K[][], values: V[], leaf?: boolean, parent?: string | null, next?: string | null, prev?: string | null): Promise<BPTreeUnknownNode<K, V>>;
31
- /**
32
- * Attempts to commit the transaction.
33
- * Uses Optimistic Locking (Compare-And-Swap) on the root node ID to detect conflicts.
34
- *
35
- * @param cleanup Whether to clean up obsolete nodes after commit. Defaults to true.
36
- * @returns A promise that resolves to the transaction result.
37
- */
38
- commit(cleanup?: boolean): Promise<BPTreeTransactionResult>;
39
15
  /**
40
- * Rolls back the transaction by clearing all buffered changes.
41
- * If cleanup is `true`, it also clears the transaction nodes.
42
- * @param cleanup Whether to clear the transaction nodes.
43
- * @returns The IDs of nodes that were created in this transaction.
16
+ * Create a new node with a unique ID.
44
17
  */
45
- rollback(cleanup?: boolean): Promise<string[]>;
46
- protected readLock<T>(fn: () => Promise<T>): Promise<T>;
47
- protected writeLock<T>(fn: () => Promise<T>): Promise<T>;
48
- protected commitHeadBuffer(): Promise<void>;
49
- protected commitNodeCreateBuffer(): Promise<void>;
50
- protected commitNodeUpdateBuffer(): Promise<void>;
51
- protected commitNodeDeleteBuffer(): Promise<void>;
18
+ protected _createNode(leaf: boolean, keys: string[] | K[][], values: V[], parent?: string | null, next?: string | null, prev?: string | null): Promise<BPTreeUnknownNode<K, V>>;
19
+ protected _updateNode(node: BPTreeUnknownNode<K, V>): Promise<void>;
20
+ protected _deleteNode(node: BPTreeUnknownNode<K, V>): Promise<void>;
21
+ protected _readHead(): Promise<SerializeStrategyHead | null>;
22
+ protected _writeHead(head: SerializeStrategyHead): Promise<void>;
23
+ protected _insertAtLeaf(node: BPTreeLeafNode<K, V>, key: K, value: V): Promise<void>;
24
+ protected _insertInParent(node: BPTreeUnknownNode<K, V>, value: V, pointer: BPTreeUnknownNode<K, V>): Promise<void>;
25
+ protected insertableNode(value: V): Promise<BPTreeLeafNode<K, V>>;
26
+ protected insertableNodeByPrimary(value: V): Promise<BPTreeLeafNode<K, V>>;
27
+ protected insertableRightestNodeByPrimary(value: V): Promise<BPTreeLeafNode<K, V>>;
28
+ protected insertableRightestEndNodeByPrimary(value: V): Promise<BPTreeLeafNode<K, V> | null>;
29
+ protected insertableEndNode(value: V, direction: 1 | -1): Promise<BPTreeLeafNode<K, V> | null>;
30
+ protected leftestNode(): Promise<BPTreeLeafNode<K, V>>;
31
+ protected rightestNode(): Promise<BPTreeLeafNode<K, V>>;
32
+ 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]>;
33
+ init(): Promise<void>;
34
+ exists(key: K, value: V): Promise<boolean>;
35
+ forceUpdate(id?: string): Promise<number>;
36
+ get(key: K): Promise<V | undefined>;
37
+ keysStream(condition: BPTreeCondition<V>, filterValues?: Set<K>, limit?: number): AsyncGenerator<K>;
38
+ whereStream(condition: BPTreeCondition<V>, limit?: number): AsyncGenerator<[K, V]>;
39
+ keys(condition: BPTreeCondition<V>, filterValues?: Set<K>): Promise<Set<K>>;
40
+ where(condition: BPTreeCondition<V>): Promise<BPTreePair<K, V>>;
41
+ insert(key: K, value: V): Promise<void>;
42
+ protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>): Promise<void>;
43
+ delete(key: K, value: V): Promise<void>;
44
+ getHeadData(): Promise<SerializableData>;
45
+ setHeadData(data: SerializableData): Promise<void>;
46
+ commit(label?: string): Promise<TransactionResult<string, BPTreeNode<K, V>>>;
47
+ rollback(): TransactionResult<string, BPTreeNode<K, V>>;
52
48
  }
@@ -0,0 +1,15 @@
1
+ import type { SerializeStrategyAsync } from '../SerializeStrategyAsync';
2
+ import type { BPTreeNode } from '../types';
3
+ import { AsyncMVCCStrategy } from 'mvcc-api';
4
+ /**
5
+ * MVCC Strategy for synchronous B+Tree operations.
6
+ * Uses node ID as key and node data as value.
7
+ */
8
+ export declare class BPTreeMVCCStrategyAsync<K, V, B extends BPTreeNode<K, V>> extends AsyncMVCCStrategy<string, B> {
9
+ private readonly strategy;
10
+ constructor(strategy: SerializeStrategyAsync<K, V>);
11
+ read(key: string): Promise<B>;
12
+ write(key: string, value: B): Promise<void>;
13
+ delete(key: string): Promise<void>;
14
+ exists(key: string): Promise<boolean>;
15
+ }
@@ -0,0 +1,15 @@
1
+ import type { SerializeStrategySync } from '../SerializeStrategySync';
2
+ import type { BPTreeNode } from '../types';
3
+ import { SyncMVCCStrategy } from 'mvcc-api';
4
+ /**
5
+ * MVCC Strategy for synchronous B+Tree operations.
6
+ * Uses node ID as key and node data as value.
7
+ */
8
+ export declare class BPTreeMVCCStrategySync<K, V, B extends BPTreeNode<K, V>> extends SyncMVCCStrategy<string, B> {
9
+ private readonly strategy;
10
+ constructor(strategy: SerializeStrategySync<K, V>);
11
+ read(key: string): B;
12
+ write(key: string, value: B): void;
13
+ delete(key: string): void;
14
+ exists(key: string): boolean;
15
+ }
@@ -1,52 +1,48 @@
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
- readonly obsoleteNodes: Map<string, BPTreeUnknownNode<K, V>>;
15
- private readonly originalNodes;
16
- private initialRootId;
17
- private transactionRootId;
18
- private transactionId;
19
- private initialLastCommittedTransactionId;
20
- constructor(baseTree: BPTreeSyncBase<K, V>);
21
- /**
22
- * Initializes the transaction by capturing the current state of the tree.
23
- */
24
- initTransaction(): void;
1
+ import type { BPTreeCondition, BPTreeConstructorOption, BPTreeLeafNode, BPTreeNode, BPTreeNodeKey, BPTreePair, BPTreeUnknownNode, SerializableData, SerializeStrategyHead, SyncBPTreeMVCC } from '../types';
2
+ import { TransactionResult } from 'mvcc-api';
3
+ import { BPTreeTransaction } from '../base/BPTreeTransaction';
4
+ import { SerializeStrategySync } from '../SerializeStrategySync';
5
+ import { ValueComparator } from '../base/ValueComparator';
6
+ export declare class BPTreeSyncTransaction<K, V> extends BPTreeTransaction<K, V> {
7
+ protected readonly rootTx: BPTreeSyncTransaction<K, V>;
8
+ protected readonly mvccRoot: SyncBPTreeMVCC<K, V>;
9
+ protected readonly mvcc: SyncBPTreeMVCC<K, V>;
10
+ protected readonly strategy: SerializeStrategySync<K, V>;
11
+ protected readonly comparator: ValueComparator<V>;
12
+ protected readonly option: BPTreeConstructorOption;
13
+ constructor(rootTx: BPTreeSyncTransaction<K, V>, mvccRoot: SyncBPTreeMVCC<K, V>, mvcc: SyncBPTreeMVCC<K, V>, strategy: SerializeStrategySync<K, V>, comparator: ValueComparator<V>, option?: BPTreeConstructorOption);
25
14
  protected getNode(id: string): BPTreeUnknownNode<K, V>;
26
- protected bufferForNodeUpdate(node: BPTreeUnknownNode<K, V>): void;
27
- protected bufferForNodeCreate(node: BPTreeUnknownNode<K, V>): void;
28
- protected bufferForNodeDelete(node: BPTreeUnknownNode<K, V>): void;
29
- private markPathDirty;
30
- protected _createNode(isLeaf: boolean, keys: string[] | K[][], values: V[], leaf?: boolean, parent?: string | null, next?: string | null, prev?: string | null): BPTreeUnknownNode<K, V>;
31
- /**
32
- * Attempts to commit the transaction.
33
- * Uses Optimistic Locking (Compare-And-Swap) on the root node ID to detect conflicts.
34
- *
35
- * @param cleanup Whether to clean up obsolete nodes after commit. Defaults to true.
36
- * @returns The transaction result.
37
- */
38
- commit(cleanup?: boolean): BPTreeTransactionResult;
39
15
  /**
40
- * Rolls back the transaction by clearing all buffered changes.
41
- * If cleanup is `true`, it also clears the transaction nodes.
42
- * @param cleanup Whether to clear the transaction nodes.
43
- * @returns The IDs of nodes that were created in this transaction.
16
+ * Create a new node with a unique ID.
44
17
  */
45
- rollback(cleanup?: boolean): string[];
46
- protected readLock<T>(fn: () => T): T;
47
- protected writeLock<T>(fn: () => T): T;
48
- protected commitHeadBuffer(): void;
49
- protected commitNodeCreateBuffer(): void;
50
- protected commitNodeUpdateBuffer(): void;
51
- protected commitNodeDeleteBuffer(): void;
18
+ protected _createNode(leaf: boolean, keys: string[] | K[][], values: V[], parent?: string | null, next?: string | null, prev?: string | null): BPTreeUnknownNode<K, V>;
19
+ protected _updateNode(node: BPTreeUnknownNode<K, V>): void;
20
+ protected _deleteNode(node: BPTreeUnknownNode<K, V>): void;
21
+ protected _readHead(): SerializeStrategyHead | null;
22
+ protected _writeHead(head: SerializeStrategyHead): void;
23
+ protected _insertAtLeaf(node: BPTreeLeafNode<K, V>, key: K, value: V): void;
24
+ protected _insertInParent(node: BPTreeUnknownNode<K, V>, value: V, pointer: BPTreeUnknownNode<K, V>): void;
25
+ protected insertableNode(value: V): BPTreeLeafNode<K, V>;
26
+ protected insertableNodeByPrimary(value: V): BPTreeLeafNode<K, V>;
27
+ protected insertableRightestNodeByPrimary(value: V): BPTreeLeafNode<K, V>;
28
+ protected insertableRightestEndNodeByPrimary(value: V): BPTreeLeafNode<K, V> | null;
29
+ protected insertableEndNode(value: V, direction: 1 | -1): BPTreeLeafNode<K, V> | null;
30
+ protected leftestNode(): BPTreeLeafNode<K, V>;
31
+ protected rightestNode(): BPTreeLeafNode<K, V>;
32
+ 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]>;
33
+ init(): void;
34
+ exists(key: K, value: V): boolean;
35
+ forceUpdate(id?: string): number;
36
+ get(key: K): V | undefined;
37
+ keysStream(condition: BPTreeCondition<V>, filterValues?: Set<K>, limit?: number): Generator<K>;
38
+ whereStream(condition: BPTreeCondition<V>, limit?: number): Generator<[K, V]>;
39
+ keys(condition: BPTreeCondition<V>, filterValues?: Set<K>): Set<K>;
40
+ where(condition: BPTreeCondition<V>): BPTreePair<K, V>;
41
+ insert(key: K, value: V): void;
42
+ protected _deleteEntry(node: BPTreeUnknownNode<K, V>, key: BPTreeNodeKey<K>): void;
43
+ delete(key: K, value: V): void;
44
+ getHeadData(): SerializableData;
45
+ setHeadData(data: SerializableData): void;
46
+ commit(label?: string): TransactionResult<string, BPTreeNode<K, V>>;
47
+ rollback(): TransactionResult<string, BPTreeNode<K, V>>;
52
48
  }
@@ -1,3 +1,6 @@
1
+ import type { SyncMVCCTransaction, AsyncMVCCTransaction, MVCCTransaction, MVCCStrategy } from 'mvcc-api';
2
+ import { BPTreeMVCCStrategyAsync } from '../transaction/BPTreeMVCCStrategyAsync';
3
+ import { BPTreeMVCCStrategySync } from '../transaction/BPTreeMVCCStrategySync';
1
4
  export type Sync<T> = T;
2
5
  export type Async<T> = Promise<T>;
3
6
  export type Deferred<T> = Sync<T> | Async<T>;
@@ -78,6 +81,8 @@ export interface BPTreeTransactionResult {
78
81
  createdIds: string[];
79
82
  /** IDs of nodes that became obsolete and can be deleted after a successful commit. */
80
83
  obsoleteIds: string[];
84
+ /** Error message if the transaction failed. */
85
+ error?: string;
81
86
  }
82
87
  export type SerializableData = Record<string, Json>;
83
88
  export interface SerializeStrategyHead {
@@ -85,6 +90,9 @@ export interface SerializeStrategyHead {
85
90
  order: number;
86
91
  data: SerializableData;
87
92
  }
93
+ export type BPTreeMVCC<K, V> = MVCCTransaction<MVCCStrategy<string, BPTreeNode<K, V>>, string, BPTreeNode<K, V>>;
94
+ export type SyncBPTreeMVCC<K, V> = SyncMVCCTransaction<BPTreeMVCCStrategySync<K, V, BPTreeNode<K, V>>, string, BPTreeNode<K, V>>;
95
+ export type AsyncBPTreeMVCC<K, V> = AsyncMVCCTransaction<BPTreeMVCCStrategyAsync<K, V, BPTreeNode<K, V>>, string, BPTreeNode<K, V>>;
88
96
  export type Primitive = string | number | null | boolean;
89
97
  export type Json = Primitive | Primitive[] | Json[] | {
90
98
  [key: string]: Json;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "serializable-bptree",
3
- "version": "7.0.3",
3
+ "version": "8.0.0",
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",
@@ -16,7 +16,7 @@
16
16
  "dist/**/*"
17
17
  ],
18
18
  "scripts": {
19
- "test": "jest",
19
+ "test": "jest --runInBand",
20
20
  "build": "node build/index.js && tsc"
21
21
  },
22
22
  "author": "izure <admin@izure.org>",
@@ -44,6 +44,7 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "cache-entanglement": "^1.7.1",
47
+ "mvcc-api": "^1.2.8",
47
48
  "ryoiki": "^1.2.0"
48
49
  }
49
50
  }
@@ -1,41 +0,0 @@
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
- }
@@ -1,39 +0,0 @@
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,18 +0,0 @@
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(newRoot: string, newTxId: number): Promise<void>;
14
- getLastCommittedTransactionId(): Promise<number>;
15
- getHeadData(key: string, defaultValue: Json): Promise<Json>;
16
- setHeadData(key: string, data: Json): Promise<void>;
17
- autoIncrement(key: string, defaultValue: number): Promise<number>;
18
- }
@@ -1,18 +0,0 @@
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(newRoot: string, newTxId: number): void;
14
- getLastCommittedTransactionId(): number;
15
- getHeadData(key: string, defaultValue: Json): Json;
16
- setHeadData(key: string, data: Json): void;
17
- autoIncrement(key: string, defaultValue: number): number;
18
- }