@rocicorp/zero 1.11.0-canary.23 → 1.11.0-canary.25
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/out/shared/src/centroid.d.ts +0 -1
- package/out/shared/src/centroid.d.ts.map +1 -1
- package/out/shared/src/centroid.js +1 -4
- package/out/shared/src/centroid.js.map +1 -1
- package/out/shared/src/tdigest.d.ts +10 -0
- package/out/shared/src/tdigest.d.ts.map +1 -1
- package/out/shared/src/tdigest.js +147 -63
- package/out/shared/src/tdigest.js.map +1 -1
- package/out/z2s/src/compiler.d.ts.map +1 -1
- package/out/z2s/src/compiler.js +9 -5
- package/out/z2s/src/compiler.js.map +1 -1
- package/out/z2s/src/sql.d.ts.map +1 -1
- package/out/z2s/src/sql.js +7 -3
- package/out/z2s/src/sql.js.map +1 -1
- package/out/zero/package.js +1 -1
- package/out/zero/package.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +5 -0
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +14 -0
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/db/migration-lite.d.ts.map +1 -1
- package/out/zero-cache/src/db/migration-lite.js +5 -3
- package/out/zero-cache/src/db/migration-lite.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +5 -1
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts +38 -1
- package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-restore.js +27 -10
- package/out/zero-cache/src/services/change-source/common/replica-restore.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source-init.js +29 -13
- package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.d.ts +22 -1
- package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.js +80 -26
- package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
- package/out/zero-cache/src/services/litestream/config-v5.yml +1 -0
- package/out/zero-cache/src/services/litestream/wal-keeper.d.ts +33 -0
- package/out/zero-cache/src/services/litestream/wal-keeper.d.ts.map +1 -0
- package/out/zero-cache/src/services/litestream/wal-keeper.js +49 -0
- package/out/zero-cache/src/services/litestream/wal-keeper.js.map +1 -0
- package/out/zero-cache/src/services/replicator/change-processor.js +2 -0
- package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
- package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
- package/out/zero-cache/src/services/run-ast.js +14 -7
- package/out/zero-cache/src/services/run-ast.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +8 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js +51 -9
- package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts +25 -9
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js +76 -38
- package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +20 -2
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +103 -41
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/types.d.ts +1 -106
- package/out/zero-cache/src/services/view-syncer/schema/types.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/types.js +5 -20
- package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +10 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +45 -8
- package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +17 -16
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/pg-data-type.d.ts +2 -0
- package/out/zero-cache/src/types/pg-data-type.d.ts.map +1 -1
- package/out/zero-cache/src/types/pg-data-type.js +6 -1
- package/out/zero-cache/src/types/pg-data-type.js.map +1 -1
- package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/workers/replicator.js +15 -7
- package/out/zero-cache/src/workers/replicator.js.map +1 -1
- package/out/zero-client/src/client/context.d.ts +1 -1
- package/out/zero-client/src/client/context.d.ts.map +1 -1
- package/out/zero-client/src/client/context.js +2 -1
- package/out/zero-client/src/client/context.js.map +1 -1
- package/out/zero-client/src/client/inspector/lazy-inspector.js +1 -1
- package/out/zero-client/src/client/query-manager.d.ts +9 -0
- package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/query-manager.js +3 -3
- package/out/zero-client/src/client/query-manager.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero.js +1 -1
- package/out/zero-server/src/schema.d.ts.map +1 -1
- package/out/zero-server/src/schema.js +1 -0
- package/out/zero-server/src/schema.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts +1 -1
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +1 -1
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/query/measure-push-operator.d.ts +7 -1
- package/out/zql/src/query/measure-push-operator.d.ts.map +1 -1
- package/out/zql/src/query/measure-push-operator.js +22 -4
- package/out/zql/src/query/measure-push-operator.js.map +1 -1
- package/out/zqlite/src/table-source.d.ts +5 -0
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +22 -17
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +1 -1
- package/out/zql/src/ivm/connection-index.d.ts +0 -68
- package/out/zql/src/ivm/connection-index.d.ts.map +0 -1
- package/out/zql/src/ivm/connection-index.js +0 -149
- package/out/zql/src/ivm/connection-index.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"centroid.d.ts","sourceRoot":"","sources":["../../../../shared/src/centroid.ts"],"names":[],"mappings":"AAIA,qBAAa,QAAQ;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IAEf,YAAY,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAGvC;IAED,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,CAWrB;CACF;AAED,qEAAqE;AACrE,MAAM,MAAM,YAAY,GAAG,QAAQ,EAAE,CAAC
|
|
1
|
+
{"version":3,"file":"centroid.d.ts","sourceRoot":"","sources":["../../../../shared/src/centroid.ts"],"names":[],"mappings":"AAIA,qBAAa,QAAQ;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IAEf,YAAY,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAGvC;IAED,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,CAWrB;CACF;AAED,qEAAqE;AACrE,MAAM,MAAM,YAAY,GAAG,QAAQ,EAAE,CAAC"}
|
|
@@ -17,10 +17,7 @@ var Centroid = class {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
|
-
function sortCentroidList(centroids) {
|
|
21
|
-
centroids.sort((a, b) => a.mean - b.mean);
|
|
22
|
-
}
|
|
23
20
|
//#endregion
|
|
24
|
-
export { Centroid
|
|
21
|
+
export { Centroid };
|
|
25
22
|
|
|
26
23
|
//# sourceMappingURL=centroid.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"centroid.js","names":[],"sources":["../../../../shared/src/centroid.ts"],"sourcesContent":["// Apache License 2.0\n// https://github.com/influxdata/tdigest\n\n// Centroid average position of all points in a shape\nexport class Centroid {\n mean: number;\n weight: number;\n\n constructor(mean: number, weight: number) {\n this.mean = mean;\n this.weight = weight;\n }\n\n add(r: Centroid): void {\n if (r.weight < 0) {\n throw new Error('centroid weight cannot be less than zero');\n }\n if (this.weight !== 0) {\n this.weight += r.weight;\n this.mean += (r.weight * (r.mean - this.mean)) / this.weight;\n } else {\n this.weight = r.weight;\n this.mean = r.mean;\n }\n }\n}\n\n/** CentroidList is sorted by the mean of the centroid, ascending. */\nexport type CentroidList = Centroid[];\n
|
|
1
|
+
{"version":3,"file":"centroid.js","names":[],"sources":["../../../../shared/src/centroid.ts"],"sourcesContent":["// Apache License 2.0\n// https://github.com/influxdata/tdigest\n\n// Centroid average position of all points in a shape\nexport class Centroid {\n mean: number;\n weight: number;\n\n constructor(mean: number, weight: number) {\n this.mean = mean;\n this.weight = weight;\n }\n\n add(r: Centroid): void {\n if (r.weight < 0) {\n throw new Error('centroid weight cannot be less than zero');\n }\n if (this.weight !== 0) {\n this.weight += r.weight;\n this.mean += (r.weight * (r.mean - this.mean)) / this.weight;\n } else {\n this.weight = r.weight;\n this.mean = r.mean;\n }\n }\n}\n\n/** CentroidList is sorted by the mean of the centroid, ascending. */\nexport type CentroidList = Centroid[];\n"],"mappings":";AAIA,IAAa,WAAb,MAAsB;CACpB;CACA;CAEA,YAAY,MAAc,QAAgB;EACxC,KAAK,OAAO;EACZ,KAAK,SAAS;CAChB;CAEA,IAAI,GAAmB;EACrB,IAAI,EAAE,SAAS,GACb,MAAM,IAAI,MAAM,0CAA0C;EAE5D,IAAI,KAAK,WAAW,GAAG;GACrB,KAAK,UAAU,EAAE;GACjB,KAAK,QAAS,EAAE,UAAU,EAAE,OAAO,KAAK,QAAS,KAAK;EACxD,OAAO;GACL,KAAK,SAAS,EAAE;GAChB,KAAK,OAAO,EAAE;EAChB;CACF;AACF"}
|
|
@@ -8,6 +8,12 @@ export interface ReadonlyTDigest {
|
|
|
8
8
|
export declare class TDigest {
|
|
9
9
|
#private;
|
|
10
10
|
readonly compression: number;
|
|
11
|
+
/**
|
|
12
|
+
* A digest keeps roughly `compression` centroids, and buffers up to eight
|
|
13
|
+
* times as many values between merges. The Go original defaults to 1000;
|
|
14
|
+
* 100 keeps p50, p95 and p99 within about 0.5% for a tenth of the memory
|
|
15
|
+
* and serialized size, which is plenty for the inspector's percentiles.
|
|
16
|
+
*/
|
|
11
17
|
constructor(compression?: number);
|
|
12
18
|
/**
|
|
13
19
|
* fromJSON creates a TDigest from a JSON-serializable representation.
|
|
@@ -15,6 +21,10 @@ export declare class TDigest {
|
|
|
15
21
|
*/
|
|
16
22
|
static fromJSON(data: Readonly<TDigestJSON>): TDigest;
|
|
17
23
|
reset(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Adds a value with the given weight.
|
|
26
|
+
* Weights which are not a number or are <= 0 are ignored, as are NaN means.
|
|
27
|
+
*/
|
|
18
28
|
add(mean: number, weight?: number): void;
|
|
19
29
|
/** AddCentroidList can quickly add multiple centroids. */
|
|
20
30
|
addCentroidList(centroidList: CentroidList): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tdigest.d.ts","sourceRoot":"","sources":["../../../../shared/src/tdigest.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"tdigest.d.ts","sourceRoot":"","sources":["../../../../shared/src/tdigest.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,QAAQ,EAAE,KAAK,YAAY,EAAC,MAAM,eAAe,CAAC;AAC1D,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,qBAAqB,CAAC;AAErD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CACrC;AAcD,qBAAa,OAAO;;IAClB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAqB7B;;;;;OAKG;IACH,YAAY,WAAW,GAAE,MAAY,EAOpC;IAED;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,OAAO,CASpD;IAED,KAAK,IAAI,IAAI,CASZ;IAED;;;OAGG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAU,GAAG,IAAI,CAiB1C;IAED,0DAA0D;IAC1D,eAAe,CAAC,YAAY,EAAE,YAAY,QAIzC;IAED;;;OAGG;IACH,WAAW,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,CAE7B;IAED;;;;QAII;IACJ,KAAK,CAAC,EAAE,EAAE,OAAO,QAShB;IAiHD;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,GAAE,YAAiB,GAAG,YAAY,CAO7C;IAED,KAAK,IAAI,MAAM,CAMd;IAED;;;OAGG;IACH,MAAM,IAAI,WAAW,CAOpB;IA6BD,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAqC1B;IAED;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CA2ErB;CAgBF;AAID,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoB3D"}
|
|
@@ -1,21 +1,37 @@
|
|
|
1
1
|
import { binarySearch } from "./binary-search.js";
|
|
2
|
-
import { Centroid
|
|
2
|
+
import { Centroid } from "./centroid.js";
|
|
3
3
|
//#region ../shared/src/tdigest.ts
|
|
4
|
+
/** Initial capacity of the buffer of unprocessed values. */
|
|
5
|
+
var INITIAL_CAPACITY = 16;
|
|
4
6
|
var TDigest = class TDigest {
|
|
5
7
|
compression;
|
|
6
|
-
#maxProcessed;
|
|
7
8
|
#maxUnprocessed;
|
|
8
|
-
|
|
9
|
-
#
|
|
9
|
+
/** Means of the processed centroids, ascending. */
|
|
10
|
+
#means;
|
|
11
|
+
/** Weights of the processed centroids, parallel to `#means`. */
|
|
12
|
+
#weights;
|
|
13
|
+
/** Means of the values added since the last `#process`, in order. */
|
|
14
|
+
#unprocessedMeans;
|
|
15
|
+
/** Weights of the unprocessed values, parallel to `#unprocessedMeans`. */
|
|
16
|
+
#unprocessedWeights;
|
|
17
|
+
#unprocessedCount;
|
|
10
18
|
#cumulative;
|
|
11
19
|
#processedWeight;
|
|
12
20
|
#unprocessedWeight;
|
|
13
21
|
#min;
|
|
14
22
|
#max;
|
|
15
|
-
|
|
23
|
+
/**
|
|
24
|
+
* A digest keeps roughly `compression` centroids, and buffers up to eight
|
|
25
|
+
* times as many values between merges. The Go original defaults to 1000;
|
|
26
|
+
* 100 keeps p50, p95 and p99 within about 0.5% for a tenth of the memory
|
|
27
|
+
* and serialized size, which is plenty for the inspector's percentiles.
|
|
28
|
+
*/
|
|
29
|
+
constructor(compression = 100) {
|
|
16
30
|
this.compression = compression;
|
|
17
|
-
this.#maxProcessed = processedSize(0, this.compression);
|
|
18
31
|
this.#maxUnprocessed = unprocessedSize(0, this.compression);
|
|
32
|
+
const capacity = Math.min(INITIAL_CAPACITY, this.#maxUnprocessed + 1);
|
|
33
|
+
this.#unprocessedMeans = new Float64Array(capacity);
|
|
34
|
+
this.#unprocessedWeights = new Float64Array(capacity);
|
|
19
35
|
this.reset();
|
|
20
36
|
}
|
|
21
37
|
/**
|
|
@@ -29,30 +45,39 @@ var TDigest = class TDigest {
|
|
|
29
45
|
return digest;
|
|
30
46
|
}
|
|
31
47
|
reset() {
|
|
32
|
-
this.#
|
|
33
|
-
this.#
|
|
48
|
+
this.#means = [];
|
|
49
|
+
this.#weights = [];
|
|
50
|
+
this.#unprocessedCount = 0;
|
|
34
51
|
this.#cumulative = [];
|
|
35
52
|
this.#processedWeight = 0;
|
|
36
53
|
this.#unprocessedWeight = 0;
|
|
37
54
|
this.#min = Number.MAX_VALUE;
|
|
38
55
|
this.#max = -Number.MAX_VALUE;
|
|
39
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Adds a value with the given weight.
|
|
59
|
+
* Weights which are not a number or are <= 0 are ignored, as are NaN means.
|
|
60
|
+
*/
|
|
40
61
|
add(mean, weight = 1) {
|
|
41
|
-
|
|
62
|
+
if (Number.isNaN(mean) || weight <= 0 || !Number.isFinite(weight)) return;
|
|
63
|
+
const n = this.#unprocessedCount;
|
|
64
|
+
if (n === this.#unprocessedMeans.length) this.#grow();
|
|
65
|
+
this.#unprocessedMeans[n] = mean;
|
|
66
|
+
this.#unprocessedWeights[n] = weight;
|
|
67
|
+
this.#unprocessedCount = n + 1;
|
|
68
|
+
this.#unprocessedWeight += weight;
|
|
69
|
+
if (this.#unprocessedCount > this.#maxUnprocessed) this.#process();
|
|
42
70
|
}
|
|
43
71
|
/** AddCentroidList can quickly add multiple centroids. */
|
|
44
72
|
addCentroidList(centroidList) {
|
|
45
|
-
for (const c of centroidList) this.
|
|
73
|
+
for (const c of centroidList) this.add(c.mean, c.weight);
|
|
46
74
|
}
|
|
47
75
|
/**
|
|
48
76
|
* AddCentroid adds a single centroid.
|
|
49
77
|
* Weights which are not a number or are <= 0 are ignored, as are NaN means.
|
|
50
78
|
*/
|
|
51
79
|
addCentroid(c) {
|
|
52
|
-
|
|
53
|
-
this.#unprocessed.push(new Centroid(c.mean, c.weight));
|
|
54
|
-
this.#unprocessedWeight += c.weight;
|
|
55
|
-
if (this.#processed.length > this.#maxProcessed || this.#unprocessed.length > this.#maxUnprocessed) this.#process();
|
|
80
|
+
this.add(c.mean, c.weight);
|
|
56
81
|
}
|
|
57
82
|
/**
|
|
58
83
|
* Merges the supplied digest into this digest. Functionally equivalent to
|
|
@@ -61,35 +86,88 @@ var TDigest = class TDigest {
|
|
|
61
86
|
**/
|
|
62
87
|
merge(t2) {
|
|
63
88
|
t2.#process();
|
|
64
|
-
|
|
89
|
+
const means = t2.#means;
|
|
90
|
+
const weights = t2.#weights;
|
|
91
|
+
for (let i = 0; i < means.length; i++) this.add(means[i], weights[i]);
|
|
92
|
+
}
|
|
93
|
+
/** Doubles the unprocessed buffer, up to what `add` lets it hold. */
|
|
94
|
+
#grow() {
|
|
95
|
+
const capacity = Math.min(this.#unprocessedMeans.length * 2, this.#maxUnprocessed + 1);
|
|
96
|
+
const means = new Float64Array(capacity);
|
|
97
|
+
means.set(this.#unprocessedMeans);
|
|
98
|
+
this.#unprocessedMeans = means;
|
|
99
|
+
const weights = new Float64Array(capacity);
|
|
100
|
+
weights.set(this.#unprocessedWeights);
|
|
101
|
+
this.#unprocessedWeights = weights;
|
|
65
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Merges the unprocessed values into the centroids: walks both in order of
|
|
105
|
+
* mean, folding each into the last centroid while that stays within its
|
|
106
|
+
* size limit, and starting a new centroid otherwise.
|
|
107
|
+
*/
|
|
66
108
|
#process() {
|
|
67
|
-
if (this.#
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
109
|
+
if (this.#unprocessedCount === 0) return;
|
|
110
|
+
const [newMeans, newWeights] = this.#sortedUnprocessed();
|
|
111
|
+
const oldMeans = this.#means;
|
|
112
|
+
const oldWeights = this.#weights;
|
|
113
|
+
const n = newMeans.length;
|
|
114
|
+
const p = oldMeans.length;
|
|
115
|
+
this.#unprocessedCount = 0;
|
|
116
|
+
this.#processedWeight += this.#unprocessedWeight;
|
|
117
|
+
this.#unprocessedWeight = 0;
|
|
118
|
+
const total = this.#processedWeight;
|
|
119
|
+
const means = [];
|
|
120
|
+
const weights = [];
|
|
121
|
+
let mean = 0;
|
|
122
|
+
let weight = 0;
|
|
123
|
+
let soFar = 0;
|
|
124
|
+
let limit = 0;
|
|
125
|
+
let i = 0;
|
|
126
|
+
let j = 0;
|
|
127
|
+
while (i < n || j < p) {
|
|
128
|
+
let m;
|
|
129
|
+
let w;
|
|
130
|
+
if (i < n && (j === p || newMeans[i] <= oldMeans[j])) {
|
|
131
|
+
m = newMeans[i];
|
|
132
|
+
w = newWeights[i++];
|
|
133
|
+
} else {
|
|
134
|
+
m = oldMeans[j];
|
|
135
|
+
w = oldWeights[j++];
|
|
136
|
+
}
|
|
137
|
+
if (soFar + w <= limit) {
|
|
138
|
+
weight += w;
|
|
139
|
+
mean += w * (m - mean) / weight;
|
|
140
|
+
} else {
|
|
141
|
+
if (weight > 0) {
|
|
142
|
+
means.push(mean);
|
|
143
|
+
weights.push(weight);
|
|
87
144
|
}
|
|
145
|
+
const k = this.#integratedLocation(soFar / total);
|
|
146
|
+
limit = total * this.#integratedQ(k + 1);
|
|
147
|
+
mean = m;
|
|
148
|
+
weight = w;
|
|
88
149
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
150
|
+
soFar += w;
|
|
151
|
+
}
|
|
152
|
+
means.push(mean);
|
|
153
|
+
weights.push(weight);
|
|
154
|
+
this.#means = means;
|
|
155
|
+
this.#weights = weights;
|
|
156
|
+
this.#min = Math.min(this.#min, means[0]);
|
|
157
|
+
this.#max = Math.max(this.#max, means.at(-1));
|
|
158
|
+
}
|
|
159
|
+
/** The unprocessed means and weights, sorted by mean. */
|
|
160
|
+
#sortedUnprocessed() {
|
|
161
|
+
const n = this.#unprocessedCount;
|
|
162
|
+
const means = this.#unprocessedMeans.subarray(0, n);
|
|
163
|
+
const weights = this.#unprocessedWeights.subarray(0, n);
|
|
164
|
+
if (isSorted(means)) return [means, weights];
|
|
165
|
+
if (allEqual(weights)) {
|
|
166
|
+
means.sort();
|
|
167
|
+
return [means, weights];
|
|
92
168
|
}
|
|
169
|
+
const order = Array.from(means, (_, k) => k).sort((a, b) => means[a] - means[b]);
|
|
170
|
+
return [Float64Array.from(order, (k) => means[k]), Float64Array.from(order, (k) => weights[k])];
|
|
93
171
|
}
|
|
94
172
|
/**
|
|
95
173
|
* Centroids returns a copy of processed centroids.
|
|
@@ -100,7 +178,9 @@ var TDigest = class TDigest {
|
|
|
100
178
|
*/
|
|
101
179
|
centroids(cl = []) {
|
|
102
180
|
this.#process();
|
|
103
|
-
|
|
181
|
+
const result = [...cl];
|
|
182
|
+
for (let i = 0; i < this.#means.length; i++) result.push(new Centroid(this.#means[i], this.#weights[i]));
|
|
183
|
+
return result;
|
|
104
184
|
}
|
|
105
185
|
count() {
|
|
106
186
|
this.#process();
|
|
@@ -113,37 +193,37 @@ var TDigest = class TDigest {
|
|
|
113
193
|
toJSON() {
|
|
114
194
|
this.#process();
|
|
115
195
|
const data = [this.compression];
|
|
116
|
-
for (
|
|
196
|
+
for (let i = 0; i < this.#means.length; i++) data.push(this.#means[i], this.#weights[i]);
|
|
117
197
|
return data;
|
|
118
198
|
}
|
|
119
199
|
#updateCumulative() {
|
|
120
200
|
if (this.#cumulative.length > 0 && this.#cumulative.at(-1) === this.#processedWeight) return;
|
|
121
|
-
const n = this.#
|
|
201
|
+
const n = this.#means.length + 1;
|
|
122
202
|
if (this.#cumulative.length > n) this.#cumulative.length = n;
|
|
123
203
|
let prev = 0;
|
|
124
|
-
for (let i = 0; i < this.#
|
|
125
|
-
const cur = this.#
|
|
204
|
+
for (let i = 0; i < this.#means.length; i++) {
|
|
205
|
+
const cur = this.#weights[i];
|
|
126
206
|
this.#cumulative[i] = prev + cur / 2;
|
|
127
207
|
prev += cur;
|
|
128
208
|
}
|
|
129
|
-
this.#cumulative[this.#
|
|
209
|
+
this.#cumulative[this.#means.length] = prev;
|
|
130
210
|
}
|
|
131
211
|
quantile(q) {
|
|
132
212
|
this.#process();
|
|
133
213
|
this.#updateCumulative();
|
|
134
|
-
if (q < 0 || q > 1 || this.#
|
|
135
|
-
if (this.#
|
|
214
|
+
if (q < 0 || q > 1 || this.#means.length === 0) return NaN;
|
|
215
|
+
if (this.#means.length === 1) return this.#means[0];
|
|
136
216
|
const index = q * this.#processedWeight;
|
|
137
|
-
if (index <= this.#
|
|
217
|
+
if (index <= this.#weights[0] / 2) return this.#min + 2 * index / this.#weights[0] * (this.#means[0] - this.#min);
|
|
138
218
|
const lower = binarySearch(this.#cumulative.length, (i) => -this.#cumulative[i] + index);
|
|
139
219
|
if (lower + 1 !== this.#cumulative.length) {
|
|
140
220
|
const z1 = index - this.#cumulative[lower - 1];
|
|
141
221
|
const z2 = this.#cumulative[lower] - index;
|
|
142
|
-
return weightedAverage(this.#
|
|
222
|
+
return weightedAverage(this.#means[lower - 1], z2, this.#means[lower], z1);
|
|
143
223
|
}
|
|
144
|
-
const z1 = index - this.#processedWeight - this.#
|
|
145
|
-
const z2 = this.#
|
|
146
|
-
return weightedAverage(this.#
|
|
224
|
+
const z1 = index - this.#processedWeight - this.#weights[lower - 1] / 2;
|
|
225
|
+
const z2 = this.#weights[lower - 1] / 2 - z1;
|
|
226
|
+
return weightedAverage(this.#means.at(-1), z1, this.#max, z2);
|
|
147
227
|
}
|
|
148
228
|
/**
|
|
149
229
|
* CDF returns the cumulative distribution function for a given value x.
|
|
@@ -151,7 +231,7 @@ var TDigest = class TDigest {
|
|
|
151
231
|
cdf(x) {
|
|
152
232
|
this.#process();
|
|
153
233
|
this.#updateCumulative();
|
|
154
|
-
switch (this.#
|
|
234
|
+
switch (this.#means.length) {
|
|
155
235
|
case 0: return 0;
|
|
156
236
|
case 1: {
|
|
157
237
|
const width = this.#max - this.#min;
|
|
@@ -163,19 +243,19 @@ var TDigest = class TDigest {
|
|
|
163
243
|
}
|
|
164
244
|
if (x <= this.#min) return 0;
|
|
165
245
|
if (x >= this.#max) return 1;
|
|
166
|
-
const m0 = this.#
|
|
246
|
+
const m0 = this.#means[0];
|
|
167
247
|
if (x <= m0) {
|
|
168
|
-
if (m0 - this.#min > 0) return (x - this.#min) / (m0 - this.#min) * this.#
|
|
248
|
+
if (m0 - this.#min > 0) return (x - this.#min) / (m0 - this.#min) * this.#weights[0] / this.#processedWeight / 2;
|
|
169
249
|
return 0;
|
|
170
250
|
}
|
|
171
|
-
const mn = this.#
|
|
251
|
+
const mn = this.#means.at(-1);
|
|
172
252
|
if (x >= mn) {
|
|
173
|
-
if (this.#max - mn > 0) return 1 - (this.#max - x) / (this.#max - mn) * this.#
|
|
253
|
+
if (this.#max - mn > 0) return 1 - (this.#max - x) / (this.#max - mn) * this.#weights.at(-1) / this.#processedWeight / 2;
|
|
174
254
|
return 1;
|
|
175
255
|
}
|
|
176
|
-
const upper = binarySearch(this.#
|
|
177
|
-
const z1 = x - this.#
|
|
178
|
-
const z2 = this.#
|
|
256
|
+
const upper = binarySearch(this.#means.length, (i) => x - this.#means[i] || 1);
|
|
257
|
+
const z1 = x - this.#means[upper - 1];
|
|
258
|
+
const z2 = this.#means[upper] - x;
|
|
179
259
|
return weightedAverage(this.#cumulative[upper - 1], z2, this.#cumulative[upper], z1) / this.#processedWeight;
|
|
180
260
|
}
|
|
181
261
|
#integratedQ(k) {
|
|
@@ -185,6 +265,14 @@ var TDigest = class TDigest {
|
|
|
185
265
|
return this.compression * (Math.asin(2 * q - 1) + Math.PI / 2) / Math.PI;
|
|
186
266
|
}
|
|
187
267
|
};
|
|
268
|
+
function isSorted(values) {
|
|
269
|
+
for (let i = 1; i < values.length; i++) if (values[i] < values[i - 1]) return false;
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
function allEqual(values) {
|
|
273
|
+
for (let i = 1; i < values.length; i++) if (values[i] !== values[0]) return false;
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
188
276
|
function weightedAverage(x1, w1, x2, w2) {
|
|
189
277
|
if (x1 <= x2) return weightedAverageSorted(x1, w1, x2, w2);
|
|
190
278
|
return weightedAverageSorted(x2, w2, x1, w1);
|
|
@@ -193,10 +281,6 @@ function weightedAverageSorted(x1, w1, x2, w2) {
|
|
|
193
281
|
const x = (x1 * w1 + x2 * w2) / (w1 + w2);
|
|
194
282
|
return Math.max(x1, Math.min(x, x2));
|
|
195
283
|
}
|
|
196
|
-
function processedSize(size, compression) {
|
|
197
|
-
if (size === 0) return Math.ceil(compression) * 2;
|
|
198
|
-
return size;
|
|
199
|
-
}
|
|
200
284
|
function unprocessedSize(size, compression) {
|
|
201
285
|
if (size === 0) return Math.ceil(compression) * 8;
|
|
202
286
|
return size;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tdigest.js","names":["#maxProcessed","#maxUnprocessed","#processed","#unprocessed","#cumulative","#processedWeight","#unprocessedWeight","#min","#max","#process","#integratedQ","#integratedLocation","#updateCumulative"],"sources":["../../../../shared/src/tdigest.ts"],"sourcesContent":["// Apache License 2.0\n// https://github.com/influxdata/tdigest\n\nimport {binarySearch} from './binary-search.ts';\nimport {Centroid, sortCentroidList, type CentroidList} from './centroid.ts';\nimport type {TDigestJSON} from './tdigest-schema.ts';\n\nexport interface ReadonlyTDigest {\n readonly count: () => number;\n readonly quantile: (q: number) => number;\n readonly cdf: (x: number) => number;\n}\n\n// TDigest is a data structure for accurate on-line accumulation of\n// rank-based statistics such as quantiles and trimmed means.\nexport class TDigest {\n readonly compression: number;\n\n #maxProcessed: number;\n #maxUnprocessed: number;\n #processed!: CentroidList;\n #unprocessed!: CentroidList;\n #cumulative!: number[];\n #processedWeight!: number;\n #unprocessedWeight!: number;\n #min!: number;\n #max!: number;\n\n constructor(compression: number = 1000) {\n this.compression = compression;\n this.#maxProcessed = processedSize(0, this.compression);\n this.#maxUnprocessed = unprocessedSize(0, this.compression);\n this.reset();\n }\n\n /**\n * fromJSON creates a TDigest from a JSON-serializable representation.\n * The data should be an object with compression and centroids array.\n */\n static fromJSON(data: Readonly<TDigestJSON>): TDigest {\n const digest = new TDigest(data[0]);\n if (data.length % 2 !== 1) {\n throw new Error('Invalid centroids array');\n }\n for (let i = 1; i < data.length; i += 2) {\n digest.add(data[i], data[i + 1]);\n }\n return digest;\n }\n\n reset(): void {\n this.#processed = [];\n this.#unprocessed = [];\n this.#cumulative = [];\n this.#processedWeight = 0;\n this.#unprocessedWeight = 0;\n this.#min = Number.MAX_VALUE;\n this.#max = -Number.MAX_VALUE;\n }\n\n add(mean: number, weight: number = 1) {\n this.addCentroid(new Centroid(mean, weight));\n }\n\n /** AddCentroidList can quickly add multiple centroids. */\n addCentroidList(centroidList: CentroidList) {\n for (const c of centroidList) {\n this.addCentroid(c);\n }\n }\n\n /**\n * AddCentroid adds a single centroid.\n * Weights which are not a number or are <= 0 are ignored, as are NaN means.\n */\n addCentroid(c: Centroid): void {\n if (\n Number.isNaN(c.mean) ||\n c.weight <= 0 ||\n Number.isNaN(c.weight) ||\n !Number.isFinite(c.weight)\n ) {\n return;\n }\n\n this.#unprocessed.push(new Centroid(c.mean, c.weight));\n this.#unprocessedWeight += c.weight;\n\n if (\n this.#processed.length > this.#maxProcessed ||\n this.#unprocessed.length > this.#maxUnprocessed\n ) {\n this.#process();\n }\n }\n\n /**\n * Merges the supplied digest into this digest. Functionally equivalent to\n * calling t.AddCentroidList(t2.Centroids(nil)), but avoids making an extra\n * copy of the CentroidList.\n **/\n merge(t2: TDigest) {\n t2.#process();\n this.addCentroidList(t2.#processed);\n }\n\n #process() {\n if (\n this.#unprocessed.length > 0 ||\n this.#processed.length > this.#maxProcessed\n ) {\n // Append all processed centroids to the unprocessed list and sort\n this.#unprocessed.push(...this.#processed);\n sortCentroidList(this.#unprocessed);\n\n // Reset processed list with first centroid\n this.#processed.length = 0;\n this.#processed.push(this.#unprocessed[0]);\n\n this.#processedWeight += this.#unprocessedWeight;\n this.#unprocessedWeight = 0;\n let soFar = this.#unprocessed[0].weight;\n let limit = this.#processedWeight * this.#integratedQ(1);\n for (let i = 1; i < this.#unprocessed.length; i++) {\n const centroid = this.#unprocessed[i];\n const projected = soFar + centroid.weight;\n if (projected <= limit) {\n soFar = projected;\n // oxlint-disable-next-line typescript/no-non-null-assertion\n this.#processed.at(-1)!.add(centroid);\n } else {\n const k1 = this.#integratedLocation(soFar / this.#processedWeight);\n limit = this.#processedWeight * this.#integratedQ(k1 + 1);\n soFar += centroid.weight;\n this.#processed.push(centroid);\n }\n }\n this.#min = Math.min(this.#min, this.#processed[0].mean);\n // oxlint-disable-next-line typescript/no-non-null-assertion\n this.#max = Math.max(this.#max, this.#processed.at(-1)!.mean);\n this.#unprocessed.length = 0;\n }\n }\n\n /**\n * Centroids returns a copy of processed centroids.\n * Useful when aggregating multiple t-digests.\n *\n * Centroids are appended to the passed CentroidList; if you're re-using a\n * buffer, be sure to pass cl[:0].\n */\n centroids(cl: CentroidList = []): CentroidList {\n this.#process();\n return [...cl, ...this.#processed];\n }\n\n count(): number {\n this.#process();\n\n // this.process always updates this.processedWeight to the total count of all\n // centroids, so we don't need to re-count here.\n return this.#processedWeight;\n }\n\n /**\n * toJSON returns a JSON-serializable representation of the digest.\n * This processes the digest and returns an object with compression and centroid data.\n */\n toJSON(): TDigestJSON {\n this.#process();\n const data: TDigestJSON = [this.compression];\n for (const centroid of this.#processed) {\n data.push(centroid.mean, centroid.weight);\n }\n return data;\n }\n\n #updateCumulative() {\n // Weight can only increase, so the final cumulative value will always be\n // either equal to, or less than, the total weight. If they are the same,\n // then nothing has changed since the last update.\n if (\n this.#cumulative.length > 0 &&\n this.#cumulative.at(-1) === this.#processedWeight\n ) {\n return;\n }\n const n = this.#processed.length + 1;\n if (this.#cumulative.length > n) {\n this.#cumulative.length = n;\n }\n\n let prev = 0;\n for (let i = 0; i < this.#processed.length; i++) {\n const centroid = this.#processed[i];\n const cur = centroid.weight;\n this.#cumulative[i] = prev + cur / 2;\n prev += cur;\n }\n this.#cumulative[this.#processed.length] = prev;\n }\n\n // Quantile returns the (approximate) quantile of\n // the distribution. Accepted values for q are between 0 and 1.\n // Returns NaN if Count is zero or bad inputs.\n quantile(q: number): number {\n this.#process();\n this.#updateCumulative();\n if (q < 0 || q > 1 || this.#processed.length === 0) {\n return NaN;\n }\n if (this.#processed.length === 1) {\n return this.#processed[0].mean;\n }\n const index = q * this.#processedWeight;\n if (index <= this.#processed[0].weight / 2) {\n return (\n this.#min +\n ((2 * index) / this.#processed[0].weight) *\n (this.#processed[0].mean - this.#min)\n );\n }\n\n const lower = binarySearch(\n this.#cumulative.length,\n (i: number) => -this.#cumulative[i] + index,\n );\n\n if (lower + 1 !== this.#cumulative.length) {\n const z1 = index - this.#cumulative[lower - 1];\n const z2 = this.#cumulative[lower] - index;\n return weightedAverage(\n this.#processed[lower - 1].mean,\n z2,\n this.#processed[lower].mean,\n z1,\n );\n }\n\n const z1 =\n index - this.#processedWeight - this.#processed[lower - 1].weight / 2;\n const z2 = this.#processed[lower - 1].weight / 2 - z1;\n // oxlint-disable-next-line typescript/no-non-null-assertion\n return weightedAverage(this.#processed.at(-1)!.mean, z1, this.#max, z2);\n }\n\n /**\n * CDF returns the cumulative distribution function for a given value x.\n */\n cdf(x: number): number {\n this.#process();\n this.#updateCumulative();\n switch (this.#processed.length) {\n case 0:\n return 0;\n case 1: {\n const width = this.#max - this.#min;\n if (x <= this.#min) {\n return 0;\n }\n if (x >= this.#max) {\n return 1;\n }\n if (x - this.#min <= width) {\n // min and max are too close together to do any viable interpolation\n return 0.5;\n }\n return (x - this.#min) / width;\n }\n }\n\n if (x <= this.#min) {\n return 0;\n }\n if (x >= this.#max) {\n return 1;\n }\n const m0 = this.#processed[0].mean;\n // Left Tail\n if (x <= m0) {\n if (m0 - this.#min > 0) {\n return (\n (((x - this.#min) / (m0 - this.#min)) * this.#processed[0].weight) /\n this.#processedWeight /\n 2\n );\n }\n return 0;\n }\n // Right Tail\n // oxlint-disable-next-line typescript/no-non-null-assertion\n const mn = this.#processed.at(-1)!.mean;\n if (x >= mn) {\n if (this.#max - mn > 0) {\n return (\n 1 -\n (((this.#max - x) / (this.#max - mn)) *\n // oxlint-disable-next-line typescript/no-non-null-assertion\n this.#processed.at(-1)!.weight) /\n this.#processedWeight /\n 2\n );\n }\n return 1;\n }\n\n const upper = binarySearch(\n this.#processed.length,\n // Treat equals as greater than, so we can use the upper index\n // This is equivalent to:\n // i => this.#processed[i].mean > x ? -1 : 1,\n i => x - this.#processed[i].mean || 1,\n );\n\n const z1 = x - this.#processed[upper - 1].mean;\n const z2 = this.#processed[upper].mean - x;\n return (\n weightedAverage(\n this.#cumulative[upper - 1],\n z2,\n this.#cumulative[upper],\n z1,\n ) / this.#processedWeight\n );\n }\n\n #integratedQ(k: number): number {\n return (\n (Math.sin(\n (Math.min(k, this.compression) * Math.PI) / this.compression -\n Math.PI / 2,\n ) +\n 1) /\n 2\n );\n }\n\n #integratedLocation(q: number): number {\n return (this.compression * (Math.asin(2 * q - 1) + Math.PI / 2)) / Math.PI;\n }\n}\n\n// Calculate number of bytes needed for a tdigest of size c,\n// where c is the compression value\nexport function byteSizeForCompression(comp: number): number {\n const c = comp | 0;\n // // A centroid is 2 float64s, so we need 16 bytes for each centroid\n // float_size := 8\n // centroid_size := 2 * float_size\n\n // // Unprocessed and processed can grow up to length c\n // unprocessed_size := centroid_size * c\n // processed_size := unprocessed_size\n\n // // the cumulative field can also be of length c, but each item is a single float64\n // cumulative_size := float_size * c // <- this could also be unprocessed_size / 2\n\n // return unprocessed_size + processed_size + cumulative_size\n\n // // or, more succinctly:\n // return float_size * c * 5\n\n // or even more succinctly\n return c * 40;\n}\n\nfunction weightedAverage(\n x1: number,\n w1: number,\n x2: number,\n w2: number,\n): number {\n if (x1 <= x2) {\n return weightedAverageSorted(x1, w1, x2, w2);\n }\n return weightedAverageSorted(x2, w2, x1, w1);\n}\n\nfunction weightedAverageSorted(\n x1: number,\n w1: number,\n x2: number,\n w2: number,\n): number {\n const x = (x1 * w1 + x2 * w2) / (w1 + w2);\n return Math.max(x1, Math.min(x, x2));\n}\n\nfunction processedSize(size: number, compression: number): number {\n if (size === 0) {\n return Math.ceil(compression) * 2;\n }\n return size;\n}\n\nfunction unprocessedSize(size: number, compression: number): number {\n if (size === 0) {\n return Math.ceil(compression) * 8;\n }\n return size;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tdigest.js","names":["#maxUnprocessed","#unprocessedMeans","#unprocessedWeights","#means","#weights","#unprocessedCount","#cumulative","#processedWeight","#unprocessedWeight","#min","#max","#grow","#process","#sortedUnprocessed","#integratedLocation","#integratedQ","#updateCumulative"],"sources":["../../../../shared/src/tdigest.ts"],"sourcesContent":["// Apache License 2.0\n// https://github.com/influxdata/tdigest\n\nimport {binarySearch} from './binary-search.ts';\nimport {Centroid, type CentroidList} from './centroid.ts';\nimport type {TDigestJSON} from './tdigest-schema.ts';\n\nexport interface ReadonlyTDigest {\n readonly count: () => number;\n readonly quantile: (q: number) => number;\n readonly cdf: (x: number) => number;\n}\n\n/** Initial capacity of the buffer of unprocessed values. */\nconst INITIAL_CAPACITY = 16;\n\n// TDigest is a data structure for accurate on-line accumulation of\n// rank-based statistics such as quantiles and trimmed means.\n//\n// Unlike the Go original, centroids are kept as parallel arrays of means and\n// weights rather than as objects, so adding a value allocates nothing. New\n// values are buffered in a Float64Array and sorted with its native numeric\n// sort instead of Array.prototype.sort with a comparator. On an engine\n// without a JIT, such as Hermes in React Native, calling the comparator for\n// every comparison is what made adding values expensive.\nexport class TDigest {\n readonly compression: number;\n\n readonly #maxUnprocessed: number;\n\n /** Means of the processed centroids, ascending. */\n #means!: number[];\n /** Weights of the processed centroids, parallel to `#means`. */\n #weights!: number[];\n\n /** Means of the values added since the last `#process`, in order. */\n #unprocessedMeans: Float64Array;\n /** Weights of the unprocessed values, parallel to `#unprocessedMeans`. */\n #unprocessedWeights: Float64Array;\n #unprocessedCount!: number;\n\n #cumulative!: number[];\n #processedWeight!: number;\n #unprocessedWeight!: number;\n #min!: number;\n #max!: number;\n\n /**\n * A digest keeps roughly `compression` centroids, and buffers up to eight\n * times as many values between merges. The Go original defaults to 1000;\n * 100 keeps p50, p95 and p99 within about 0.5% for a tenth of the memory\n * and serialized size, which is plenty for the inspector's percentiles.\n */\n constructor(compression: number = 100) {\n this.compression = compression;\n this.#maxUnprocessed = unprocessedSize(0, this.compression);\n const capacity = Math.min(INITIAL_CAPACITY, this.#maxUnprocessed + 1);\n this.#unprocessedMeans = new Float64Array(capacity);\n this.#unprocessedWeights = new Float64Array(capacity);\n this.reset();\n }\n\n /**\n * fromJSON creates a TDigest from a JSON-serializable representation.\n * The data should be an object with compression and centroids array.\n */\n static fromJSON(data: Readonly<TDigestJSON>): TDigest {\n const digest = new TDigest(data[0]);\n if (data.length % 2 !== 1) {\n throw new Error('Invalid centroids array');\n }\n for (let i = 1; i < data.length; i += 2) {\n digest.add(data[i], data[i + 1]);\n }\n return digest;\n }\n\n reset(): void {\n this.#means = [];\n this.#weights = [];\n this.#unprocessedCount = 0;\n this.#cumulative = [];\n this.#processedWeight = 0;\n this.#unprocessedWeight = 0;\n this.#min = Number.MAX_VALUE;\n this.#max = -Number.MAX_VALUE;\n }\n\n /**\n * Adds a value with the given weight.\n * Weights which are not a number or are <= 0 are ignored, as are NaN means.\n */\n add(mean: number, weight: number = 1): void {\n if (Number.isNaN(mean) || weight <= 0 || !Number.isFinite(weight)) {\n return;\n }\n\n const n = this.#unprocessedCount;\n if (n === this.#unprocessedMeans.length) {\n this.#grow();\n }\n this.#unprocessedMeans[n] = mean;\n this.#unprocessedWeights[n] = weight;\n this.#unprocessedCount = n + 1;\n this.#unprocessedWeight += weight;\n\n if (this.#unprocessedCount > this.#maxUnprocessed) {\n this.#process();\n }\n }\n\n /** AddCentroidList can quickly add multiple centroids. */\n addCentroidList(centroidList: CentroidList) {\n for (const c of centroidList) {\n this.add(c.mean, c.weight);\n }\n }\n\n /**\n * AddCentroid adds a single centroid.\n * Weights which are not a number or are <= 0 are ignored, as are NaN means.\n */\n addCentroid(c: Centroid): void {\n this.add(c.mean, c.weight);\n }\n\n /**\n * Merges the supplied digest into this digest. Functionally equivalent to\n * calling t.AddCentroidList(t2.Centroids(nil)), but avoids making an extra\n * copy of the CentroidList.\n **/\n merge(t2: TDigest) {\n t2.#process();\n // #process replaces the arrays rather than changing them, so these stay\n // intact even if t2 is this digest.\n const means = t2.#means;\n const weights = t2.#weights;\n for (let i = 0; i < means.length; i++) {\n this.add(means[i], weights[i]);\n }\n }\n\n /** Doubles the unprocessed buffer, up to what `add` lets it hold. */\n #grow(): void {\n const capacity = Math.min(\n this.#unprocessedMeans.length * 2,\n this.#maxUnprocessed + 1,\n );\n const means = new Float64Array(capacity);\n means.set(this.#unprocessedMeans);\n this.#unprocessedMeans = means;\n const weights = new Float64Array(capacity);\n weights.set(this.#unprocessedWeights);\n this.#unprocessedWeights = weights;\n }\n\n /**\n * Merges the unprocessed values into the centroids: walks both in order of\n * mean, folding each into the last centroid while that stays within its\n * size limit, and starting a new centroid otherwise.\n */\n #process() {\n if (this.#unprocessedCount === 0) {\n return;\n }\n const [newMeans, newWeights] = this.#sortedUnprocessed();\n const oldMeans = this.#means;\n const oldWeights = this.#weights;\n const n = newMeans.length;\n const p = oldMeans.length;\n this.#unprocessedCount = 0;\n this.#processedWeight += this.#unprocessedWeight;\n this.#unprocessedWeight = 0;\n const total = this.#processedWeight;\n\n const means: number[] = [];\n const weights: number[] = [];\n // The centroid being built, kept in locals rather than in the arrays,\n // which is markedly faster without a JIT. Its weight is 0 until the first\n // value.\n let mean = 0;\n let weight = 0;\n let soFar = 0;\n // A limit of 0 makes the first value start a centroid, whose limit then\n // comes from the same formula as every other's. With soFar at 0 that is\n // integratedQ(1): integratedLocation(0) is exactly 0, since\n // Math.asin(-1) is -Math.PI / 2.\n let limit = 0;\n let i = 0;\n let j = 0;\n while (i < n || j < p) {\n // On a tie the new value goes first, as in the original, which appended\n // the old centroids to the new values and sorted them with a stable sort.\n let m: number;\n let w: number;\n if (i < n && (j === p || newMeans[i] <= oldMeans[j])) {\n m = newMeans[i];\n w = newWeights[i++];\n } else {\n m = oldMeans[j];\n w = oldWeights[j++];\n }\n if (soFar + w <= limit) {\n // Same arithmetic as Centroid.add.\n weight += w;\n mean += (w * (m - mean)) / weight;\n } else {\n if (weight > 0) {\n means.push(mean);\n weights.push(weight);\n }\n const k = this.#integratedLocation(soFar / total);\n limit = total * this.#integratedQ(k + 1);\n mean = m;\n weight = w;\n }\n soFar += w;\n }\n means.push(mean);\n weights.push(weight);\n\n this.#means = means;\n this.#weights = weights;\n this.#min = Math.min(this.#min, means[0]);\n // oxlint-disable-next-line typescript/no-non-null-assertion\n this.#max = Math.max(this.#max, means.at(-1)!);\n }\n\n /** The unprocessed means and weights, sorted by mean. */\n #sortedUnprocessed(): [Float64Array, Float64Array] {\n const n = this.#unprocessedCount;\n const means = this.#unprocessedMeans.subarray(0, n);\n const weights = this.#unprocessedWeights.subarray(0, n);\n // fromJSON and merge add centroids in order of mean.\n if (isSorted(means)) {\n return [means, weights];\n }\n // With one weight for all the values, sorting the means alone keeps every\n // value with its weight, and the native numeric sort needs no comparator.\n if (allEqual(weights)) {\n means.sort();\n return [means, weights];\n }\n // A stable sort, so values with equal means stay in the order added.\n const order = Array.from(means, (_, k) => k).sort(\n (a, b) => means[a] - means[b],\n );\n return [\n Float64Array.from(order, k => means[k]),\n Float64Array.from(order, k => weights[k]),\n ];\n }\n\n /**\n * Centroids returns a copy of processed centroids.\n * Useful when aggregating multiple t-digests.\n *\n * Centroids are appended to the passed CentroidList; if you're re-using a\n * buffer, be sure to pass cl[:0].\n */\n centroids(cl: CentroidList = []): CentroidList {\n this.#process();\n const result = [...cl];\n for (let i = 0; i < this.#means.length; i++) {\n result.push(new Centroid(this.#means[i], this.#weights[i]));\n }\n return result;\n }\n\n count(): number {\n this.#process();\n\n // this.process always updates this.processedWeight to the total count of all\n // centroids, so we don't need to re-count here.\n return this.#processedWeight;\n }\n\n /**\n * toJSON returns a JSON-serializable representation of the digest.\n * This processes the digest and returns an object with compression and centroid data.\n */\n toJSON(): TDigestJSON {\n this.#process();\n const data: TDigestJSON = [this.compression];\n for (let i = 0; i < this.#means.length; i++) {\n data.push(this.#means[i], this.#weights[i]);\n }\n return data;\n }\n\n #updateCumulative() {\n // Weight can only increase, so the final cumulative value will always be\n // either equal to, or less than, the total weight. If they are the same,\n // then nothing has changed since the last update.\n if (\n this.#cumulative.length > 0 &&\n this.#cumulative.at(-1) === this.#processedWeight\n ) {\n return;\n }\n const n = this.#means.length + 1;\n if (this.#cumulative.length > n) {\n this.#cumulative.length = n;\n }\n\n let prev = 0;\n for (let i = 0; i < this.#means.length; i++) {\n const cur = this.#weights[i];\n this.#cumulative[i] = prev + cur / 2;\n prev += cur;\n }\n this.#cumulative[this.#means.length] = prev;\n }\n\n // Quantile returns the (approximate) quantile of\n // the distribution. Accepted values for q are between 0 and 1.\n // Returns NaN if Count is zero or bad inputs.\n quantile(q: number): number {\n this.#process();\n this.#updateCumulative();\n if (q < 0 || q > 1 || this.#means.length === 0) {\n return NaN;\n }\n if (this.#means.length === 1) {\n return this.#means[0];\n }\n const index = q * this.#processedWeight;\n if (index <= this.#weights[0] / 2) {\n return (\n this.#min +\n ((2 * index) / this.#weights[0]) * (this.#means[0] - this.#min)\n );\n }\n\n const lower = binarySearch(\n this.#cumulative.length,\n (i: number) => -this.#cumulative[i] + index,\n );\n\n if (lower + 1 !== this.#cumulative.length) {\n const z1 = index - this.#cumulative[lower - 1];\n const z2 = this.#cumulative[lower] - index;\n return weightedAverage(\n this.#means[lower - 1],\n z2,\n this.#means[lower],\n z1,\n );\n }\n\n const z1 = index - this.#processedWeight - this.#weights[lower - 1] / 2;\n const z2 = this.#weights[lower - 1] / 2 - z1;\n // oxlint-disable-next-line typescript/no-non-null-assertion\n return weightedAverage(this.#means.at(-1)!, z1, this.#max, z2);\n }\n\n /**\n * CDF returns the cumulative distribution function for a given value x.\n */\n cdf(x: number): number {\n this.#process();\n this.#updateCumulative();\n switch (this.#means.length) {\n case 0:\n return 0;\n case 1: {\n const width = this.#max - this.#min;\n if (x <= this.#min) {\n return 0;\n }\n if (x >= this.#max) {\n return 1;\n }\n if (x - this.#min <= width) {\n // min and max are too close together to do any viable interpolation\n return 0.5;\n }\n return (x - this.#min) / width;\n }\n }\n\n if (x <= this.#min) {\n return 0;\n }\n if (x >= this.#max) {\n return 1;\n }\n const m0 = this.#means[0];\n // Left Tail\n if (x <= m0) {\n if (m0 - this.#min > 0) {\n return (\n (((x - this.#min) / (m0 - this.#min)) * this.#weights[0]) /\n this.#processedWeight /\n 2\n );\n }\n return 0;\n }\n // Right Tail\n // oxlint-disable-next-line typescript/no-non-null-assertion\n const mn = this.#means.at(-1)!;\n if (x >= mn) {\n if (this.#max - mn > 0) {\n return (\n 1 -\n (((this.#max - x) / (this.#max - mn)) *\n // oxlint-disable-next-line typescript/no-non-null-assertion\n this.#weights.at(-1)!) /\n this.#processedWeight /\n 2\n );\n }\n return 1;\n }\n\n const upper = binarySearch(\n this.#means.length,\n // Treat equals as greater than, so we can use the upper index\n // This is equivalent to:\n // i => this.#means[i] > x ? -1 : 1,\n i => x - this.#means[i] || 1,\n );\n\n const z1 = x - this.#means[upper - 1];\n const z2 = this.#means[upper] - x;\n return (\n weightedAverage(\n this.#cumulative[upper - 1],\n z2,\n this.#cumulative[upper],\n z1,\n ) / this.#processedWeight\n );\n }\n\n #integratedQ(k: number): number {\n return (\n (Math.sin(\n (Math.min(k, this.compression) * Math.PI) / this.compression -\n Math.PI / 2,\n ) +\n 1) /\n 2\n );\n }\n\n #integratedLocation(q: number): number {\n return (this.compression * (Math.asin(2 * q - 1) + Math.PI / 2)) / Math.PI;\n }\n}\n\n// Calculate number of bytes needed for a tdigest of size c,\n// where c is the compression value\nexport function byteSizeForCompression(comp: number): number {\n const c = comp | 0;\n // // A centroid is 2 float64s, so we need 16 bytes for each centroid\n // float_size := 8\n // centroid_size := 2 * float_size\n\n // // Unprocessed and processed can grow up to length c\n // unprocessed_size := centroid_size * c\n // processed_size := unprocessed_size\n\n // // the cumulative field can also be of length c, but each item is a single float64\n // cumulative_size := float_size * c // <- this could also be unprocessed_size / 2\n\n // return unprocessed_size + processed_size + cumulative_size\n\n // // or, more succinctly:\n // return float_size * c * 5\n\n // or even more succinctly\n return c * 40;\n}\n\nfunction isSorted(values: Float64Array): boolean {\n for (let i = 1; i < values.length; i++) {\n if (values[i] < values[i - 1]) {\n return false;\n }\n }\n return true;\n}\n\nfunction allEqual(values: Float64Array): boolean {\n for (let i = 1; i < values.length; i++) {\n if (values[i] !== values[0]) {\n return false;\n }\n }\n return true;\n}\n\nfunction weightedAverage(\n x1: number,\n w1: number,\n x2: number,\n w2: number,\n): number {\n if (x1 <= x2) {\n return weightedAverageSorted(x1, w1, x2, w2);\n }\n return weightedAverageSorted(x2, w2, x1, w1);\n}\n\nfunction weightedAverageSorted(\n x1: number,\n w1: number,\n x2: number,\n w2: number,\n): number {\n const x = (x1 * w1 + x2 * w2) / (w1 + w2);\n return Math.max(x1, Math.min(x, x2));\n}\n\nfunction unprocessedSize(size: number, compression: number): number {\n if (size === 0) {\n return Math.ceil(compression) * 8;\n }\n return size;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../../z2s/src/compiler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAQ7C,OAAO,EAAC,KAAK,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAExD,OAAO,KAAK,EACV,GAAG,EACH,KAAK,EAEL,kBAAkB,EAElB,WAAW,EAEX,QAAQ,EACR,eAAe,EAEhB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAEL,KAAK,UAAU,EAChB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,gCAAgC,CAAC;AAC3D,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,uCAAuC,CAAC;AACxE,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,2BAA2B,CAAC;AAUtD,KAAK,KAAK,GAAG;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,MAAM,EAAE,YAAY,CAAC;IAErB,MAAM,EAAE,UAAU,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAQF,wBAAgB,OAAO,CACrB,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,GAAG,EACR,MAAM,CAAC,EAAE,MAAM,GACd,QAAQ,CAgBV;AAiDD,wBAAgB,KAAK,CACnB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,QAAQ,EAAE,OAAO,GAAG,SAAS,GAC5B,QAAQ,CAWV;AAUD,wBAAgB,OAAO,CACrB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,QAAQ,GAAG,SAAS,EAC7B,KAAK,EAAE,KAAK,GACX,QAAQ,CAoBV;AAED,wBAAgB,KAAK,CACnB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,GAAG,SAAS,EACxB,OAAO,EAAE,QAAQ,GAAG,SAAS,EAC7B,KAAK,EAAE,KAAK,GACX,QAAQ,CA4CV;AA2KD,wBAAgB,cAAc,CAC5B,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,SAAS,eAAe,EAAE,EACxC,cAAc,EAAE,SAAS,MAAM,EAAE,GAChC,CAAC,UAAU,EAAE,KAAK,KAAK,QAAQ,CAiBjC;AAED,wBAAgB,MAAM,CACpB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,eAAe,EAC1B,KAAK,EAAE,KAAK,GACX,QAAQ,
|
|
1
|
+
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../../z2s/src/compiler.ts"],"names":[],"mappings":"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"}
|
package/out/z2s/src/compiler.js
CHANGED
|
@@ -152,16 +152,20 @@ function makeCorrelator(spec, parentFields, childZqlFields) {
|
|
|
152
152
|
}
|
|
153
153
|
function simple(spec, condition, table) {
|
|
154
154
|
switch (condition.op) {
|
|
155
|
+
case "ILIKE":
|
|
156
|
+
case "LIKE":
|
|
157
|
+
case "NOT ILIKE":
|
|
158
|
+
case "NOT LIKE": {
|
|
159
|
+
const { right } = condition;
|
|
160
|
+
assert(right.type === "literal", "Static parameters must be bound to a value before compiling to SQL");
|
|
161
|
+
return sql`${valueComparison(spec, condition.left, table, right, false)} ${sql.__dangerous__rawValue(condition.op)} ${sqlConvertSingularLiteralArg(right.value === null ? null : String(right.value))}`;
|
|
162
|
+
}
|
|
155
163
|
case "!=":
|
|
156
164
|
case "<":
|
|
157
165
|
case "<=":
|
|
158
166
|
case "=":
|
|
159
167
|
case ">":
|
|
160
|
-
case ">=":
|
|
161
|
-
case "ILIKE":
|
|
162
|
-
case "LIKE":
|
|
163
|
-
case "NOT ILIKE":
|
|
164
|
-
case "NOT LIKE": return sql`${valueComparison(spec, condition.left, table, condition.right, false)} ${sql.__dangerous__rawValue(condition.op)} ${valueComparison(spec, condition.right, table, condition.left, false)}`;
|
|
168
|
+
case ">=": return sql`${valueComparison(spec, condition.left, table, condition.right, false)} ${sql.__dangerous__rawValue(condition.op)} ${valueComparison(spec, condition.right, table, condition.left, false)}`;
|
|
165
169
|
case "NOT IN":
|
|
166
170
|
case "IN": return any(spec, condition, table);
|
|
167
171
|
case "IS":
|