UNPKG

@tanstack/db-ivm

Version:

Incremental View Maintenance for TanStack DB based on Differential Dataflow

157 lines (156 loc) 6.29 kB
"use strict"; var __typeError = (msg) => { throw TypeError(msg); }; var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value); var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value); var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method); var _valueIndex, _hashIndex, _Index_instances, entries_fn, entriesIterators_fn; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const multiset = require("./multiset.cjs"); const hashIndex = require("./hashIndex.cjs"); const valueIndex = require("./valueIndex.cjs"); const utils = require("./utils.cjs"); class Index { constructor() { __privateAdd(this, _Index_instances); /* * This is a hybrid Index that composes a ValueIndex and a HashIndex. * Keys that have only one value are stored in the ValueIndex. * Keys that have multiple values are stored in the HashIndex, the hash distinguishes between the values. * This reduces the amount of hashes we need to compute since often times only a small portion of the keys are updated * so we don't have to hash the keys that are never updated. * * Note: The `valueIndex` and `hashIndex` have disjoint keys. * When a key that has only one value gets a new distinct value, * it is added to the `hashIndex` and removed from the `valueIndex` and vice versa. */ __privateAdd(this, _valueIndex); __privateAdd(this, _hashIndex); __privateSet(this, _valueIndex, new valueIndex.ValueIndex()); __privateSet(this, _hashIndex, new hashIndex.HashIndex()); } toString(indent = false) { return `Index( ${__privateGet(this, _valueIndex).toString(indent)}, ${__privateGet(this, _hashIndex).toString(indent)} )`; } get(key) { if (__privateGet(this, _valueIndex).has(key)) { return [__privateGet(this, _valueIndex).get(key)]; } return __privateGet(this, _hashIndex).get(key); } getMultiplicity(key, value) { if (__privateGet(this, _valueIndex).has(key)) { return __privateGet(this, _valueIndex).getMultiplicity(key); } return __privateGet(this, _hashIndex).getMultiplicity(key, value); } has(key) { return __privateGet(this, _valueIndex).has(key) || __privateGet(this, _hashIndex).has(key); } get size() { return __privateGet(this, _valueIndex).size + __privateGet(this, _hashIndex).size; } addValue(key, value) { const containedInValueIndex = __privateGet(this, _valueIndex).has(key); const containedInHashIndex = __privateGet(this, _hashIndex).has(key); if (containedInHashIndex && containedInValueIndex) { throw new Error( `Key ${key} is contained in both the value index and the hash index. This should never happen because they should have disjoint keysets.` ); } if (!containedInValueIndex && !containedInHashIndex) { __privateGet(this, _valueIndex).addValue(key, value); return; } if (containedInValueIndex) { try { __privateGet(this, _valueIndex).addValue(key, value); } catch { const existingValue = __privateGet(this, _valueIndex).get(key); __privateGet(this, _valueIndex).delete(key); __privateGet(this, _hashIndex).addValue(key, existingValue); __privateGet(this, _hashIndex).addValue(key, value); } return; } if (containedInHashIndex) { const singleRemainingValue = __privateGet(this, _hashIndex).addValue(key, value); if (singleRemainingValue) { __privateGet(this, _hashIndex).delete(key); __privateGet(this, _valueIndex).addValue(key, singleRemainingValue); } return; } } append(other) { var _a; for (const [key, value] of __privateMethod(_a = other, _Index_instances, entries_fn).call(_a)) { this.addValue(key, value); } } join(other) { var _a; const result = []; if (this.size <= other.size) { for (const [key, valueIt] of __privateMethod(this, _Index_instances, entriesIterators_fn).call(this)) { if (!other.has(key)) continue; const otherValues = other.get(key); for (const [val1, mul1] of valueIt) { for (const [val2, mul2] of otherValues) { if (mul1 !== 0 && mul2 !== 0) { result.push([[key, [val1, val2]], mul1 * mul2]); } } } } } else { for (const [key, otherValueIt] of __privateMethod(_a = other, _Index_instances, entriesIterators_fn).call(_a)) { if (!this.has(key)) continue; const values = this.get(key); for (const [val2, mul2] of otherValueIt) { for (const [val1, mul1] of values) { if (mul1 !== 0 && mul2 !== 0) { result.push([[key, [val1, val2]], mul1 * mul2]); } } } } } return new multiset.MultiSet(result); } } _valueIndex = new WeakMap(); _hashIndex = new WeakMap(); _Index_instances = new WeakSet(); /** * This returns an iterator that iterates over all key-value pairs. * @returns An iterable of all key-value pairs (and their multiplicities) in the index. */ entries_fn = function() { return utils.concatIterable( __privateGet(this, _valueIndex).entries(), __privateGet(this, _hashIndex).entriesIterator() ); }; entriesIterators_fn = function* () { for (const [key, [value, multiplicity]] of __privateGet(this, _valueIndex).entries()) { yield [key, /* @__PURE__ */ new Map([[value, multiplicity]])]; } for (const [key, valueMap] of __privateGet(this, _hashIndex).entries()) { yield [ key, utils.mapIterable(valueMap, ([_hash, [value, multiplicity]]) => [ value, multiplicity ]) ]; } }; exports.Index = Index; //# sourceMappingURL=indexes.cjs.map