UNPKG

arquero

Version:

Query processing and transformation of array-backed data tables.

93 lines (76 loc) 2.19 kB
import { ascending } from '../../util/ascending.js'; import { bisector } from '../../util/bisector.js'; import { concat } from '../../util/concat.js'; import { unroll } from '../../util/unroll.js'; const bisect = bisector(ascending); export function windowState(data, frame, adjust, ops, aggrs) { let rows, peer, cells, result, key; const isPeer = index => peer[index - 1] === peer[index]; const numOps = ops.length; const numAgg = aggrs.length; const evaluate = ops.length ? unroll( ['w', 'r', 'k'], '{' + concat(ops, (_, i) => `r[_${i}.id][k]=_${i}.value(w,_${i}.get);`) + '}', ops ) : () => {}; const w = { i0: 0, i1: 0, index: 0, size: 0, peer: isPeer, init(partition, peers, results, group) { w.index = w.i0 = w.i1 = 0; w.size = peers.length; rows = partition; peer = peers; result = results; key = group; // initialize aggregates cells = aggrs ? aggrs.map(aggr => aggr.init()) : null; // initialize window ops for (let i = 0; i < numOps; ++i) { ops[i].init(); } return w; }, value(index, get) { return get(rows[index], data); }, step(idx) { const [f0, f1] = frame; const n = w.size; const p0 = w.i0; const p1 = w.i1; w.i0 = f0 != null ? Math.max(0, idx - Math.abs(f0)) : 0; w.i1 = f1 != null ? Math.min(n, idx + Math.abs(f1) + 1) : n; w.index = idx; if (adjust) { if (w.i0 > 0 && isPeer(w.i0)) { w.i0 = bisect.left(peer, peer[w.i0]); } if (w.i1 < n && isPeer(w.i1)) { w.i1 = bisect.right(peer, peer[w.i1 - 1]); } } // evaluate aggregates for (let i = 0; i < numAgg; ++i) { const aggr = aggrs[i]; const cell = cells[i]; for (let j = p0; j < w.i0; ++j) { aggr.rem(cell, rows[j], data); } for (let j = p1; j < w.i1; ++j) { aggr.add(cell, rows[j], data); } aggr.write(cell, result, key); } // evaluate window ops evaluate(w, result, key); return result; } }; return w; }