UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

192 lines (191 loc) 5.24 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const comparison = require("../utils/comparison.cjs"); const btree = require("../utils/btree.cjs"); const baseIndex = require("./base-index.cjs"); class BTreeIndex extends baseIndex.BaseIndex { constructor(id, expression, name, options) { super(id, expression, name, options); this.supportedOperations = /* @__PURE__ */ new Set([ `eq`, `gt`, `gte`, `lt`, `lte`, `in` ]); this.valueMap = /* @__PURE__ */ new Map(); this.indexedKeys = /* @__PURE__ */ new Set(); this.compareFn = comparison.ascComparator; this.compareFn = (options == null ? void 0 : options.compareFn) ?? comparison.ascComparator; this.orderedEntries = new btree.BTree(this.compareFn); } initialize(_options) { } /** * Adds a value to the index */ add(key, item) { let indexedValue; try { indexedValue = this.evaluateIndexExpression(item); } catch (error) { throw new Error( `Failed to evaluate index expression for key ${key}: ${error}` ); } if (this.valueMap.has(indexedValue)) { this.valueMap.get(indexedValue).add(key); } else { const keySet = /* @__PURE__ */ new Set([key]); this.valueMap.set(indexedValue, keySet); this.orderedEntries.set(indexedValue, void 0); } this.indexedKeys.add(key); this.updateTimestamp(); } /** * Removes a value from the index */ remove(key, item) { let indexedValue; try { indexedValue = this.evaluateIndexExpression(item); } catch (error) { console.warn( `Failed to evaluate index expression for key ${key} during removal:`, error ); return; } if (this.valueMap.has(indexedValue)) { const keySet = this.valueMap.get(indexedValue); keySet.delete(key); if (keySet.size === 0) { this.valueMap.delete(indexedValue); this.orderedEntries.delete(indexedValue); } } this.indexedKeys.delete(key); this.updateTimestamp(); } /** * Updates a value in the index */ update(key, oldItem, newItem) { this.remove(key, oldItem); this.add(key, newItem); } /** * Builds the index from a collection of entries */ build(entries) { this.clear(); for (const [key, item] of entries) { this.add(key, item); } } /** * Clears all data from the index */ clear() { this.orderedEntries.clear(); this.valueMap.clear(); this.indexedKeys.clear(); this.updateTimestamp(); } /** * Performs a lookup operation */ lookup(operation, value) { const startTime = performance.now(); let result; switch (operation) { case `eq`: result = this.equalityLookup(value); break; case `gt`: result = this.rangeQuery({ from: value, fromInclusive: false }); break; case `gte`: result = this.rangeQuery({ from: value, fromInclusive: true }); break; case `lt`: result = this.rangeQuery({ to: value, toInclusive: false }); break; case `lte`: result = this.rangeQuery({ to: value, toInclusive: true }); break; case `in`: result = this.inArrayLookup(value); break; default: throw new Error(`Operation ${operation} not supported by BTreeIndex`); } this.trackLookup(startTime); return result; } /** * Gets the number of indexed keys */ get keyCount() { return this.indexedKeys.size; } // Public methods for backward compatibility (used by tests) /** * Performs an equality lookup */ equalityLookup(value) { return new Set(this.valueMap.get(value) ?? []); } /** * Performs a range query with options * This is more efficient for compound queries like "WHERE a > 5 AND a < 10" */ rangeQuery(options = {}) { const { from, to, fromInclusive = true, toInclusive = true } = options; const result = /* @__PURE__ */ new Set(); const fromKey = from ?? this.orderedEntries.minKey(); const toKey = to ?? this.orderedEntries.maxKey(); this.orderedEntries.forRange( fromKey, toKey, toInclusive, (indexedValue, _) => { if (!fromInclusive && this.compareFn(indexedValue, from) === 0) { return; } const keys = this.valueMap.get(indexedValue); if (keys) { keys.forEach((key) => result.add(key)); } } ); return result; } /** * Performs an IN array lookup */ inArrayLookup(values) { const result = /* @__PURE__ */ new Set(); for (const value of values) { const keys = this.valueMap.get(value); if (keys) { keys.forEach((key) => result.add(key)); } } return result; } // Getter methods for testing compatibility get indexedKeysSet() { return this.indexedKeys; } get orderedEntriesArray() { return this.orderedEntries.keysArray().map((key) => [key, this.valueMap.get(key) ?? /* @__PURE__ */ new Set()]); } get valueMapData() { return this.valueMap; } } exports.BTreeIndex = BTreeIndex; //# sourceMappingURL=btree-index.cjs.map