deno.land / x / pg_mem@2.8.1 / transforms / and-filter.ts
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273import { _ISelection, _IIndex, _ITable, _Transaction, _Explainer, _SelectExplanation, Stats, nil } from '../interfaces-private.ts';import { FilterBase } from './transform-base.ts';import { SeqScanFilter } from './seq-scan.ts';
export class AndFilter<T = any> extends FilterBase<T> {
get index(): _IIndex<T> | nil { return null; }
private prevEntropy?: { t: _Transaction; ret: number };
entropy(t: _Transaction) { // just a bit of caching if (t === this.prevEntropy?.t) { return this.prevEntropy.ret; } const { best } = this.plan(t); const ret = best.entropy(t); this.prevEntropy = { ret, t, }; return ret; }
hasItem(value: T, t: _Transaction): boolean { return this.filters.every(x => x.hasItem(value, t)); }
constructor(private filters: _ISelection<T>[]) { super(filters.find(x => !(x instanceof SeqScanFilter)) ?? filters[0]); if (filters.some(f => f.columns !== this.base.columns)) { throw new Error('Column set mismatch'); } }
private plan(t: _Transaction) { const sorted = [...this.filters] .sort((a, b) => a.entropy(t) > b.entropy(t) ? 1 : -1); const [best] = sorted.splice(0, 1); return { best, sorted }; }
stats(t: _Transaction): Stats | null { return null; }
*enumerate(t: _Transaction): Iterable<T> { // sort them so the most restrictive filter is first const { best, sorted } = this.plan(t) for (const item of best.enumerate(t)) { if (!sorted.every(x => x.hasItem(item, t))) { continue; } yield item; } }
explain(e: _Explainer): _SelectExplanation { const { best, sorted } = this.plan(e.transaction); return { id: e.idFor(this), _: 'and', enumerate: best.explain(e), andCheck: sorted.map(x => x.explain(e)), }; }
}
Version Info