import type { TransactionEntry, TransactionResult } from 'mvcc-api'; import type { BPTreeCondition, BPTreeConstructorOption, BPTreeUnknownNode, Deferred, BPTreeLeafNode, BPTreeNodeKey, BPTreePair, SerializableData, BPTreeNode, BPTreeMVCC, BPTreeSearchOption, IBPTree } from '../types'; import { ValueComparator } from './ValueComparator'; import { SerializeStrategy } from './SerializeStrategy'; export declare abstract class BPTreeTransaction implements IBPTree { protected readonly _cachedRegexp: Map; protected readonly rootTx: BPTreeTransaction; protected readonly mvccRoot: BPTreeMVCC; protected readonly mvcc: BPTreeMVCC; protected readonly strategy: SerializeStrategy; protected readonly comparator: ValueComparator; protected readonly option: BPTreeConstructorOption; protected order: number; protected rootId: string; protected isInitialized: boolean; protected isDestroyed: boolean; protected readonly verifierMap: Record, (nodeValue: V, value: V | V[]) => boolean>; protected readonly searchConfigs: Record, Record<'asc' | 'desc', { start: (tx: BPTreeTransaction, v: V[]) => Deferred | null>; end: (tx: BPTreeTransaction, v: V[]) => Deferred | null>; direction: 1 | -1; earlyTerminate: boolean; }>>; /** * Priority map for condition types. * Higher value = higher selectivity (fewer expected results). * Used by `chooseDriver` to select the most selective index. */ protected static readonly conditionPriority: Record, number>; /** * Selects the best driver tree from multiple tree/condition pairs. * Uses rule-based optimization to choose the tree with highest estimated selectivity. * * @param candidates Array of { tree, condition } pairs to evaluate * @returns The candidate with highest priority condition, or null if empty * * @example * ```typescript * const driver = BPTreeSync.chooseDriver([ * { tree: idxId, condition: { equal: 100 } }, * { tree: idxAge, condition: { gt: 20 } } * ]) * // Returns { tree: idxId, condition: { equal: 100 } } because 'equal' has higher priority * ``` */ static ChooseDriver(candidates: Array<{ tree: T; condition: BPTreeCondition; }>): { tree: T; condition: BPTreeCondition; } | null; /** * Checks for conflicts between multiple transactions. * * @param transactions Array of BPTreeTransaction instances to check * @returns An array of keys that are in conflict. Empty array if no conflicts. */ static CheckConflicts(transactions: BPTreeTransaction[]): string[]; abstract getRootNode(): Deferred>; getRootId(): string; getOrder(): number; verify(nodeValue: V, condition: BPTreeCondition): boolean; /** * Inserts a key-value pair into an already-cloned leaf node in-place. * Unlike _insertAtLeaf, this does NOT clone or update the node via MVCC. * Used by batchInsert to batch multiple insertions with a single clone/update. * @returns true if the leaf was modified, false if the key already exists. */ protected _insertValueIntoLeaf(leaf: BPTreeLeafNode, key: K, value: V): boolean; protected _cloneNode>(node: T): T; /** * Resolves the best start/end configuration by independently examining * all conditions. Selects the tightest lower bound for start and the * tightest upper bound for end (in asc; reversed for desc). * * @param condition The condition to analyze. * @param order The sort order ('asc' or 'desc'). * @returns The resolved start/end keys, values, and traversal direction. */ resolveStartEndConfigs(condition: BPTreeCondition, order: 'asc' | 'desc'): { startKey: keyof BPTreeCondition | null; endKey: keyof BPTreeCondition | null; startValues: V[]; endValues: V[]; direction: 1 | -1; }; private static readonly _lowerBoundKeys; private static readonly _upperBoundKeys; private static readonly _multiValueKeys; protected constructor(rootTx: BPTreeTransaction | null, mvccRoot: BPTreeMVCC, mvcc: BPTreeMVCC, strategy: SerializeStrategy, comparator: ValueComparator, option?: BPTreeConstructorOption); protected abstract _createNode(leaf: boolean, keys: string[] | K[][], values: V[], parent?: string | null, next?: string | null, prev?: string | null): Deferred>; protected abstract _deleteEntry(node: BPTreeUnknownNode, key: BPTreeNodeKey): Deferred>; protected abstract _insertInParent(node: BPTreeUnknownNode, value: V, pointer: BPTreeUnknownNode): Deferred; protected abstract _insertAtLeaf(node: BPTreeUnknownNode, key: BPTreeNodeKey, value: V): Deferred>; protected abstract getNode(id: string): Deferred>; protected abstract locateLeaf(value: V): Deferred>; protected abstract findLowerBoundLeaf(value: V): Deferred>; protected abstract findUpperBoundLeaf(value: V): Deferred>; protected abstract findOuterBoundaryLeaf(value: V, direction: 1 | -1): Deferred | null>; protected abstract leftestNode(): Deferred>; protected abstract rightestNode(): Deferred>; abstract init(): Deferred; abstract reload(): Deferred; abstract get(key: K): Deferred; abstract keysStream(condition: BPTreeCondition, options?: BPTreeSearchOption): AsyncGenerator | Generator; abstract whereStream(condition: BPTreeCondition, options?: BPTreeSearchOption): AsyncGenerator<[K, V]> | Generator<[K, V]>; abstract keys(condition: BPTreeCondition, options?: BPTreeSearchOption): Deferred>; abstract where(condition: BPTreeCondition, options?: BPTreeSearchOption): Deferred>; abstract insert(key: K, value: V): Deferred; abstract batchInsert(entries: [K, V][]): Deferred; abstract bulkLoad(entries: [K, V][]): Deferred; abstract delete(key: K, value?: V): Deferred; abstract batchDelete(entries: [K, V?][]): Deferred; abstract exists(key: K, value: V): Deferred; abstract setHeadData(data: SerializableData): Deferred; abstract getHeadData(): Deferred; /** * Commits the transaction and returns the result. * @param label The label of the transaction. */ abstract commit(label?: string): Deferred>>; /** * Rolls back the transaction and returns the result. */ abstract rollback(): Deferred>>; protected ensureValues(v: V | V[]): V[]; protected lowestValue(v: V[]): V; protected highestValue(v: V[]): V; protected lowestPrimaryValue(v: V[]): V; protected highestPrimaryValue(v: V[]): V; /** * Returns the result entries of the transaction. * @returns Returns the node entries that will be created, updated, and deleted by this transaction. */ getResultEntries(): { created: TransactionEntry>[]; updated: TransactionEntry>[]; deleted: TransactionEntry>[]; }; protected _clearCache(): void; protected _resetForReload(): void; /** * Clears all cached nodes. * This method is useful for freeing up memory when the tree is no longer needed. */ clear(): void; protected _clearInternal(): void; protected _binarySearchValues(values: V[], target: V, usePrimary?: boolean, upperBound?: boolean): { index: number; found: boolean; }; }