@uwdata/mosaic-core 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mosaic-core.js +11493 -19779
- package/dist/mosaic-core.min.js +6 -15
- package/package.json +8 -8
- package/src/Coordinator.js +225 -55
- package/src/DataCubeIndexer.js +304 -141
- package/src/MosaicClient.js +12 -3
- package/src/QueryConsolidator.js +15 -11
- package/src/QueryManager.js +13 -5
- package/src/Selection.js +64 -12
- package/src/SelectionClause.js +22 -8
- package/src/connectors/rest.js +3 -3
- package/src/connectors/socket.js +4 -3
- package/src/connectors/wasm.js +20 -4
- package/src/index.js +10 -6
- package/src/util/AsyncDispatch.js +15 -5
- package/src/util/decode-ipc.js +11 -0
- package/src/util/field-info.js +3 -11
- package/src/util/index-columns.js +79 -80
- package/src/util/is-arrow-table.js +10 -0
- package/src/util/priority-queue.js +75 -76
- package/src/util/query-result.js +41 -8
- package/src/util/throttle.js +11 -1
- package/src/util/to-data-columns.js +60 -0
- package/src/FilterGroup.js +0 -81
- package/src/util/convert-arrow.js +0 -145
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { isArrowTable } from './is-arrow-table.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {Array | Int8Array | Uint8Array | Uint8ClampedArray
|
|
5
|
+
* | Int16Array | Uint16Array | Int32Array | Uint32Array
|
|
6
|
+
* | Float32Array | Float64Array
|
|
7
|
+
* } Arrayish - an Array or TypedArray
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {
|
|
12
|
+
* | { numRows: number, columns: Record<string,Arrayish> }
|
|
13
|
+
* | { numRows: number, values: Arrayish; }
|
|
14
|
+
* } DataColumns
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Convert input data to a set of column arrays.
|
|
19
|
+
* @param {any} data The input data.
|
|
20
|
+
* @returns {DataColumns} An object with named column arrays.
|
|
21
|
+
*/
|
|
22
|
+
export function toDataColumns(data) {
|
|
23
|
+
return isArrowTable(data)
|
|
24
|
+
? arrowToColumns(data)
|
|
25
|
+
: arrayToColumns(data);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Convert an Arrow table to a set of column arrays.
|
|
30
|
+
* @param {import('@uwdata/flechette').Table} data An Arrow Table.
|
|
31
|
+
* @returns {DataColumns} An object with named column arrays.
|
|
32
|
+
*/
|
|
33
|
+
function arrowToColumns(data) {
|
|
34
|
+
const { numRows } = data;
|
|
35
|
+
return { numRows, columns: data.toColumns() };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Convert an array of values to a set of column arrays.
|
|
40
|
+
* If the array values are objects, build out named columns.
|
|
41
|
+
* We use the keys of the first object as the column names.
|
|
42
|
+
* Otherwise, use a special "values" array.
|
|
43
|
+
* @param {object[]} data An array of data objects.
|
|
44
|
+
* @returns {DataColumns} An object with named column arrays.
|
|
45
|
+
*/
|
|
46
|
+
function arrayToColumns(data) {
|
|
47
|
+
const numRows = data.length;
|
|
48
|
+
if (typeof data[0] === 'object') {
|
|
49
|
+
const names = numRows ? Object.keys(data[0]) : [];
|
|
50
|
+
const columns = {};
|
|
51
|
+
if (names.length > 0) {
|
|
52
|
+
names.forEach(name => {
|
|
53
|
+
columns[name] = data.map(d => d[name]);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return { numRows, columns };
|
|
57
|
+
} else {
|
|
58
|
+
return { numRows, values: data };
|
|
59
|
+
}
|
|
60
|
+
}
|
package/src/FilterGroup.js
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { Coordinator } from './Coordinator.js';
|
|
2
|
-
import { DataCubeIndexer } from './DataCubeIndexer.js';
|
|
3
|
-
import { MosaicClient } from './MosaicClient.js';
|
|
4
|
-
import { Selection } from './Selection.js';
|
|
5
|
-
|
|
6
|
-
export class FilterGroup {
|
|
7
|
-
/**
|
|
8
|
-
* @param {Coordinator} coordinator The Mosaic coordinator.
|
|
9
|
-
* @param {Selection} selection The shared filter selection.
|
|
10
|
-
* @param {object|boolean} index Boolean flag or options hash for
|
|
11
|
-
* a data cube indexer. Falsy values disable indexing.
|
|
12
|
-
*/
|
|
13
|
-
constructor(coordinator, selection, index = true) {
|
|
14
|
-
this.mc = coordinator;
|
|
15
|
-
this.selection = selection;
|
|
16
|
-
/** @type {Set<MosaicClient>} */
|
|
17
|
-
this.clients = new Set();
|
|
18
|
-
/** @type {DataCubeIndexer | null} */
|
|
19
|
-
this.indexer = null;
|
|
20
|
-
this.index(index);
|
|
21
|
-
|
|
22
|
-
const { value, activate } = this.handlers = {
|
|
23
|
-
value: () => this.update(),
|
|
24
|
-
activate: clause => { this.indexer?.index(this.clients, clause); }
|
|
25
|
-
};
|
|
26
|
-
selection.addEventListener('value', value);
|
|
27
|
-
selection.addEventListener('activate', activate);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
finalize() {
|
|
31
|
-
const { value, activate } = this.handlers;
|
|
32
|
-
this.selection.removeEventListener('value', value);
|
|
33
|
-
this.selection.removeEventListener('activate', activate);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
index(state) {
|
|
37
|
-
const { selection } = this;
|
|
38
|
-
const { resolver } = selection;
|
|
39
|
-
this.indexer = state && (resolver.single || !resolver.union)
|
|
40
|
-
? new DataCubeIndexer(this.mc, { ...state, selection })
|
|
41
|
-
: null;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
reset() {
|
|
45
|
-
this.indexer?.reset();
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
add(client) {
|
|
49
|
-
(this.clients = new Set(this.clients)).add(client);
|
|
50
|
-
return this;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
remove(client) {
|
|
54
|
-
if (this.clients.has(client)) {
|
|
55
|
-
(this.clients = new Set(this.clients)).delete(client);
|
|
56
|
-
}
|
|
57
|
-
return this;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Internal method to process a selection update.
|
|
62
|
-
* The return value is passed as a selection callback value.
|
|
63
|
-
* @returns {Promise} A Promise that resolves when the update completes.
|
|
64
|
-
*/
|
|
65
|
-
update() {
|
|
66
|
-
const { mc, indexer, clients, selection } = this;
|
|
67
|
-
const hasIndex = indexer?.index(clients);
|
|
68
|
-
return hasIndex
|
|
69
|
-
? indexer.update()
|
|
70
|
-
: defaultUpdate(mc, clients, selection);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function defaultUpdate(mc, clients, selection) {
|
|
75
|
-
return Promise.all(Array.from(clients).map(client => {
|
|
76
|
-
const filter = selection.predicate(client);
|
|
77
|
-
if (filter != null) {
|
|
78
|
-
return mc.updateClient(client, client.query(filter));
|
|
79
|
-
}
|
|
80
|
-
}));
|
|
81
|
-
}
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import { DataType } from 'apache-arrow';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @typedef {import('apache-arrow').Vector} Vector
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Test if a value is an Apache Arrow table.
|
|
9
|
-
* As sometimes multiple Arrow versions may be used simultaneously,
|
|
10
|
-
* we use a "duck typing" approach and check for a getChild function.
|
|
11
|
-
* @param {*} values The value to test
|
|
12
|
-
* @returns {values is import('apache-arrow').Table} true if the value duck types as Apache Arrow data
|
|
13
|
-
*/
|
|
14
|
-
export function isArrowTable(values) {
|
|
15
|
-
return typeof values?.getChild === 'function';
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Return a JavaScript array type for an Apache Arrow column type.
|
|
20
|
-
* @param {DataType} type an Apache Arrow column type
|
|
21
|
-
* @returns a JavaScript array constructor
|
|
22
|
-
*/
|
|
23
|
-
export function convertArrowArrayType(type) {
|
|
24
|
-
return DataType.isInt(type) || DataType.isFloat(type) || DataType.isDecimal(type)
|
|
25
|
-
? Float64Array
|
|
26
|
-
: Array;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Return a function that converts Apache Arrow values to JavaScript values.
|
|
31
|
-
* Timestamps are converted to Date values.
|
|
32
|
-
* Large integers (BigInt) are converted to Float64 numbers.
|
|
33
|
-
* Fixed-point decimal values are convert to Float64 numbers.
|
|
34
|
-
* Otherwise, the default Arrow values are used.
|
|
35
|
-
* @param {DataType} type an Apache Arrow column type
|
|
36
|
-
* @returns a value conversion function
|
|
37
|
-
*/
|
|
38
|
-
export function convertArrowValue(type) {
|
|
39
|
-
// map timestamp numbers to date objects
|
|
40
|
-
if (DataType.isTimestamp(type)) {
|
|
41
|
-
return v => v == null ? v : new Date(v);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// map bigint to number
|
|
45
|
-
if (DataType.isInt(type) && type.bitWidth >= 64) {
|
|
46
|
-
return v => v == null ? v : Number(v);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// map decimal to number
|
|
50
|
-
if (DataType.isDecimal(type)) {
|
|
51
|
-
const scale = 1 / Math.pow(10, type.scale);
|
|
52
|
-
return v => v == null ? v : decimalToNumber(v, scale);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// otherwise use Arrow JS defaults
|
|
56
|
-
return v => v;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Convert an Apache Arrow column to a JavaScript array.
|
|
61
|
-
* Timestamps are converted to Date values.
|
|
62
|
-
* Large integers (BigInt) are converted to Float64 numbers.
|
|
63
|
-
* Fixed-point decimal values are convert to Float64 numbers.
|
|
64
|
-
* Otherwise, the default Arrow values are used.
|
|
65
|
-
* @param {Vector} column An Apache Arrow column
|
|
66
|
-
* @returns an array of values
|
|
67
|
-
*/
|
|
68
|
-
export function convertArrowColumn(column) {
|
|
69
|
-
const { type } = column;
|
|
70
|
-
|
|
71
|
-
// map timestamp numbers to date objects
|
|
72
|
-
if (DataType.isTimestamp(type)) {
|
|
73
|
-
const size = column.length;
|
|
74
|
-
const array = new Array(size);
|
|
75
|
-
for (let row = 0; row < size; ++row) {
|
|
76
|
-
const v = column.get(row);
|
|
77
|
-
array[row] = v == null ? null : new Date(v);
|
|
78
|
-
}
|
|
79
|
-
return array;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// map bigint to number
|
|
83
|
-
if (DataType.isInt(type) && type.bitWidth >= 64) {
|
|
84
|
-
const size = column.length;
|
|
85
|
-
const array = column.nullCount ? new Array(size) : new Float64Array(size);
|
|
86
|
-
for (let row = 0; row < size; ++row) {
|
|
87
|
-
const v = column.get(row);
|
|
88
|
-
array[row] = v == null ? null : Number(v);
|
|
89
|
-
}
|
|
90
|
-
return array;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// map decimal to number
|
|
94
|
-
if (DataType.isDecimal(type)) {
|
|
95
|
-
const scale = 1 / Math.pow(10, type.scale);
|
|
96
|
-
const size = column.length;
|
|
97
|
-
const array = column.nullCount ? new Array(size) : new Float64Array(size);
|
|
98
|
-
for (let row = 0; row < size; ++row) {
|
|
99
|
-
const v = column.get(row);
|
|
100
|
-
array[row] = v == null ? null : decimalToNumber(v, scale);
|
|
101
|
-
}
|
|
102
|
-
return array;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// if there are null values, use a standard array
|
|
106
|
-
if (column.nullCount) {
|
|
107
|
-
return Array.from(column);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// otherwise use Arrow JS defaults
|
|
111
|
-
return column.toArray();
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// generate base values for big integers
|
|
115
|
-
// represented within a Uint32Array
|
|
116
|
-
const BASE32 = Array.from(
|
|
117
|
-
{ length: 8 },
|
|
118
|
-
(_, i) => Math.pow(2, i * 32)
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Convert a fixed point decimal value to a double precision number.
|
|
123
|
-
* Note: if the value is sufficiently large the conversion may be lossy!
|
|
124
|
-
* @param {Uint32Array & { signed: boolean }} v a fixed decimal value
|
|
125
|
-
* @param {number} scale a scale factor, corresponding to the
|
|
126
|
-
* number of fractional decimal digits in the fixed point value
|
|
127
|
-
* @returns {number} the resulting number
|
|
128
|
-
*/
|
|
129
|
-
function decimalToNumber(v, scale) {
|
|
130
|
-
const n = v.length;
|
|
131
|
-
let x = 0;
|
|
132
|
-
|
|
133
|
-
if (v.signed && (v[n - 1] | 0) < 0) {
|
|
134
|
-
for (let i = 0; i < n; ++i) {
|
|
135
|
-
x += ~v[i] * BASE32[i];
|
|
136
|
-
}
|
|
137
|
-
x = -(x + 1);
|
|
138
|
-
} else {
|
|
139
|
-
for (let i = 0; i < n; ++i) {
|
|
140
|
-
x += v[i] * BASE32[i];
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return x * scale;
|
|
145
|
-
}
|