Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

vega-crossfilter

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vega-crossfilter - npm Package Compare versions

Comparing version 4.0.2 to 4.0.3

751

build/vega-crossfilter.js
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-array'), require('vega-dataflow'), require('vega-util')) :
typeof define === 'function' && define.amd ? define(['exports', 'd3-array', 'vega-dataflow', 'vega-util'], factory) :
(global = global || self, factory((global.vega = global.vega || {}, global.vega.transforms = {}), global.d3, global.vega, global.vega));
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.vega = global.vega || {}, global.vega.transforms = {}), global.d3, global.vega, global.vega));
}(this, (function (exports, d3Array, vegaDataflow, vegaUtil) { 'use strict';
function array8(n) { return new Uint8Array(n); }
const array8 = n => new Uint8Array(n);
function array16(n) { return new Uint16Array(n); }
const array16 = n => new Uint16Array(n);
function array32(n) { return new Uint32Array(n); }
const array32 = n => new Uint32Array(n);

@@ -18,3 +18,3 @@ /**

var width = 8,
let width = 8,
data = [],

@@ -26,11 +26,8 @@ seen = array32(0),

return {
data: () => data,
data: function() { return data; },
seen: () => (seen = lengthen(seen, data.length)),
seen: function() {
return (seen = lengthen(seen, data.length));
},
add: function(array) {
for (var i=0, j=data.length, n=array.length, t; i<n; ++i) {
add(array) {
for (let i=0, j=data.length, n=array.length, t; i<n; ++i) {
t = array[i];

@@ -42,4 +39,4 @@ t._index = j++;

remove: function(num, map) { // map: index -> boolean (true => remove)
var n = data.length,
remove(num, map) { // map: index -> boolean (true => remove)
let n = data.length,
copy = Array(n - num),

@@ -74,20 +71,19 @@ reindex = data, // reuse old data array for index map

size: function() { return data.length; },
size: () => data.length,
curr: function() { return curr; },
curr: () => curr,
prev: function() { return prev; },
prev: () => prev,
reset: function(k) { prev[k] = curr[k]; },
reset: k => prev[k] = curr[k],
all: function() {
return width < 0x101 ? 0xff : width < 0x10001 ? 0xffff : 0xffffffff;
},
all: () =>
width < 0x101 ? 0xff : width < 0x10001 ? 0xffff : 0xffffffff,
set: function(k, one) { curr[k] |= one; },
set(k, one) { curr[k] |= one; },
clear: function(k, one) { curr[k] &= ~one; },
clear(k, one) { curr[k] &= ~one; },
resize: function(n, m) {
var k = curr.length;
resize(n, m) {
const k = curr.length;
if (n > k || m > width) {

@@ -110,3 +106,5 @@ width = Math.max(m, width);

function array(n, m, array) {
var copy = (m < 0x101 ? array8 : m < 0x10001 ? array16 : array32)(n);
const copy = (m < 0x101 ? array8
: m < 0x10001 ? array16
: array32)(n);
if (array) copy.set(array);

@@ -117,3 +115,3 @@ return copy;

function Dimension(index, i, query) {
var bit = (1 << i);
const bit = (1 << i);

@@ -128,4 +126,4 @@ return {

onAdd: function(added, curr) {
var dim = this,
onAdd(added, curr) {
let dim = this,
range = dim.bisect(dim.range, added.value),

@@ -148,3 +146,3 @@ idx = added.index,

function SortedIndex() {
var index = array32(0),
let index = array32(0),
value = [],

@@ -156,3 +154,3 @@ size = 0;

var n0 = size,
let n0 = size,
n1 = data.length,

@@ -189,3 +187,3 @@ addv = Array(n1),

// map: index -> remove
var n = size,
let n = size,
idx, i, j;

@@ -209,3 +207,3 @@

function reindex(map) {
for (var i=0, n=size; i<n; ++i) {
for (let i=0, n=size; i<n; ++i) {
index[i] = map[index[i]];

@@ -216,3 +214,3 @@ }

function bisect(range, array) {
var n;
let n;
if (array) {

@@ -235,4 +233,4 @@ n = array.length;

reindex: reindex,
index: function() { return index; },
size: function() { return size; }
index: () => index,
size: () => size
};

@@ -242,5 +240,5 @@ }

function sort(values, index) {
values.sort.call(index, function(a, b) {
var x = values[a],
y = values[b];
values.sort.call(index, (a, b) => {
const x = values[a],
y = values[b];
return x < y ? -1 : x > y ? 1 : 0;

@@ -252,3 +250,3 @@ });

function merge(base, value0, index0, n0, value1, index1, n1, value, index) {
var i0 = 0, i1 = 0, i;
let i0 = 0, i1 = 0, i;

@@ -299,358 +297,358 @@ for (i=0; i0 < n0 && i1 < n1; ++i) {

var prototype = vegaUtil.inherits(CrossFilter, vegaDataflow.Transform);
vegaUtil.inherits(CrossFilter, vegaDataflow.Transform, {
transform(_, pulse) {
if (!this._dims) {
return this.init(_, pulse);
} else {
var init = _.modified('fields')
|| _.fields.some(f => pulse.modified(f.fields));
prototype.transform = function(_, pulse) {
if (!this._dims) {
return this.init(_, pulse);
} else {
var init = _.modified('fields')
|| _.fields.some(function(f) { return pulse.modified(f.fields); });
return init
? this.reinit(_, pulse)
: this.eval(_, pulse);
}
},
return init
? this.reinit(_, pulse)
: this.eval(_, pulse);
}
};
init(_, pulse) {
let fields = _.fields,
query = _.query,
indices = this._indices = {},
dims = this._dims = [],
m = query.length,
i = 0, key, index;
prototype.init = function(_, pulse) {
var fields = _.fields,
query = _.query,
indices = this._indices = {},
dims = this._dims = [],
m = query.length,
i = 0, key, index;
// instantiate indices and dimensions
for (; i<m; ++i) {
key = fields[i].fname;
index = indices[key] || (indices[key] = SortedIndex());
dims.push(Dimension(index, i, query[i]));
}
// instantiate indices and dimensions
for (; i<m; ++i) {
key = fields[i].fname;
index = indices[key] || (indices[key] = SortedIndex());
dims.push(Dimension(index, i, query[i]));
}
return this.eval(_, pulse);
},
return this.eval(_, pulse);
};
reinit(_, pulse) {
let output = pulse.materialize().fork(),
fields = _.fields,
query = _.query,
indices = this._indices,
dims = this._dims,
bits = this.value,
curr = bits.curr(),
prev = bits.prev(),
all = bits.all(),
out = (output.rem = output.add),
mod = output.mod,
m = query.length,
adds = {}, add, index, key,
mods, remMap, modMap, i, n, f;
prototype.reinit = function(_, pulse) {
var output = pulse.materialize().fork(),
fields = _.fields,
query = _.query,
indices = this._indices,
dims = this._dims,
bits = this.value,
curr = bits.curr(),
prev = bits.prev(),
all = bits.all(),
out = (output.rem = output.add),
mod = output.mod,
m = query.length,
adds = {}, add, index, key,
mods, remMap, modMap, i, n, f;
// set prev to current state
prev.set(curr);
// set prev to current state
prev.set(curr);
// if pulse has remove tuples, process them first
if (pulse.rem.length) {
remMap = this.remove(_, pulse, output);
}
// if pulse has remove tuples, process them first
if (pulse.rem.length) {
remMap = this.remove(_, pulse, output);
}
// if pulse has added tuples, add them to state
if (pulse.add.length) {
bits.add(pulse.add);
}
// if pulse has added tuples, add them to state
if (pulse.add.length) {
bits.add(pulse.add);
}
// if pulse has modified tuples, create an index map
if (pulse.mod.length) {
modMap = {};
for (mods=pulse.mod, i=0, n=mods.length; i<n; ++i) {
modMap[mods[i]._index] = 1;
// if pulse has modified tuples, create an index map
if (pulse.mod.length) {
modMap = {};
for (mods=pulse.mod, i=0, n=mods.length; i<n; ++i) {
modMap[mods[i]._index] = 1;
}
}
}
// re-initialize indices as needed, update curr bitmap
for (i=0; i<m; ++i) {
f = fields[i];
if (!dims[i] || _.modified('fields', i) || pulse.modified(f.fields)) {
key = f.fname;
if (!(add = adds[key])) {
indices[key] = index = SortedIndex();
adds[key] = add = index.insert(f, pulse.source, 0);
// re-initialize indices as needed, update curr bitmap
for (i=0; i<m; ++i) {
f = fields[i];
if (!dims[i] || _.modified('fields', i) || pulse.modified(f.fields)) {
key = f.fname;
if (!(add = adds[key])) {
indices[key] = index = SortedIndex();
adds[key] = add = index.insert(f, pulse.source, 0);
}
dims[i] = Dimension(index, i, query[i]).onAdd(add, curr);
}
dims[i] = Dimension(index, i, query[i]).onAdd(add, curr);
}
}
// visit each tuple
// if filter state changed, push index to add/rem
// else if in mod and passes a filter, push index to mod
for (i=0, n=bits.data().length; i<n; ++i) {
if (remMap[i]) { // skip if removed tuple
continue;
} else if (prev[i] !== curr[i]) { // add if state changed
out.push(i);
} else if (modMap[i] && curr[i] !== all) { // otherwise, pass mods through
mod.push(i);
// visit each tuple
// if filter state changed, push index to add/rem
// else if in mod and passes a filter, push index to mod
for (i=0, n=bits.data().length; i<n; ++i) {
if (remMap[i]) { // skip if removed tuple
continue;
} else if (prev[i] !== curr[i]) { // add if state changed
out.push(i);
} else if (modMap[i] && curr[i] !== all) { // otherwise, pass mods through
mod.push(i);
}
}
}
bits.mask = (1 << m) - 1;
return output;
};
bits.mask = (1 << m) - 1;
return output;
},
prototype.eval = function(_, pulse) {
var output = pulse.materialize().fork(),
m = this._dims.length,
mask = 0;
eval(_, pulse) {
let output = pulse.materialize().fork(),
m = this._dims.length,
mask = 0;
if (pulse.rem.length) {
this.remove(_, pulse, output);
mask |= (1 << m) - 1;
}
if (pulse.rem.length) {
this.remove(_, pulse, output);
mask |= (1 << m) - 1;
}
if (_.modified('query') && !_.modified('fields')) {
mask |= this.update(_, pulse, output);
}
if (_.modified('query') && !_.modified('fields')) {
mask |= this.update(_, pulse, output);
}
if (pulse.add.length) {
this.insert(_, pulse, output);
mask |= (1 << m) - 1;
}
if (pulse.add.length) {
this.insert(_, pulse, output);
mask |= (1 << m) - 1;
}
if (pulse.mod.length) {
this.modify(pulse, output);
mask |= (1 << m) - 1;
}
if (pulse.mod.length) {
this.modify(pulse, output);
mask |= (1 << m) - 1;
}
this.value.mask = mask;
return output;
};
this.value.mask = mask;
return output;
},
prototype.insert = function(_, pulse, output) {
var tuples = pulse.add,
bits = this.value,
dims = this._dims,
indices = this._indices,
fields = _.fields,
adds = {},
out = output.add,
k = bits.size(),
n = k + tuples.length,
m = dims.length, j, key, add;
insert(_, pulse, output) {
let tuples = pulse.add,
bits = this.value,
dims = this._dims,
indices = this._indices,
fields = _.fields,
adds = {},
out = output.add,
k = bits.size(),
n = k + tuples.length,
m = dims.length, j, key, add;
// resize bitmaps and add tuples as needed
bits.resize(n, m);
bits.add(tuples);
// resize bitmaps and add tuples as needed
bits.resize(n, m);
bits.add(tuples);
var curr = bits.curr(),
prev = bits.prev(),
all = bits.all();
const curr = bits.curr(),
prev = bits.prev(),
all = bits.all();
// add to dimensional indices
for (j=0; j<m; ++j) {
key = fields[j].fname;
add = adds[key] || (adds[key] = indices[key].insert(fields[j], tuples, k));
dims[j].onAdd(add, curr);
}
// add to dimensional indices
for (j=0; j<m; ++j) {
key = fields[j].fname;
add = adds[key] || (adds[key] = indices[key].insert(fields[j], tuples, k));
dims[j].onAdd(add, curr);
}
// set previous filters, output if passes at least one filter
for (; k<n; ++k) {
prev[k] = all;
if (curr[k] !== all) out.push(k);
}
};
// set previous filters, output if passes at least one filter
for (; k<n; ++k) {
prev[k] = all;
if (curr[k] !== all) out.push(k);
}
},
prototype.modify = function(pulse, output) {
var out = output.mod,
bits = this.value,
curr = bits.curr(),
all = bits.all(),
tuples = pulse.mod,
i, n, k;
modify(pulse, output) {
let out = output.mod,
bits = this.value,
curr = bits.curr(),
all = bits.all(),
tuples = pulse.mod,
i, n, k;
for (i=0, n=tuples.length; i<n; ++i) {
k = tuples[i]._index;
if (curr[k] !== all) out.push(k);
}
};
for (i=0, n=tuples.length; i<n; ++i) {
k = tuples[i]._index;
if (curr[k] !== all) out.push(k);
}
},
prototype.remove = function(_, pulse, output) {
var indices = this._indices,
bits = this.value,
curr = bits.curr(),
prev = bits.prev(),
all = bits.all(),
map = {},
out = output.rem,
tuples = pulse.rem,
i, n, k, f;
remove(_, pulse, output) {
let indices = this._indices,
bits = this.value,
curr = bits.curr(),
prev = bits.prev(),
all = bits.all(),
map = {},
out = output.rem,
tuples = pulse.rem,
i, n, k, f;
// process tuples, output if passes at least one filter
for (i=0, n=tuples.length; i<n; ++i) {
k = tuples[i]._index;
map[k] = 1; // build index map
prev[k] = (f = curr[k]);
curr[k] = all;
if (f !== all) out.push(k);
}
// process tuples, output if passes at least one filter
for (i=0, n=tuples.length; i<n; ++i) {
k = tuples[i]._index;
map[k] = 1; // build index map
prev[k] = (f = curr[k]);
curr[k] = all;
if (f !== all) out.push(k);
}
// remove from dimensional indices
for (k in indices) {
indices[k].remove(n, map);
}
// remove from dimensional indices
for (k in indices) {
indices[k].remove(n, map);
}
this.reindex(pulse, n, map);
return map;
};
this.reindex(pulse, n, map);
return map;
},
// reindex filters and indices after propagation completes
prototype.reindex = function(pulse, num, map) {
var indices = this._indices,
bits = this.value;
// reindex filters and indices after propagation completes
reindex(pulse, num, map) {
const indices = this._indices,
bits = this.value;
pulse.runAfter(function() {
var indexMap = bits.remove(num, map);
for (var key in indices) indices[key].reindex(indexMap);
});
};
pulse.runAfter(() => {
const indexMap = bits.remove(num, map);
for (const key in indices) indices[key].reindex(indexMap);
});
},
prototype.update = function(_, pulse, output) {
var dims = this._dims,
query = _.query,
stamp = pulse.stamp,
m = dims.length,
mask = 0, i, q;
update(_, pulse, output) {
let dims = this._dims,
query = _.query,
stamp = pulse.stamp,
m = dims.length,
mask = 0, i, q;
// survey how many queries have changed
output.filters = 0;
for (q=0; q<m; ++q) {
if (_.modified('query', q)) { i = q; ++mask; }
}
// survey how many queries have changed
output.filters = 0;
for (q=0; q<m; ++q) {
if (_.modified('query', q)) { i = q; ++mask; }
}
if (mask === 1) {
// only one query changed, use more efficient update
mask = dims[i].one;
this.incrementOne(dims[i], query[i], output.add, output.rem);
} else {
// multiple queries changed, perform full record keeping
for (q=0, mask=0; q<m; ++q) {
if (!_.modified('query', q)) continue;
mask |= dims[q].one;
this.incrementAll(dims[q], query[q], stamp, output.add);
output.rem = output.add; // duplicate add/rem for downstream resolve
if (mask === 1) {
// only one query changed, use more efficient update
mask = dims[i].one;
this.incrementOne(dims[i], query[i], output.add, output.rem);
} else {
// multiple queries changed, perform full record keeping
for (q=0, mask=0; q<m; ++q) {
if (!_.modified('query', q)) continue;
mask |= dims[q].one;
this.incrementAll(dims[q], query[q], stamp, output.add);
output.rem = output.add; // duplicate add/rem for downstream resolve
}
}
}
return mask;
};
return mask;
},
prototype.incrementAll = function(dim, query, stamp, out) {
var bits = this.value,
seen = bits.seen(),
curr = bits.curr(),
prev = bits.prev(),
index = dim.index(),
old = dim.bisect(dim.range),
range = dim.bisect(query),
lo1 = range[0],
hi1 = range[1],
lo0 = old[0],
hi0 = old[1],
one = dim.one,
i, j, k;
incrementAll(dim, query, stamp, out) {
let bits = this.value,
seen = bits.seen(),
curr = bits.curr(),
prev = bits.prev(),
index = dim.index(),
old = dim.bisect(dim.range),
range = dim.bisect(query),
lo1 = range[0],
hi1 = range[1],
lo0 = old[0],
hi0 = old[1],
one = dim.one,
i, j, k;
// Fast incremental update based on previous lo index.
if (lo1 < lo0) {
for (i = lo1, j = Math.min(lo0, hi1); i < j; ++i) {
k = index[i];
if (seen[k] !== stamp) {
prev[k] = curr[k];
seen[k] = stamp;
out.push(k);
// Fast incremental update based on previous lo index.
if (lo1 < lo0) {
for (i = lo1, j = Math.min(lo0, hi1); i < j; ++i) {
k = index[i];
if (seen[k] !== stamp) {
prev[k] = curr[k];
seen[k] = stamp;
out.push(k);
}
curr[k] ^= one;
}
curr[k] ^= one;
}
} else if (lo1 > lo0) {
for (i = lo0, j = Math.min(lo1, hi0); i < j; ++i) {
k = index[i];
if (seen[k] !== stamp) {
prev[k] = curr[k];
seen[k] = stamp;
out.push(k);
} else if (lo1 > lo0) {
for (i = lo0, j = Math.min(lo1, hi0); i < j; ++i) {
k = index[i];
if (seen[k] !== stamp) {
prev[k] = curr[k];
seen[k] = stamp;
out.push(k);
}
curr[k] ^= one;
}
curr[k] ^= one;
}
}
// Fast incremental update based on previous hi index.
if (hi1 > hi0) {
for (i = Math.max(lo1, hi0), j = hi1; i < j; ++i) {
k = index[i];
if (seen[k] !== stamp) {
prev[k] = curr[k];
seen[k] = stamp;
out.push(k);
// Fast incremental update based on previous hi index.
if (hi1 > hi0) {
for (i = Math.max(lo1, hi0), j = hi1; i < j; ++i) {
k = index[i];
if (seen[k] !== stamp) {
prev[k] = curr[k];
seen[k] = stamp;
out.push(k);
}
curr[k] ^= one;
}
curr[k] ^= one;
}
} else if (hi1 < hi0) {
for (i = Math.max(lo0, hi1), j = hi0; i < j; ++i) {
k = index[i];
if (seen[k] !== stamp) {
prev[k] = curr[k];
seen[k] = stamp;
out.push(k);
} else if (hi1 < hi0) {
for (i = Math.max(lo0, hi1), j = hi0; i < j; ++i) {
k = index[i];
if (seen[k] !== stamp) {
prev[k] = curr[k];
seen[k] = stamp;
out.push(k);
}
curr[k] ^= one;
}
curr[k] ^= one;
}
}
dim.range = query.slice();
};
dim.range = query.slice();
},
prototype.incrementOne = function(dim, query, add, rem) {
var bits = this.value,
curr = bits.curr(),
index = dim.index(),
old = dim.bisect(dim.range),
range = dim.bisect(query),
lo1 = range[0],
hi1 = range[1],
lo0 = old[0],
hi0 = old[1],
one = dim.one,
i, j, k;
incrementOne(dim, query, add, rem) {
let bits = this.value,
curr = bits.curr(),
index = dim.index(),
old = dim.bisect(dim.range),
range = dim.bisect(query),
lo1 = range[0],
hi1 = range[1],
lo0 = old[0],
hi0 = old[1],
one = dim.one,
i, j, k;
// Fast incremental update based on previous lo index.
if (lo1 < lo0) {
for (i = lo1, j = Math.min(lo0, hi1); i < j; ++i) {
k = index[i];
curr[k] ^= one;
add.push(k);
// Fast incremental update based on previous lo index.
if (lo1 < lo0) {
for (i = lo1, j = Math.min(lo0, hi1); i < j; ++i) {
k = index[i];
curr[k] ^= one;
add.push(k);
}
} else if (lo1 > lo0) {
for (i = lo0, j = Math.min(lo1, hi0); i < j; ++i) {
k = index[i];
curr[k] ^= one;
rem.push(k);
}
}
} else if (lo1 > lo0) {
for (i = lo0, j = Math.min(lo1, hi0); i < j; ++i) {
k = index[i];
curr[k] ^= one;
rem.push(k);
// Fast incremental update based on previous hi index.
if (hi1 > hi0) {
for (i = Math.max(lo1, hi0), j = hi1; i < j; ++i) {
k = index[i];
curr[k] ^= one;
add.push(k);
}
} else if (hi1 < hi0) {
for (i = Math.max(lo0, hi1), j = hi0; i < j; ++i) {
k = index[i];
curr[k] ^= one;
rem.push(k);
}
}
}
// Fast incremental update based on previous hi index.
if (hi1 > hi0) {
for (i = Math.max(lo1, hi0), j = hi1; i < j; ++i) {
k = index[i];
curr[k] ^= one;
add.push(k);
}
} else if (hi1 < hi0) {
for (i = Math.max(lo0, hi1), j = hi0; i < j; ++i) {
k = index[i];
curr[k] ^= one;
rem.push(k);
}
dim.range = query.slice();
}
});
dim.range = query.slice();
};
/**

@@ -680,50 +678,47 @@ * Selectively filters tuples by resolving against a filter bitmap.

var prototype$1 = vegaUtil.inherits(ResolveFilter, vegaDataflow.Transform);
vegaUtil.inherits(ResolveFilter, vegaDataflow.Transform, {
transform(_, pulse) {
const ignore = ~(_.ignore || 0), // bit mask where zeros -> dims to ignore
bitmap = _.filter,
mask = bitmap.mask;
prototype$1.transform = function(_, pulse) {
var ignore = ~(_.ignore || 0), // bit mask where zeros -> dims to ignore
bitmap = _.filter,
mask = bitmap.mask;
// exit early if no relevant filter changes
if ((mask & ignore) === 0) return pulse.StopPropagation;
// exit early if no relevant filter changes
if ((mask & ignore) === 0) return pulse.StopPropagation;
const output = pulse.fork(pulse.ALL),
data = bitmap.data(),
curr = bitmap.curr(),
prev = bitmap.prev(),
pass = k => !(curr[k] & ignore) ? data[k] : null;
var output = pulse.fork(pulse.ALL),
data = bitmap.data(),
curr = bitmap.curr(),
prev = bitmap.prev(),
pass = function(k) {
return !(curr[k] & ignore) ? data[k] : null;
};
// propagate all mod tuples that pass the filter
output.filter(output.MOD, pass);
// propagate all mod tuples that pass the filter
output.filter(output.MOD, pass);
// determine add & rem tuples via filter functions
// for efficiency, we do *not* populate new arrays,
// instead we add filter functions applied downstream
// determine add & rem tuples via filter functions
// for efficiency, we do *not* populate new arrays,
// instead we add filter functions applied downstream
if (!(mask & (mask-1))) { // only one filter changed
output.filter(output.ADD, pass);
output.filter(output.REM, k =>
(curr[k] & ignore) === mask ? data[k] : null);
if (!(mask & (mask-1))) { // only one filter changed
output.filter(output.ADD, pass);
output.filter(output.REM, function(k) {
return (curr[k] & ignore) === mask ? data[k] : null;
});
} else { // multiple filters changed
output.filter(output.ADD, k => {
const c = curr[k] & ignore,
f = !c && (c ^ (prev[k] & ignore));
return f ? data[k] : null;
});
output.filter(output.REM, k => {
const c = curr[k] & ignore,
f = c && !(c ^ (c ^ (prev[k] & ignore)));
return f ? data[k] : null;
});
}
} else { // multiple filters changed
output.filter(output.ADD, function(k) {
var c = curr[k] & ignore,
f = !c && (c ^ (prev[k] & ignore));
return f ? data[k] : null;
});
output.filter(output.REM, function(k) {
var c = curr[k] & ignore,
f = c && !(c ^ (c ^ (prev[k] & ignore)));
return f ? data[k] : null;
});
// add filter to source data in case of reflow...
return output.filter(output.SOURCE, t => pass(t._index));
}
});
// add filter to source data in case of reflow...
return output.filter(output.SOURCE, function(t) { return pass(t._index); });
};
exports.crossfilter = CrossFilter;

@@ -730,0 +725,0 @@ exports.resolvefilter = ResolveFilter;

@@ -1,1 +0,1 @@

!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("d3-array"),require("vega-dataflow"),require("vega-util")):"function"==typeof define&&define.amd?define(["exports","d3-array","vega-dataflow","vega-util"],r):r(((e=e||self).vega=e.vega||{},e.vega.transforms={}),e.d3,e.vega,e.vega)}(this,(function(e,r,n,i){"use strict";function t(e){return new Uint8Array(e)}function a(e){return new Uint16Array(e)}function o(e){return new Uint32Array(e)}function f(e,r,n){var i=(r<257?t:r<65537?a:o)(e);return n&&i.set(n),i}function u(e,r,n){var i=1<<r;return{one:i,zero:~i,range:n.slice(),bisect:e.bisect,index:e.index,size:e.size,onAdd:function(e,r){var n,t=this.bisect(this.range,e.value),a=e.index,o=t[0],f=t[1],u=a.length;for(n=0;n<o;++n)r[a[n]]|=i;for(n=f;n<u;++n)r[a[n]]|=i;return this}}}function s(){var e=o(0),n=[],i=0;return{insert:function(t,a,f){if(!a.length)return[];var u,s,l,d=i,c=a.length,h=Array(c),m=o(c);for(l=0;l<c;++l)h[l]=t(a[l]),m[l]=l;if(h=function(e,n){return e.sort.call(n,(function(r,n){var i=e[r],t=e[n];return i<t?-1:i>t?1:0})),r.permute(e,n)}(h,m),d)u=n,s=e,n=Array(d+c),e=o(d+c),function(e,r,n,i,t,a,o,f,u){var s,l=0,d=0;for(s=0;l<i&&d<o;++s)r[l]<t[d]?(f[s]=r[l],u[s]=n[l++]):(f[s]=t[d],u[s]=a[d++]+e);for(;l<i;++l,++s)f[s]=r[l],u[s]=n[l];for(;d<o;++d,++s)f[s]=t[d],u[s]=a[d]+e}(f,u,s,d,h,m,c,n,e);else{if(f>0)for(l=0;l<c;++l)m[l]+=f;n=h,e=m}return i=d+c,{index:m,value:h}},remove:function(r,t){var a,o,f,u=i;for(o=0;!t[e[o]]&&o<u;++o);for(f=o;o<u;++o)t[a=e[o]]||(e[f]=a,n[f]=n[o],++f);i=u-r},bisect:function(e,t){var a;return t?a=t.length:(t=n,a=i),[r.bisectLeft(t,e[0],0,a),r.bisectRight(t,e[1],0,a)]},reindex:function(r){for(var n=0,t=i;n<t;++n)e[n]=r[e[n]]},index:function(){return e},size:function(){return i}}}function l(e){var r,i,t,a,u;n.Transform.call(this,(r=8,i=[],t=o(0),a=f(0,r),u=f(0,r),{data:function(){return i},seen:function(){return t=function(e,r,n){return e.length>=r?e:((n=n||new e.constructor(r)).set(e),n)}(t,i.length)},add:function(e){for(var r,n=0,t=i.length,a=e.length;n<a;++n)(r=e[n])._index=t++,i.push(r)},remove:function(e,r){var n,t,o,f=i.length,s=Array(f-e),l=i;for(t=0;!r[t]&&t<f;++t)s[t]=i[t],l[t]=t;for(o=t;t<f;++t)n=i[t],r[t]?l[t]=-1:(l[t]=o,a[o]=a[t],u[o]=u[t],s[o]=n,n._index=o++),a[t]=0;return i=s,l},size:function(){return i.length},curr:function(){return a},prev:function(){return u},reset:function(e){u[e]=a[e]},all:function(){return r<257?255:r<65537?65535:4294967295},set:function(e,r){a[e]|=r},clear:function(e,r){a[e]&=~r},resize:function(e,n){(e>a.length||n>r)&&(r=Math.max(n,r),a=f(e,r,a),u=f(e,r))}}),e),this._indices=null,this._dims=null}l.Definition={type:"CrossFilter",metadata:{},params:[{name:"fields",type:"field",array:!0,required:!0},{name:"query",type:"array",array:!0,required:!0,content:{type:"number",array:!0,length:2}}]};var d=i.inherits(l,n.Transform);function c(e){n.Transform.call(this,null,e)}d.transform=function(e,r){return this._dims?e.modified("fields")||e.fields.some((function(e){return r.modified(e.fields)}))?this.reinit(e,r):this.eval(e,r):this.init(e,r)},d.init=function(e,r){for(var n,i,t=e.fields,a=e.query,o=this._indices={},f=this._dims=[],l=a.length,d=0;d<l;++d)i=o[n=t[d].fname]||(o[n]=s()),f.push(u(i,d,a[d]));return this.eval(e,r)},d.reinit=function(e,r){var n,i,t,a,o,f,l,d,c,h=r.materialize().fork(),m=e.fields,v=e.query,g=this._indices,p=this._dims,y=this.value,x=y.curr(),_=y.prev(),b=y.all(),A=h.rem=h.add,q=h.mod,M=v.length,z={};if(_.set(x),r.rem.length&&(o=this.remove(e,r,h)),r.add.length&&y.add(r.add),r.mod.length)for(f={},l=0,d=(a=r.mod).length;l<d;++l)f[a[l]._index]=1;for(l=0;l<M;++l)c=m[l],(!p[l]||e.modified("fields",l)||r.modified(c.fields))&&((n=z[t=c.fname])||(g[t]=i=s(),z[t]=n=i.insert(c,r.source,0)),p[l]=u(i,l,v[l]).onAdd(n,x));for(l=0,d=y.data().length;l<d;++l)o[l]||(_[l]!==x[l]?A.push(l):f[l]&&x[l]!==b&&q.push(l));return y.mask=(1<<M)-1,h},d.eval=function(e,r){var n=r.materialize().fork(),i=this._dims.length,t=0;return r.rem.length&&(this.remove(e,r,n),t|=(1<<i)-1),e.modified("query")&&!e.modified("fields")&&(t|=this.update(e,r,n)),r.add.length&&(this.insert(e,r,n),t|=(1<<i)-1),r.mod.length&&(this.modify(r,n),t|=(1<<i)-1),this.value.mask=t,n},d.insert=function(e,r,n){var i,t,a,o=r.add,f=this.value,u=this._dims,s=this._indices,l=e.fields,d={},c=n.add,h=f.size(),m=h+o.length,v=u.length;f.resize(m,v),f.add(o);var g=f.curr(),p=f.prev(),y=f.all();for(i=0;i<v;++i)a=d[t=l[i].fname]||(d[t]=s[t].insert(l[i],o,h)),u[i].onAdd(a,g);for(;h<m;++h)p[h]=y,g[h]!==y&&c.push(h)},d.modify=function(e,r){var n,i,t,a=r.mod,o=this.value,f=o.curr(),u=o.all(),s=e.mod;for(n=0,i=s.length;n<i;++n)f[t=s[n]._index]!==u&&a.push(t)},d.remove=function(e,r,n){var i,t,a,o,f=this._indices,u=this.value,s=u.curr(),l=u.prev(),d=u.all(),c={},h=n.rem,m=r.rem;for(i=0,t=m.length;i<t;++i)c[a=m[i]._index]=1,l[a]=o=s[a],s[a]=d,o!==d&&h.push(a);for(a in f)f[a].remove(t,c);return this.reindex(r,t,c),c},d.reindex=function(e,r,n){var i=this._indices,t=this.value;e.runAfter((function(){var e=t.remove(r,n);for(var a in i)i[a].reindex(e)}))},d.update=function(e,r,n){var i,t,a=this._dims,o=e.query,f=r.stamp,u=a.length,s=0;for(n.filters=0,t=0;t<u;++t)e.modified("query",t)&&(i=t,++s);if(1===s)s=a[i].one,this.incrementOne(a[i],o[i],n.add,n.rem);else for(t=0,s=0;t<u;++t)e.modified("query",t)&&(s|=a[t].one,this.incrementAll(a[t],o[t],f,n.add),n.rem=n.add);return s},d.incrementAll=function(e,r,n,i){var t,a,o,f=this.value,u=f.seen(),s=f.curr(),l=f.prev(),d=e.index(),c=e.bisect(e.range),h=e.bisect(r),m=h[0],v=h[1],g=c[0],p=c[1],y=e.one;if(m<g)for(t=m,a=Math.min(g,v);t<a;++t)u[o=d[t]]!==n&&(l[o]=s[o],u[o]=n,i.push(o)),s[o]^=y;else if(m>g)for(t=g,a=Math.min(m,p);t<a;++t)u[o=d[t]]!==n&&(l[o]=s[o],u[o]=n,i.push(o)),s[o]^=y;if(v>p)for(t=Math.max(m,p),a=v;t<a;++t)u[o=d[t]]!==n&&(l[o]=s[o],u[o]=n,i.push(o)),s[o]^=y;else if(v<p)for(t=Math.max(g,v),a=p;t<a;++t)u[o=d[t]]!==n&&(l[o]=s[o],u[o]=n,i.push(o)),s[o]^=y;e.range=r.slice()},d.incrementOne=function(e,r,n,i){var t,a,o,f=this.value.curr(),u=e.index(),s=e.bisect(e.range),l=e.bisect(r),d=l[0],c=l[1],h=s[0],m=s[1],v=e.one;if(d<h)for(t=d,a=Math.min(h,c);t<a;++t)f[o=u[t]]^=v,n.push(o);else if(d>h)for(t=h,a=Math.min(d,m);t<a;++t)f[o=u[t]]^=v,i.push(o);if(c>m)for(t=Math.max(d,m),a=c;t<a;++t)f[o=u[t]]^=v,n.push(o);else if(c<m)for(t=Math.max(h,c),a=m;t<a;++t)f[o=u[t]]^=v,i.push(o);e.range=r.slice()},c.Definition={type:"ResolveFilter",metadata:{},params:[{name:"ignore",type:"number",required:!0,description:"A bit mask indicating which filters to ignore."},{name:"filter",type:"object",required:!0,description:"Per-tuple filter bitmaps from a CrossFilter transform."}]},i.inherits(c,n.Transform).transform=function(e,r){var n=~(e.ignore||0),i=e.filter,t=i.mask;if(0==(t&n))return r.StopPropagation;var a=r.fork(r.ALL),o=i.data(),f=i.curr(),u=i.prev(),s=function(e){return f[e]&n?null:o[e]};return a.filter(a.MOD,s),t&t-1?(a.filter(a.ADD,(function(e){var r=f[e]&n;return!r&&r^u[e]&n?o[e]:null})),a.filter(a.REM,(function(e){var r=f[e]&n;return r&&!(r^r^u[e]&n)?o[e]:null}))):(a.filter(a.ADD,s),a.filter(a.REM,(function(e){return(f[e]&n)===t?o[e]:null}))),a.filter(a.SOURCE,(function(e){return s(e._index)}))},e.crossfilter=l,e.resolvefilter=c,Object.defineProperty(e,"__esModule",{value:!0})}));
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("d3-array"),require("vega-dataflow"),require("vega-util")):"function"==typeof define&&define.amd?define(["exports","d3-array","vega-dataflow","vega-util"],t):t(((e="undefined"!=typeof globalThis?globalThis:e||self).vega=e.vega||{},e.vega.transforms={}),e.d3,e.vega,e.vega)}(this,(function(e,t,r,i){"use strict";const n=e=>new Uint8Array(e),s=e=>new Uint16Array(e),l=e=>new Uint32Array(e);function o(e,t,r){const i=(t<257?n:t<65537?s:l)(e);return r&&i.set(r),i}function a(e,t,r){const i=1<<t;return{one:i,zero:~i,range:r.slice(),bisect:e.bisect,index:e.index,size:e.size,onAdd(e,t){let r,n=this.bisect(this.range,e.value),s=e.index,l=n[0],o=n[1],a=s.length;for(r=0;r<l;++r)t[s[r]]|=i;for(r=o;r<a;++r)t[s[r]]|=i;return this}}}function f(){let e=l(0),r=[],i=0;return{insert:function(n,s,o){if(!s.length)return[];let a,f,d,u=i,h=s.length,m=Array(h),c=l(h);for(d=0;d<h;++d)m[d]=n(s[d]),c[d]=d;if(m=function(e,r){return e.sort.call(r,(t,r)=>{const i=e[t],n=e[r];return i<n?-1:i>n?1:0}),t.permute(e,r)}(m,c),u)a=r,f=e,r=Array(u+h),e=l(u+h),function(e,t,r,i,n,s,l,o,a){let f,d=0,u=0;for(f=0;d<i&&u<l;++f)t[d]<n[u]?(o[f]=t[d],a[f]=r[d++]):(o[f]=n[u],a[f]=s[u++]+e);for(;d<i;++d,++f)o[f]=t[d],a[f]=r[d];for(;u<l;++u,++f)o[f]=n[u],a[f]=s[u]+e}(o,a,f,u,m,c,h,r,e);else{if(o>0)for(d=0;d<h;++d)c[d]+=o;r=m,e=c}return i=u+h,{index:c,value:m}},remove:function(t,n){let s,l,o,a=i;for(l=0;!n[e[l]]&&l<a;++l);for(o=l;l<a;++l)n[s=e[l]]||(e[o]=s,r[o]=r[l],++o);i=a-t},bisect:function(e,n){let s;return n?s=n.length:(n=r,s=i),[t.bisectLeft(n,e[0],0,s),t.bisectRight(n,e[1],0,s)]},reindex:function(t){for(let r=0,n=i;r<n;++r)e[r]=t[e[r]]},index:()=>e,size:()=>i}}function d(e){r.Transform.call(this,function(){let e=8,t=[],r=l(0),i=o(0,e),n=o(0,e);return{data:()=>t,seen:()=>r=function(e,t,r){return e.length>=t?e:((r=r||new e.constructor(t)).set(e),r)}(r,t.length),add(e){for(let r,i=0,n=t.length,s=e.length;i<s;++i)r=e[i],r._index=n++,t.push(r)},remove(e,r){let s,l,o,a=t.length,f=Array(a-e),d=t;for(l=0;!r[l]&&l<a;++l)f[l]=t[l],d[l]=l;for(o=l;l<a;++l)s=t[l],r[l]?d[l]=-1:(d[l]=o,i[o]=i[l],n[o]=n[l],f[o]=s,s._index=o++),i[l]=0;return t=f,d},size:()=>t.length,curr:()=>i,prev:()=>n,reset:e=>n[e]=i[e],all:()=>e<257?255:e<65537?65535:4294967295,set(e,t){i[e]|=t},clear(e,t){i[e]&=~t},resize(t,r){(t>i.length||r>e)&&(e=Math.max(r,e),i=o(t,e,i),n=o(t,e))}}}(),e),this._indices=null,this._dims=null}function u(e){r.Transform.call(this,null,e)}d.Definition={type:"CrossFilter",metadata:{},params:[{name:"fields",type:"field",array:!0,required:!0},{name:"query",type:"array",array:!0,required:!0,content:{type:"number",array:!0,length:2}}]},i.inherits(d,r.Transform,{transform(e,t){return this._dims?e.modified("fields")||e.fields.some(e=>t.modified(e.fields))?this.reinit(e,t):this.eval(e,t):this.init(e,t)},init(e,t){let r,i,n=e.fields,s=e.query,l=this._indices={},o=this._dims=[],d=s.length,u=0;for(;u<d;++u)r=n[u].fname,i=l[r]||(l[r]=f()),o.push(a(i,u,s[u]));return this.eval(e,t)},reinit(e,t){let r,i,n,s,l,o,d,u,h,m=t.materialize().fork(),c=e.fields,g=e.query,p=this._indices,v=this._dims,y=this.value,x=y.curr(),_=y.prev(),b=y.all(),A=m.rem=m.add,q=m.mod,M=g.length,z={};if(_.set(x),t.rem.length&&(l=this.remove(e,t,m)),t.add.length&&y.add(t.add),t.mod.length)for(o={},s=t.mod,d=0,u=s.length;d<u;++d)o[s[d]._index]=1;for(d=0;d<M;++d)h=c[d],(!v[d]||e.modified("fields",d)||t.modified(h.fields))&&(n=h.fname,(r=z[n])||(p[n]=i=f(),z[n]=r=i.insert(h,t.source,0)),v[d]=a(i,d,g[d]).onAdd(r,x));for(d=0,u=y.data().length;d<u;++d)l[d]||(_[d]!==x[d]?A.push(d):o[d]&&x[d]!==b&&q.push(d));return y.mask=(1<<M)-1,m},eval(e,t){let r=t.materialize().fork(),i=this._dims.length,n=0;return t.rem.length&&(this.remove(e,t,r),n|=(1<<i)-1),e.modified("query")&&!e.modified("fields")&&(n|=this.update(e,t,r)),t.add.length&&(this.insert(e,t,r),n|=(1<<i)-1),t.mod.length&&(this.modify(t,r),n|=(1<<i)-1),this.value.mask=n,r},insert(e,t,r){let i,n,s,l=t.add,o=this.value,a=this._dims,f=this._indices,d=e.fields,u={},h=r.add,m=o.size(),c=m+l.length,g=a.length;o.resize(c,g),o.add(l);const p=o.curr(),v=o.prev(),y=o.all();for(i=0;i<g;++i)n=d[i].fname,s=u[n]||(u[n]=f[n].insert(d[i],l,m)),a[i].onAdd(s,p);for(;m<c;++m)v[m]=y,p[m]!==y&&h.push(m)},modify(e,t){let r,i,n,s=t.mod,l=this.value,o=l.curr(),a=l.all(),f=e.mod;for(r=0,i=f.length;r<i;++r)n=f[r]._index,o[n]!==a&&s.push(n)},remove(e,t,r){let i,n,s,l,o=this._indices,a=this.value,f=a.curr(),d=a.prev(),u=a.all(),h={},m=r.rem,c=t.rem;for(i=0,n=c.length;i<n;++i)s=c[i]._index,h[s]=1,d[s]=l=f[s],f[s]=u,l!==u&&m.push(s);for(s in o)o[s].remove(n,h);return this.reindex(t,n,h),h},reindex(e,t,r){const i=this._indices,n=this.value;e.runAfter(()=>{const e=n.remove(t,r);for(const t in i)i[t].reindex(e)})},update(e,t,r){let i,n,s=this._dims,l=e.query,o=t.stamp,a=s.length,f=0;for(r.filters=0,n=0;n<a;++n)e.modified("query",n)&&(i=n,++f);if(1===f)f=s[i].one,this.incrementOne(s[i],l[i],r.add,r.rem);else for(n=0,f=0;n<a;++n)e.modified("query",n)&&(f|=s[n].one,this.incrementAll(s[n],l[n],o,r.add),r.rem=r.add);return f},incrementAll(e,t,r,i){let n,s,l,o=this.value,a=o.seen(),f=o.curr(),d=o.prev(),u=e.index(),h=e.bisect(e.range),m=e.bisect(t),c=m[0],g=m[1],p=h[0],v=h[1],y=e.one;if(c<p)for(n=c,s=Math.min(p,g);n<s;++n)l=u[n],a[l]!==r&&(d[l]=f[l],a[l]=r,i.push(l)),f[l]^=y;else if(c>p)for(n=p,s=Math.min(c,v);n<s;++n)l=u[n],a[l]!==r&&(d[l]=f[l],a[l]=r,i.push(l)),f[l]^=y;if(g>v)for(n=Math.max(c,v),s=g;n<s;++n)l=u[n],a[l]!==r&&(d[l]=f[l],a[l]=r,i.push(l)),f[l]^=y;else if(g<v)for(n=Math.max(p,g),s=v;n<s;++n)l=u[n],a[l]!==r&&(d[l]=f[l],a[l]=r,i.push(l)),f[l]^=y;e.range=t.slice()},incrementOne(e,t,r,i){let n,s,l,o=this.value.curr(),a=e.index(),f=e.bisect(e.range),d=e.bisect(t),u=d[0],h=d[1],m=f[0],c=f[1],g=e.one;if(u<m)for(n=u,s=Math.min(m,h);n<s;++n)l=a[n],o[l]^=g,r.push(l);else if(u>m)for(n=m,s=Math.min(u,c);n<s;++n)l=a[n],o[l]^=g,i.push(l);if(h>c)for(n=Math.max(u,c),s=h;n<s;++n)l=a[n],o[l]^=g,r.push(l);else if(h<c)for(n=Math.max(m,h),s=c;n<s;++n)l=a[n],o[l]^=g,i.push(l);e.range=t.slice()}}),u.Definition={type:"ResolveFilter",metadata:{},params:[{name:"ignore",type:"number",required:!0,description:"A bit mask indicating which filters to ignore."},{name:"filter",type:"object",required:!0,description:"Per-tuple filter bitmaps from a CrossFilter transform."}]},i.inherits(u,r.Transform,{transform(e,t){const r=~(e.ignore||0),i=e.filter,n=i.mask;if(0==(n&r))return t.StopPropagation;const s=t.fork(t.ALL),l=i.data(),o=i.curr(),a=i.prev(),f=e=>o[e]&r?null:l[e];return s.filter(s.MOD,f),n&n-1?(s.filter(s.ADD,e=>{const t=o[e]&r;return!t&&t^a[e]&r?l[e]:null}),s.filter(s.REM,e=>{const t=o[e]&r;return t&&!(t^t^a[e]&r)?l[e]:null})):(s.filter(s.ADD,f),s.filter(s.REM,e=>(o[e]&r)===n?l[e]:null)),s.filter(s.SOURCE,e=>f(e._index))}}),e.crossfilter=d,e.resolvefilter=u,Object.defineProperty(e,"__esModule",{value:!0})}));
{
"name": "vega-crossfilter",
"version": "4.0.2",
"version": "4.0.3",
"description": "Indexed cross-filtering for Vega dataflows.",

@@ -25,5 +25,5 @@ "keywords": [

"dependencies": {
"d3-array": "^2.4.0",
"vega-dataflow": "^5.5.1",
"vega-util": "^1.13.2"
"d3-array": "^2.5.1",
"vega-dataflow": "^5.7.1",
"vega-util": "^1.15.0"
},

@@ -33,3 +33,3 @@ "devDependencies": {

},
"gitHead": "35e31c5c6b54db9dc3a577b5adad8d15ec274d32"
"gitHead": "28db83352e43e321dfe55fc5cb6489b211e45662"
}

@@ -1,5 +0,5 @@

export function array8(n) { return new Uint8Array(n); }
export const array8 = n => new Uint8Array(n);
export function array16(n) { return new Uint16Array(n); }
export const array16 = n => new Uint16Array(n);
export function array32(n) { return new Uint32Array(n); }
export const array32 = n => new Uint32Array(n);

@@ -8,3 +8,3 @@ import {array16, array32, array8} from './arrays';

var width = 8,
let width = 8,
data = [],

@@ -16,11 +16,8 @@ seen = array32(0),

return {
data: () => data,
data: function() { return data; },
seen: () => (seen = lengthen(seen, data.length)),
seen: function() {
return (seen = lengthen(seen, data.length));
},
add: function(array) {
for (var i=0, j=data.length, n=array.length, t; i<n; ++i) {
add(array) {
for (let i=0, j=data.length, n=array.length, t; i<n; ++i) {
t = array[i];

@@ -32,4 +29,4 @@ t._index = j++;

remove: function(num, map) { // map: index -> boolean (true => remove)
var n = data.length,
remove(num, map) { // map: index -> boolean (true => remove)
let n = data.length,
copy = Array(n - num),

@@ -64,20 +61,19 @@ reindex = data, // reuse old data array for index map

size: function() { return data.length; },
size: () => data.length,
curr: function() { return curr; },
curr: () => curr,
prev: function() { return prev; },
prev: () => prev,
reset: function(k) { prev[k] = curr[k]; },
reset: k => prev[k] = curr[k],
all: function() {
return width < 0x101 ? 0xff : width < 0x10001 ? 0xffff : 0xffffffff;
},
all: () =>
width < 0x101 ? 0xff : width < 0x10001 ? 0xffff : 0xffffffff,
set: function(k, one) { curr[k] |= one; },
set(k, one) { curr[k] |= one; },
clear: function(k, one) { curr[k] &= ~one; },
clear(k, one) { curr[k] &= ~one; },
resize: function(n, m) {
var k = curr.length;
resize(n, m) {
const k = curr.length;
if (n > k || m > width) {

@@ -100,5 +96,7 @@ width = Math.max(m, width);

function array(n, m, array) {
var copy = (m < 0x101 ? array8 : m < 0x10001 ? array16 : array32)(n);
const copy = (m < 0x101 ? array8
: m < 0x10001 ? array16
: array32)(n);
if (array) copy.set(array);
return copy;
}

@@ -30,356 +30,356 @@ import Bitmaps from './Bitmaps';

var prototype = inherits(CrossFilter, Transform);
inherits(CrossFilter, Transform, {
transform(_, pulse) {
if (!this._dims) {
return this.init(_, pulse);
} else {
var init = _.modified('fields')
|| _.fields.some(f => pulse.modified(f.fields));
prototype.transform = function(_, pulse) {
if (!this._dims) {
return this.init(_, pulse);
} else {
var init = _.modified('fields')
|| _.fields.some(function(f) { return pulse.modified(f.fields); });
return init
? this.reinit(_, pulse)
: this.eval(_, pulse);
}
},
return init
? this.reinit(_, pulse)
: this.eval(_, pulse);
}
};
init(_, pulse) {
let fields = _.fields,
query = _.query,
indices = this._indices = {},
dims = this._dims = [],
m = query.length,
i = 0, key, index;
prototype.init = function(_, pulse) {
var fields = _.fields,
query = _.query,
indices = this._indices = {},
dims = this._dims = [],
m = query.length,
i = 0, key, index;
// instantiate indices and dimensions
for (; i<m; ++i) {
key = fields[i].fname;
index = indices[key] || (indices[key] = SortedIndex());
dims.push(Dimension(index, i, query[i]));
}
// instantiate indices and dimensions
for (; i<m; ++i) {
key = fields[i].fname;
index = indices[key] || (indices[key] = SortedIndex());
dims.push(Dimension(index, i, query[i]));
}
return this.eval(_, pulse);
},
return this.eval(_, pulse);
};
reinit(_, pulse) {
let output = pulse.materialize().fork(),
fields = _.fields,
query = _.query,
indices = this._indices,
dims = this._dims,
bits = this.value,
curr = bits.curr(),
prev = bits.prev(),
all = bits.all(),
out = (output.rem = output.add),
mod = output.mod,
m = query.length,
adds = {}, add, index, key,
mods, remMap, modMap, i, n, f;
prototype.reinit = function(_, pulse) {
var output = pulse.materialize().fork(),
fields = _.fields,
query = _.query,
indices = this._indices,
dims = this._dims,
bits = this.value,
curr = bits.curr(),
prev = bits.prev(),
all = bits.all(),
out = (output.rem = output.add),
mod = output.mod,
m = query.length,
adds = {}, add, index, key,
mods, remMap, modMap, i, n, f;
// set prev to current state
prev.set(curr);
// set prev to current state
prev.set(curr);
// if pulse has remove tuples, process them first
if (pulse.rem.length) {
remMap = this.remove(_, pulse, output);
}
// if pulse has remove tuples, process them first
if (pulse.rem.length) {
remMap = this.remove(_, pulse, output);
}
// if pulse has added tuples, add them to state
if (pulse.add.length) {
bits.add(pulse.add);
}
// if pulse has added tuples, add them to state
if (pulse.add.length) {
bits.add(pulse.add);
}
// if pulse has modified tuples, create an index map
if (pulse.mod.length) {
modMap = {};
for (mods=pulse.mod, i=0, n=mods.length; i<n; ++i) {
modMap[mods[i]._index] = 1;
// if pulse has modified tuples, create an index map
if (pulse.mod.length) {
modMap = {};
for (mods=pulse.mod, i=0, n=mods.length; i<n; ++i) {
modMap[mods[i]._index] = 1;
}
}
}
// re-initialize indices as needed, update curr bitmap
for (i=0; i<m; ++i) {
f = fields[i];
if (!dims[i] || _.modified('fields', i) || pulse.modified(f.fields)) {
key = f.fname;
if (!(add = adds[key])) {
indices[key] = index = SortedIndex();
adds[key] = add = index.insert(f, pulse.source, 0);
// re-initialize indices as needed, update curr bitmap
for (i=0; i<m; ++i) {
f = fields[i];
if (!dims[i] || _.modified('fields', i) || pulse.modified(f.fields)) {
key = f.fname;
if (!(add = adds[key])) {
indices[key] = index = SortedIndex();
adds[key] = add = index.insert(f, pulse.source, 0);
}
dims[i] = Dimension(index, i, query[i]).onAdd(add, curr);
}
dims[i] = Dimension(index, i, query[i]).onAdd(add, curr);
}
}
// visit each tuple
// if filter state changed, push index to add/rem
// else if in mod and passes a filter, push index to mod
for (i=0, n=bits.data().length; i<n; ++i) {
if (remMap[i]) { // skip if removed tuple
continue;
} else if (prev[i] !== curr[i]) { // add if state changed
out.push(i);
} else if (modMap[i] && curr[i] !== all) { // otherwise, pass mods through
mod.push(i);
// visit each tuple
// if filter state changed, push index to add/rem
// else if in mod and passes a filter, push index to mod
for (i=0, n=bits.data().length; i<n; ++i) {
if (remMap[i]) { // skip if removed tuple
continue;
} else if (prev[i] !== curr[i]) { // add if state changed
out.push(i);
} else if (modMap[i] && curr[i] !== all) { // otherwise, pass mods through
mod.push(i);
}
}
}
bits.mask = (1 << m) - 1;
return output;
};
bits.mask = (1 << m) - 1;
return output;
},
prototype.eval = function(_, pulse) {
var output = pulse.materialize().fork(),
m = this._dims.length,
mask = 0;
eval(_, pulse) {
let output = pulse.materialize().fork(),
m = this._dims.length,
mask = 0;
if (pulse.rem.length) {
this.remove(_, pulse, output);
mask |= (1 << m) - 1;
}
if (pulse.rem.length) {
this.remove(_, pulse, output);
mask |= (1 << m) - 1;
}
if (_.modified('query') && !_.modified('fields')) {
mask |= this.update(_, pulse, output);
}
if (_.modified('query') && !_.modified('fields')) {
mask |= this.update(_, pulse, output);
}
if (pulse.add.length) {
this.insert(_, pulse, output);
mask |= (1 << m) - 1;
}
if (pulse.add.length) {
this.insert(_, pulse, output);
mask |= (1 << m) - 1;
}
if (pulse.mod.length) {
this.modify(pulse, output);
mask |= (1 << m) - 1;
}
if (pulse.mod.length) {
this.modify(pulse, output);
mask |= (1 << m) - 1;
}
this.value.mask = mask;
return output;
};
this.value.mask = mask;
return output;
},
prototype.insert = function(_, pulse, output) {
var tuples = pulse.add,
bits = this.value,
dims = this._dims,
indices = this._indices,
fields = _.fields,
adds = {},
out = output.add,
k = bits.size(),
n = k + tuples.length,
m = dims.length, j, key, add;
insert(_, pulse, output) {
let tuples = pulse.add,
bits = this.value,
dims = this._dims,
indices = this._indices,
fields = _.fields,
adds = {},
out = output.add,
k = bits.size(),
n = k + tuples.length,
m = dims.length, j, key, add;
// resize bitmaps and add tuples as needed
bits.resize(n, m);
bits.add(tuples);
// resize bitmaps and add tuples as needed
bits.resize(n, m);
bits.add(tuples);
var curr = bits.curr(),
prev = bits.prev(),
all = bits.all();
const curr = bits.curr(),
prev = bits.prev(),
all = bits.all();
// add to dimensional indices
for (j=0; j<m; ++j) {
key = fields[j].fname;
add = adds[key] || (adds[key] = indices[key].insert(fields[j], tuples, k));
dims[j].onAdd(add, curr);
}
// add to dimensional indices
for (j=0; j<m; ++j) {
key = fields[j].fname;
add = adds[key] || (adds[key] = indices[key].insert(fields[j], tuples, k));
dims[j].onAdd(add, curr);
}
// set previous filters, output if passes at least one filter
for (; k<n; ++k) {
prev[k] = all;
if (curr[k] !== all) out.push(k);
}
};
// set previous filters, output if passes at least one filter
for (; k<n; ++k) {
prev[k] = all;
if (curr[k] !== all) out.push(k);
}
},
prototype.modify = function(pulse, output) {
var out = output.mod,
bits = this.value,
curr = bits.curr(),
all = bits.all(),
tuples = pulse.mod,
i, n, k;
modify(pulse, output) {
let out = output.mod,
bits = this.value,
curr = bits.curr(),
all = bits.all(),
tuples = pulse.mod,
i, n, k;
for (i=0, n=tuples.length; i<n; ++i) {
k = tuples[i]._index;
if (curr[k] !== all) out.push(k);
}
};
for (i=0, n=tuples.length; i<n; ++i) {
k = tuples[i]._index;
if (curr[k] !== all) out.push(k);
}
},
prototype.remove = function(_, pulse, output) {
var indices = this._indices,
bits = this.value,
curr = bits.curr(),
prev = bits.prev(),
all = bits.all(),
map = {},
out = output.rem,
tuples = pulse.rem,
i, n, k, f;
remove(_, pulse, output) {
let indices = this._indices,
bits = this.value,
curr = bits.curr(),
prev = bits.prev(),
all = bits.all(),
map = {},
out = output.rem,
tuples = pulse.rem,
i, n, k, f;
// process tuples, output if passes at least one filter
for (i=0, n=tuples.length; i<n; ++i) {
k = tuples[i]._index;
map[k] = 1; // build index map
prev[k] = (f = curr[k]);
curr[k] = all;
if (f !== all) out.push(k);
}
// process tuples, output if passes at least one filter
for (i=0, n=tuples.length; i<n; ++i) {
k = tuples[i]._index;
map[k] = 1; // build index map
prev[k] = (f = curr[k]);
curr[k] = all;
if (f !== all) out.push(k);
}
// remove from dimensional indices
for (k in indices) {
indices[k].remove(n, map);
}
// remove from dimensional indices
for (k in indices) {
indices[k].remove(n, map);
}
this.reindex(pulse, n, map);
return map;
};
this.reindex(pulse, n, map);
return map;
},
// reindex filters and indices after propagation completes
prototype.reindex = function(pulse, num, map) {
var indices = this._indices,
bits = this.value;
// reindex filters and indices after propagation completes
reindex(pulse, num, map) {
const indices = this._indices,
bits = this.value;
pulse.runAfter(function() {
var indexMap = bits.remove(num, map);
for (var key in indices) indices[key].reindex(indexMap);
});
};
pulse.runAfter(() => {
const indexMap = bits.remove(num, map);
for (const key in indices) indices[key].reindex(indexMap);
});
},
prototype.update = function(_, pulse, output) {
var dims = this._dims,
query = _.query,
stamp = pulse.stamp,
m = dims.length,
mask = 0, i, q;
update(_, pulse, output) {
let dims = this._dims,
query = _.query,
stamp = pulse.stamp,
m = dims.length,
mask = 0, i, q;
// survey how many queries have changed
output.filters = 0;
for (q=0; q<m; ++q) {
if (_.modified('query', q)) { i = q; ++mask; }
}
// survey how many queries have changed
output.filters = 0;
for (q=0; q<m; ++q) {
if (_.modified('query', q)) { i = q; ++mask; }
}
if (mask === 1) {
// only one query changed, use more efficient update
mask = dims[i].one;
this.incrementOne(dims[i], query[i], output.add, output.rem);
} else {
// multiple queries changed, perform full record keeping
for (q=0, mask=0; q<m; ++q) {
if (!_.modified('query', q)) continue;
mask |= dims[q].one;
this.incrementAll(dims[q], query[q], stamp, output.add);
output.rem = output.add; // duplicate add/rem for downstream resolve
if (mask === 1) {
// only one query changed, use more efficient update
mask = dims[i].one;
this.incrementOne(dims[i], query[i], output.add, output.rem);
} else {
// multiple queries changed, perform full record keeping
for (q=0, mask=0; q<m; ++q) {
if (!_.modified('query', q)) continue;
mask |= dims[q].one;
this.incrementAll(dims[q], query[q], stamp, output.add);
output.rem = output.add; // duplicate add/rem for downstream resolve
}
}
}
return mask;
};
return mask;
},
prototype.incrementAll = function(dim, query, stamp, out) {
var bits = this.value,
seen = bits.seen(),
curr = bits.curr(),
prev = bits.prev(),
index = dim.index(),
old = dim.bisect(dim.range),
range = dim.bisect(query),
lo1 = range[0],
hi1 = range[1],
lo0 = old[0],
hi0 = old[1],
one = dim.one,
i, j, k;
incrementAll(dim, query, stamp, out) {
let bits = this.value,
seen = bits.seen(),
curr = bits.curr(),
prev = bits.prev(),
index = dim.index(),
old = dim.bisect(dim.range),
range = dim.bisect(query),
lo1 = range[0],
hi1 = range[1],
lo0 = old[0],
hi0 = old[1],
one = dim.one,
i, j, k;
// Fast incremental update based on previous lo index.
if (lo1 < lo0) {
for (i = lo1, j = Math.min(lo0, hi1); i < j; ++i) {
k = index[i];
if (seen[k] !== stamp) {
prev[k] = curr[k];
seen[k] = stamp;
out.push(k);
// Fast incremental update based on previous lo index.
if (lo1 < lo0) {
for (i = lo1, j = Math.min(lo0, hi1); i < j; ++i) {
k = index[i];
if (seen[k] !== stamp) {
prev[k] = curr[k];
seen[k] = stamp;
out.push(k);
}
curr[k] ^= one;
}
curr[k] ^= one;
}
} else if (lo1 > lo0) {
for (i = lo0, j = Math.min(lo1, hi0); i < j; ++i) {
k = index[i];
if (seen[k] !== stamp) {
prev[k] = curr[k];
seen[k] = stamp;
out.push(k);
} else if (lo1 > lo0) {
for (i = lo0, j = Math.min(lo1, hi0); i < j; ++i) {
k = index[i];
if (seen[k] !== stamp) {
prev[k] = curr[k];
seen[k] = stamp;
out.push(k);
}
curr[k] ^= one;
}
curr[k] ^= one;
}
}
// Fast incremental update based on previous hi index.
if (hi1 > hi0) {
for (i = Math.max(lo1, hi0), j = hi1; i < j; ++i) {
k = index[i];
if (seen[k] !== stamp) {
prev[k] = curr[k];
seen[k] = stamp;
out.push(k);
// Fast incremental update based on previous hi index.
if (hi1 > hi0) {
for (i = Math.max(lo1, hi0), j = hi1; i < j; ++i) {
k = index[i];
if (seen[k] !== stamp) {
prev[k] = curr[k];
seen[k] = stamp;
out.push(k);
}
curr[k] ^= one;
}
curr[k] ^= one;
}
} else if (hi1 < hi0) {
for (i = Math.max(lo0, hi1), j = hi0; i < j; ++i) {
k = index[i];
if (seen[k] !== stamp) {
prev[k] = curr[k];
seen[k] = stamp;
out.push(k);
} else if (hi1 < hi0) {
for (i = Math.max(lo0, hi1), j = hi0; i < j; ++i) {
k = index[i];
if (seen[k] !== stamp) {
prev[k] = curr[k];
seen[k] = stamp;
out.push(k);
}
curr[k] ^= one;
}
curr[k] ^= one;
}
}
dim.range = query.slice();
};
dim.range = query.slice();
},
prototype.incrementOne = function(dim, query, add, rem) {
var bits = this.value,
curr = bits.curr(),
index = dim.index(),
old = dim.bisect(dim.range),
range = dim.bisect(query),
lo1 = range[0],
hi1 = range[1],
lo0 = old[0],
hi0 = old[1],
one = dim.one,
i, j, k;
incrementOne(dim, query, add, rem) {
let bits = this.value,
curr = bits.curr(),
index = dim.index(),
old = dim.bisect(dim.range),
range = dim.bisect(query),
lo1 = range[0],
hi1 = range[1],
lo0 = old[0],
hi0 = old[1],
one = dim.one,
i, j, k;
// Fast incremental update based on previous lo index.
if (lo1 < lo0) {
for (i = lo1, j = Math.min(lo0, hi1); i < j; ++i) {
k = index[i];
curr[k] ^= one;
add.push(k);
// Fast incremental update based on previous lo index.
if (lo1 < lo0) {
for (i = lo1, j = Math.min(lo0, hi1); i < j; ++i) {
k = index[i];
curr[k] ^= one;
add.push(k);
}
} else if (lo1 > lo0) {
for (i = lo0, j = Math.min(lo1, hi0); i < j; ++i) {
k = index[i];
curr[k] ^= one;
rem.push(k);
}
}
} else if (lo1 > lo0) {
for (i = lo0, j = Math.min(lo1, hi0); i < j; ++i) {
k = index[i];
curr[k] ^= one;
rem.push(k);
// Fast incremental update based on previous hi index.
if (hi1 > hi0) {
for (i = Math.max(lo1, hi0), j = hi1; i < j; ++i) {
k = index[i];
curr[k] ^= one;
add.push(k);
}
} else if (hi1 < hi0) {
for (i = Math.max(lo0, hi1), j = hi0; i < j; ++i) {
k = index[i];
curr[k] ^= one;
rem.push(k);
}
}
}
// Fast incremental update based on previous hi index.
if (hi1 > hi0) {
for (i = Math.max(lo1, hi0), j = hi1; i < j; ++i) {
k = index[i];
curr[k] ^= one;
add.push(k);
}
} else if (hi1 < hi0) {
for (i = Math.max(lo0, hi1), j = hi0; i < j; ++i) {
k = index[i];
curr[k] ^= one;
rem.push(k);
}
dim.range = query.slice();
}
dim.range = query.slice();
};
});
export default function(index, i, query) {
var bit = (1 << i);
const bit = (1 << i);

@@ -12,4 +12,4 @@ return {

onAdd: function(added, curr) {
var dim = this,
onAdd(added, curr) {
let dim = this,
range = dim.bisect(dim.range, added.value),

@@ -16,0 +16,0 @@ idx = added.index,

@@ -28,48 +28,45 @@ import {Transform} from 'vega-dataflow';

var prototype = inherits(ResolveFilter, Transform);
inherits(ResolveFilter, Transform, {
transform(_, pulse) {
const ignore = ~(_.ignore || 0), // bit mask where zeros -> dims to ignore
bitmap = _.filter,
mask = bitmap.mask;
prototype.transform = function(_, pulse) {
var ignore = ~(_.ignore || 0), // bit mask where zeros -> dims to ignore
bitmap = _.filter,
mask = bitmap.mask;
// exit early if no relevant filter changes
if ((mask & ignore) === 0) return pulse.StopPropagation;
// exit early if no relevant filter changes
if ((mask & ignore) === 0) return pulse.StopPropagation;
const output = pulse.fork(pulse.ALL),
data = bitmap.data(),
curr = bitmap.curr(),
prev = bitmap.prev(),
pass = k => !(curr[k] & ignore) ? data[k] : null;
var output = pulse.fork(pulse.ALL),
data = bitmap.data(),
curr = bitmap.curr(),
prev = bitmap.prev(),
pass = function(k) {
return !(curr[k] & ignore) ? data[k] : null;
};
// propagate all mod tuples that pass the filter
output.filter(output.MOD, pass);
// propagate all mod tuples that pass the filter
output.filter(output.MOD, pass);
// determine add & rem tuples via filter functions
// for efficiency, we do *not* populate new arrays,
// instead we add filter functions applied downstream
// determine add & rem tuples via filter functions
// for efficiency, we do *not* populate new arrays,
// instead we add filter functions applied downstream
if (!(mask & (mask-1))) { // only one filter changed
output.filter(output.ADD, pass);
output.filter(output.REM, k =>
(curr[k] & ignore) === mask ? data[k] : null);
if (!(mask & (mask-1))) { // only one filter changed
output.filter(output.ADD, pass);
output.filter(output.REM, function(k) {
return (curr[k] & ignore) === mask ? data[k] : null;
});
} else { // multiple filters changed
output.filter(output.ADD, k => {
const c = curr[k] & ignore,
f = !c && (c ^ (prev[k] & ignore));
return f ? data[k] : null;
});
output.filter(output.REM, k => {
const c = curr[k] & ignore,
f = c && !(c ^ (c ^ (prev[k] & ignore)));
return f ? data[k] : null;
});
}
} else { // multiple filters changed
output.filter(output.ADD, function(k) {
var c = curr[k] & ignore,
f = !c && (c ^ (prev[k] & ignore));
return f ? data[k] : null;
});
output.filter(output.REM, function(k) {
var c = curr[k] & ignore,
f = c && !(c ^ (c ^ (prev[k] & ignore)));
return f ? data[k] : null;
});
// add filter to source data in case of reflow...
return output.filter(output.SOURCE, t => pass(t._index));
}
// add filter to source data in case of reflow...
return output.filter(output.SOURCE, function(t) { return pass(t._index); });
};
});

@@ -8,3 +8,3 @@ import {array32} from './arrays';

export default function SortedIndex() {
var index = array32(0),
let index = array32(0),
value = [],

@@ -16,3 +16,3 @@ size = 0;

var n0 = size,
let n0 = size,
n1 = data.length,

@@ -49,3 +49,3 @@ addv = Array(n1),

// map: index -> remove
var n = size,
let n = size,
idx, i, j;

@@ -69,3 +69,3 @@

function reindex(map) {
for (var i=0, n=size; i<n; ++i) {
for (let i=0, n=size; i<n; ++i) {
index[i] = map[index[i]];

@@ -76,3 +76,3 @@ }

function bisect(range, array) {
var n;
let n;
if (array) {

@@ -95,4 +95,4 @@ n = array.length;

reindex: reindex,
index: function() { return index; },
size: function() { return size; }
index: () => index,
size: () => size
};

@@ -102,5 +102,5 @@ }

function sort(values, index) {
values.sort.call(index, function(a, b) {
var x = values[a],
y = values[b];
values.sort.call(index, (a, b) => {
const x = values[a],
y = values[b];
return x < y ? -1 : x > y ? 1 : 0;

@@ -112,3 +112,3 @@ });

function merge(base, value0, index0, n0, value1, index1, n1, value, index) {
var i0 = 0, i1 = 0, i;
let i0 = 0, i1 = 0, i;

@@ -115,0 +115,0 @@ for (i=0; i0 < n0 && i1 < n1; ++i) {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc