distillate 0.14.1 → 0.15.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/README.md +23 -4
- package/dist/blocked/index.cjs +1 -1
- package/dist/blocked/index.js +1 -1
- package/dist/bloom/index.cjs +6 -4
- package/dist/bloom/index.js +6 -4
- package/dist/bytes-DWGupBUE.cjs +45 -0
- package/dist/bytes-oOWlu7N5.js +34 -0
- package/dist/countmin/index.cjs +1 -1
- package/dist/countmin/index.js +1 -1
- package/dist/cuckoo/index.cjs +1 -1
- package/dist/cuckoo/index.js +1 -1
- package/dist/ddsketch/index.cjs +23 -0
- package/dist/ddsketch/index.d.cts +4 -0
- package/dist/ddsketch/index.d.ts +4 -0
- package/dist/ddsketch/index.js +4 -0
- package/dist/ddsketch/protobuf/index.cjs +297 -0
- package/dist/ddsketch/protobuf/index.d.cts +43 -0
- package/dist/ddsketch/protobuf/index.d.ts +43 -0
- package/dist/ddsketch/protobuf/index.js +294 -0
- package/dist/ddsketch-1Buc9M3P.d.cts +293 -0
- package/dist/ddsketch-Ao9louSV.cjs +930 -0
- package/dist/ddsketch-CvwWk86v.d.ts +293 -0
- package/dist/ddsketch-D3Sy8CAU.js +841 -0
- package/dist/fuse/index.cjs +1 -1
- package/dist/fuse/index.js +1 -1
- package/dist/{hasher-DOdmZ-LI.js → hasher-BQxNrCQC.js} +3 -18
- package/dist/{hasher-DPXmP7SH.cjs → hasher-CKLP9Oqe.cjs} +3 -18
- package/dist/hll/index.cjs +1 -1
- package/dist/hll/index.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/scalable/index.cjs +1 -1
- package/dist/scalable/index.js +1 -1
- package/dist/topk/index.cjs +19 -20
- package/dist/topk/index.js +19 -20
- package/package.json +17 -1
- package/dist/bytes-Be7tq1F7.js +0 -9
- package/dist/bytes-D2duG1jq.cjs +0 -14
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { i as SerializationError } from "../../serialize-CMSYFym-.js";
|
|
2
|
+
import { d as isIndexable, i as sketchFromBins, m as mappingWithGamma, o as collapsingLowestStore, r as sketchBins } from "../../ddsketch-D3Sy8CAU.js";
|
|
3
|
+
//#region src/ddsketch/protobuf/protobuf.ts
|
|
4
|
+
const KINDS = [
|
|
5
|
+
"log",
|
|
6
|
+
"linear",
|
|
7
|
+
"quadratic",
|
|
8
|
+
"cubic"
|
|
9
|
+
];
|
|
10
|
+
const VARINT = 0;
|
|
11
|
+
const FIXED64 = 1;
|
|
12
|
+
const LENGTH = 2;
|
|
13
|
+
const FIXED32 = 5;
|
|
14
|
+
var Reader = class Reader {
|
|
15
|
+
#bytes;
|
|
16
|
+
#view;
|
|
17
|
+
#at;
|
|
18
|
+
#end;
|
|
19
|
+
constructor(bytes, at = 0, end = bytes.length) {
|
|
20
|
+
this.#bytes = bytes;
|
|
21
|
+
this.#view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
22
|
+
this.#at = at;
|
|
23
|
+
this.#end = end;
|
|
24
|
+
}
|
|
25
|
+
get done() {
|
|
26
|
+
return this.#at >= this.#end;
|
|
27
|
+
}
|
|
28
|
+
varint() {
|
|
29
|
+
let value = 0;
|
|
30
|
+
for (let shift = 0; shift < 70; shift += 7) {
|
|
31
|
+
if (this.#at >= this.#end) throw new SerializationError("protobuf: truncated varint");
|
|
32
|
+
const byte = this.#bytes[this.#at++] ?? 0;
|
|
33
|
+
value += (byte & 127) * 2 ** shift;
|
|
34
|
+
if (byte < 128) return value;
|
|
35
|
+
}
|
|
36
|
+
throw new SerializationError("protobuf: varint longer than ten bytes");
|
|
37
|
+
}
|
|
38
|
+
sint32() {
|
|
39
|
+
const u = this.varint() % 2 ** 32;
|
|
40
|
+
return u >>> 1 ^ -(u & 1);
|
|
41
|
+
}
|
|
42
|
+
double() {
|
|
43
|
+
this.#need(8);
|
|
44
|
+
const value = this.#view.getFloat64(this.#at, true);
|
|
45
|
+
this.#at += 8;
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
message() {
|
|
49
|
+
const length = this.varint();
|
|
50
|
+
this.#need(length);
|
|
51
|
+
const sub = new Reader(this.#bytes, this.#at, this.#at + length);
|
|
52
|
+
this.#at += length;
|
|
53
|
+
return sub;
|
|
54
|
+
}
|
|
55
|
+
tag() {
|
|
56
|
+
const tag = this.varint();
|
|
57
|
+
return [Math.floor(tag / 8), tag % 8];
|
|
58
|
+
}
|
|
59
|
+
skip(wire) {
|
|
60
|
+
if (wire === VARINT) this.varint();
|
|
61
|
+
else if (wire === FIXED64) this.#skipBytes(8);
|
|
62
|
+
else if (wire === LENGTH) this.message();
|
|
63
|
+
else if (wire === FIXED32) this.#skipBytes(4);
|
|
64
|
+
else throw new SerializationError(`protobuf: unsupported wire type ${String(wire)}`);
|
|
65
|
+
}
|
|
66
|
+
#skipBytes(n) {
|
|
67
|
+
this.#need(n);
|
|
68
|
+
this.#at += n;
|
|
69
|
+
}
|
|
70
|
+
#need(n) {
|
|
71
|
+
if (this.#at + n > this.#end) throw new SerializationError("protobuf: field runs past the end of its message");
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
function expectWire(field, wire, want) {
|
|
75
|
+
if (wire !== want) throw new SerializationError(`protobuf: ${field} has wire type ${String(wire)}, want ${String(want)}`);
|
|
76
|
+
}
|
|
77
|
+
function readMapping(r, into) {
|
|
78
|
+
while (!r.done) {
|
|
79
|
+
const [field, wire] = r.tag();
|
|
80
|
+
if (field === 1) {
|
|
81
|
+
expectWire("gamma", wire, FIXED64);
|
|
82
|
+
into.gamma = r.double();
|
|
83
|
+
} else if (field === 2) {
|
|
84
|
+
expectWire("indexOffset", wire, FIXED64);
|
|
85
|
+
into.indexOffset = r.double();
|
|
86
|
+
} else if (field === 3) {
|
|
87
|
+
expectWire("interpolation", wire, VARINT);
|
|
88
|
+
into.interpolation = r.varint();
|
|
89
|
+
} else r.skip(wire);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function readStore(r, bins) {
|
|
93
|
+
const contiguous = [];
|
|
94
|
+
let offset = 0;
|
|
95
|
+
while (!r.done) {
|
|
96
|
+
const [field, wire] = r.tag();
|
|
97
|
+
if (field === 1) {
|
|
98
|
+
expectWire("binCounts", wire, LENGTH);
|
|
99
|
+
const entry = r.message();
|
|
100
|
+
let index = 0;
|
|
101
|
+
let count = 0;
|
|
102
|
+
while (!entry.done) {
|
|
103
|
+
const [f, w] = entry.tag();
|
|
104
|
+
if (f === 1) {
|
|
105
|
+
expectWire("binCounts key", w, VARINT);
|
|
106
|
+
index = entry.sint32();
|
|
107
|
+
} else if (f === 2) {
|
|
108
|
+
expectWire("binCounts value", w, FIXED64);
|
|
109
|
+
count = entry.double();
|
|
110
|
+
} else entry.skip(w);
|
|
111
|
+
}
|
|
112
|
+
bins.set(index, (bins.get(index) ?? 0) + count);
|
|
113
|
+
} else if (field === 2) {
|
|
114
|
+
if (wire === LENGTH) {
|
|
115
|
+
const packed = r.message();
|
|
116
|
+
while (!packed.done) contiguous.push(packed.double());
|
|
117
|
+
} else {
|
|
118
|
+
expectWire("contiguousBinCounts", wire, FIXED64);
|
|
119
|
+
contiguous.push(r.double());
|
|
120
|
+
}
|
|
121
|
+
} else if (field === 3) {
|
|
122
|
+
expectWire("contiguousBinIndexOffset", wire, VARINT);
|
|
123
|
+
offset = r.sint32();
|
|
124
|
+
} else r.skip(wire);
|
|
125
|
+
}
|
|
126
|
+
contiguous.forEach((count, i) => {
|
|
127
|
+
if (count !== 0) bins.set(offset + i, (bins.get(offset + i) ?? 0) + count);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
function fromProtobuf(bytes, options = {}) {
|
|
131
|
+
const { store = collapsingLowestStore(4096) } = options;
|
|
132
|
+
const r = new Reader(bytes);
|
|
133
|
+
const mapped = {
|
|
134
|
+
gamma: 0,
|
|
135
|
+
indexOffset: 0,
|
|
136
|
+
interpolation: 0
|
|
137
|
+
};
|
|
138
|
+
const positive = new Map();
|
|
139
|
+
const negative = new Map();
|
|
140
|
+
let zeroCount = 0;
|
|
141
|
+
while (!r.done) {
|
|
142
|
+
const [field, wire] = r.tag();
|
|
143
|
+
if (field === 1) {
|
|
144
|
+
expectWire("mapping", wire, LENGTH);
|
|
145
|
+
readMapping(r.message(), mapped);
|
|
146
|
+
} else if (field === 2) {
|
|
147
|
+
expectWire("positiveValues", wire, LENGTH);
|
|
148
|
+
readStore(r.message(), positive);
|
|
149
|
+
} else if (field === 3) {
|
|
150
|
+
expectWire("negativeValues", wire, LENGTH);
|
|
151
|
+
readStore(r.message(), negative);
|
|
152
|
+
} else if (field === 4) {
|
|
153
|
+
expectWire("zeroCount", wire, FIXED64);
|
|
154
|
+
zeroCount = r.double();
|
|
155
|
+
} else r.skip(wire);
|
|
156
|
+
}
|
|
157
|
+
const kind = KINDS[mapped.interpolation];
|
|
158
|
+
if (kind === void 0) throw new SerializationError(`protobuf: unknown interpolation ${String(mapped.interpolation)}`);
|
|
159
|
+
const { gamma, indexOffset } = mapped;
|
|
160
|
+
if (!(gamma > 1 && gamma < Infinity) || !Number.isFinite(indexOffset)) throw new SerializationError("protobuf: gamma must be finite and above 1, and indexOffset finite");
|
|
161
|
+
if (!(zeroCount >= 0 && zeroCount < Infinity)) throw new SerializationError(`protobuf: zeroCount must be finite and not negative, got ${String(zeroCount)}`);
|
|
162
|
+
const mapping = mappingWithGamma(kind, gamma, indexOffset);
|
|
163
|
+
if (!isIndexable(mapping)) throw new SerializationError("protobuf: the mapping leaves no value indexable");
|
|
164
|
+
const lo = mapping.index(mapping.minIndexableValue);
|
|
165
|
+
const hi = mapping.index(mapping.maxIndexableValue);
|
|
166
|
+
for (const bins of [positive, negative]) for (const [index, count] of bins) if (count === 0) bins.delete(index);
|
|
167
|
+
else if (!(count > 0 && count < Infinity) || index < lo || index > hi) throw new SerializationError(`protobuf: bin ${String(index)} with count ${String(count)} is not one a sketch could hold`);
|
|
168
|
+
return sketchFromBins(mapping, store, positive, negative, zeroCount);
|
|
169
|
+
}
|
|
170
|
+
function varintSize(value) {
|
|
171
|
+
let size = 1;
|
|
172
|
+
while (value >= 128) {
|
|
173
|
+
value = Math.floor(value / 128);
|
|
174
|
+
size++;
|
|
175
|
+
}
|
|
176
|
+
return size;
|
|
177
|
+
}
|
|
178
|
+
function zigzag(value) {
|
|
179
|
+
return (value << 1 ^ value >> 31) >>> 0;
|
|
180
|
+
}
|
|
181
|
+
function present(value) {
|
|
182
|
+
return value !== 0 || Object.is(value, -0);
|
|
183
|
+
}
|
|
184
|
+
function storeBody(store, sparse) {
|
|
185
|
+
const indices = [];
|
|
186
|
+
const counts = [];
|
|
187
|
+
store.forEach((index, count) => {
|
|
188
|
+
indices.push(index);
|
|
189
|
+
counts.push(count);
|
|
190
|
+
});
|
|
191
|
+
let size = 0;
|
|
192
|
+
const first = indices[0];
|
|
193
|
+
if (sparse) for (const index of indices) {
|
|
194
|
+
const entry = 1 + varintSize(zigzag(index)) + 1 + 8;
|
|
195
|
+
size += 1 + varintSize(entry) + entry;
|
|
196
|
+
}
|
|
197
|
+
else if (first !== void 0) {
|
|
198
|
+
const packed = 8 * ((indices.at(-1) ?? first) - first + 1);
|
|
199
|
+
size = 1 + varintSize(packed) + packed;
|
|
200
|
+
if (first !== 0) size += 1 + varintSize(zigzag(first));
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
indices,
|
|
204
|
+
counts,
|
|
205
|
+
sparse,
|
|
206
|
+
size
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
var Writer = class {
|
|
210
|
+
bytes;
|
|
211
|
+
#view;
|
|
212
|
+
#at = 0;
|
|
213
|
+
constructor(size) {
|
|
214
|
+
this.bytes = new Uint8Array(size);
|
|
215
|
+
this.#view = new DataView(this.bytes.buffer);
|
|
216
|
+
}
|
|
217
|
+
tag(field, wire) {
|
|
218
|
+
this.bytes[this.#at++] = field * 8 + wire;
|
|
219
|
+
}
|
|
220
|
+
varint(value) {
|
|
221
|
+
while (value >= 128) {
|
|
222
|
+
this.bytes[this.#at++] = value % 128 | 128;
|
|
223
|
+
value = Math.floor(value / 128);
|
|
224
|
+
}
|
|
225
|
+
this.bytes[this.#at++] = value;
|
|
226
|
+
}
|
|
227
|
+
double(value) {
|
|
228
|
+
this.#view.setFloat64(this.#at, value, true);
|
|
229
|
+
this.#at += 8;
|
|
230
|
+
}
|
|
231
|
+
store(field, body) {
|
|
232
|
+
this.tag(field, LENGTH);
|
|
233
|
+
this.varint(body.size);
|
|
234
|
+
const { indices, counts } = body;
|
|
235
|
+
const first = indices[0];
|
|
236
|
+
if (first === void 0) return;
|
|
237
|
+
if (body.sparse) {
|
|
238
|
+
indices.forEach((index, i) => {
|
|
239
|
+
const key = zigzag(index);
|
|
240
|
+
this.tag(1, LENGTH);
|
|
241
|
+
this.varint(1 + varintSize(key) + 1 + 8);
|
|
242
|
+
this.tag(1, VARINT);
|
|
243
|
+
this.varint(key);
|
|
244
|
+
this.tag(2, FIXED64);
|
|
245
|
+
this.double(counts[i] ?? 0);
|
|
246
|
+
});
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
const span = (indices.at(-1) ?? first) - first + 1;
|
|
250
|
+
this.tag(2, LENGTH);
|
|
251
|
+
this.varint(8 * span);
|
|
252
|
+
indices.forEach((index, i) => {
|
|
253
|
+
this.#view.setFloat64(this.#at + 8 * (index - first), counts[i] ?? 0, true);
|
|
254
|
+
});
|
|
255
|
+
this.#at += 8 * span;
|
|
256
|
+
if (first !== 0) {
|
|
257
|
+
this.tag(3, VARINT);
|
|
258
|
+
this.varint(zigzag(first));
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
function toProtobuf(sketch) {
|
|
263
|
+
const { mapping } = sketch;
|
|
264
|
+
const { positive, negative, zeroCount } = sketchBins(sketch);
|
|
265
|
+
const sparse = sketch.store.kind === "sparse";
|
|
266
|
+
const pos = storeBody(positive, sparse);
|
|
267
|
+
const neg = storeBody(negative, sparse);
|
|
268
|
+
const interpolation = KINDS.indexOf(mapping.kind);
|
|
269
|
+
const mappingSize = (present(mapping.gamma) ? 9 : 0) + (present(mapping.indexOffset) ? 9 : 0) + (interpolation !== 0 ? 1 + varintSize(interpolation) : 0);
|
|
270
|
+
const w = new Writer(1 + varintSize(mappingSize) + mappingSize + (1 + varintSize(pos.size) + pos.size) + (1 + varintSize(neg.size) + neg.size) + (present(zeroCount) ? 9 : 0));
|
|
271
|
+
w.tag(1, LENGTH);
|
|
272
|
+
w.varint(mappingSize);
|
|
273
|
+
if (present(mapping.gamma)) {
|
|
274
|
+
w.tag(1, FIXED64);
|
|
275
|
+
w.double(mapping.gamma);
|
|
276
|
+
}
|
|
277
|
+
if (present(mapping.indexOffset)) {
|
|
278
|
+
w.tag(2, FIXED64);
|
|
279
|
+
w.double(mapping.indexOffset);
|
|
280
|
+
}
|
|
281
|
+
if (interpolation !== 0) {
|
|
282
|
+
w.tag(3, VARINT);
|
|
283
|
+
w.varint(interpolation);
|
|
284
|
+
}
|
|
285
|
+
w.store(2, pos);
|
|
286
|
+
w.store(3, neg);
|
|
287
|
+
if (present(zeroCount)) {
|
|
288
|
+
w.tag(4, FIXED64);
|
|
289
|
+
w.double(zeroCount);
|
|
290
|
+
}
|
|
291
|
+
return w.bytes;
|
|
292
|
+
}
|
|
293
|
+
//#endregion
|
|
294
|
+
export { SerializationError, fromProtobuf, toProtobuf };
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { r as FilterJSON } from "./serialize--xR6vGSW.cjs";
|
|
2
|
+
//#region src/ddsketch/mapping.d.ts
|
|
3
|
+
/** Which approximation of the logarithm a mapping bins values by. */
|
|
4
|
+
type MappingKind = "log" | "linear" | "quadratic" | "cubic";
|
|
5
|
+
/**
|
|
6
|
+
* Maps a positive value to the integer index of the bin holding it, and an
|
|
7
|
+
* index back to a value within `relativeAccuracy` of everything in that bin.
|
|
8
|
+
* Built by this module's factories only: a sketch serializes its mapping by
|
|
9
|
+
* `kind`, so a custom implementation would be written, and read back, as the
|
|
10
|
+
* built-in one of that kind.
|
|
11
|
+
*/
|
|
12
|
+
interface IndexMapping {
|
|
13
|
+
/** Which approximation of the logarithm the mapping uses. */
|
|
14
|
+
readonly kind: MappingKind;
|
|
15
|
+
/** The base the bins grow by. */
|
|
16
|
+
readonly gamma: number;
|
|
17
|
+
/** Shift added to every index, carried so foreign sketches decode exactly. */
|
|
18
|
+
readonly indexOffset: number;
|
|
19
|
+
/** The relative error any value read back from a bin is within. */
|
|
20
|
+
readonly relativeAccuracy: number;
|
|
21
|
+
/** The smallest value with a bin; anything smaller counts as zero. */
|
|
22
|
+
readonly minIndexableValue: number;
|
|
23
|
+
/** The largest value with a bin. */
|
|
24
|
+
readonly maxIndexableValue: number;
|
|
25
|
+
/** The bin index of a value in the indexable range. */
|
|
26
|
+
index(value: number): number;
|
|
27
|
+
/** The value a bin reads back as. */
|
|
28
|
+
value(index: number): number;
|
|
29
|
+
/** The smallest value that falls in a bin. */
|
|
30
|
+
lowerBound(index: number): number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A mapping whose bins grow by exactly `gamma`: the most compact for a given
|
|
34
|
+
* accuracy, at the cost of a `Math.log` per value.
|
|
35
|
+
*
|
|
36
|
+
* @param relativeAccuracy - Relative error bound, in `(0, 1)`.
|
|
37
|
+
* @throws {@link ParamError} when `relativeAccuracy` is outside `(0, 1)`, or
|
|
38
|
+
* so small that no value is indexable.
|
|
39
|
+
*/
|
|
40
|
+
declare function logMapping(relativeAccuracy: number): IndexMapping;
|
|
41
|
+
/**
|
|
42
|
+
* A mapping that interpolates log2 linearly from the float's bits instead of
|
|
43
|
+
* calling `Math.log`, at about 44% more bins than {@link logMapping} for the
|
|
44
|
+
* same accuracy. For matching sketches built with it elsewhere; in V8 it adds
|
|
45
|
+
* only slightly faster than the log mapping.
|
|
46
|
+
*
|
|
47
|
+
* @param relativeAccuracy - Relative error bound, in `(0, 1)`.
|
|
48
|
+
* @throws {@link ParamError} when `relativeAccuracy` is outside `(0, 1)`, or
|
|
49
|
+
* so small that no value is indexable.
|
|
50
|
+
*/
|
|
51
|
+
declare function linearMapping(relativeAccuracy: number): IndexMapping;
|
|
52
|
+
/**
|
|
53
|
+
* The fastest mapping: a value's bin is its float's exponent and top
|
|
54
|
+
* significand bits read as one integer, with no logarithm or other floating
|
|
55
|
+
* point arithmetic, as in sketches-java's `DDSketch.fast()`. It spends about
|
|
56
|
+
* 1.85 times the bins of {@link logMapping} at 1%, and is at least as accurate
|
|
57
|
+
* as asked: its bins come in powers of two, so it takes the finest that meets
|
|
58
|
+
* `relativeAccuracy`. Datadog's protobuf carries it as a linear mapping.
|
|
59
|
+
*
|
|
60
|
+
* @param relativeAccuracy - Relative error bound, in `(0, 1)`.
|
|
61
|
+
* @throws {@link ParamError} when `relativeAccuracy` is outside `(0, 1)`, or
|
|
62
|
+
* so small that no value is indexable.
|
|
63
|
+
*/
|
|
64
|
+
declare function bitwiseMapping(relativeAccuracy: number): IndexMapping;
|
|
65
|
+
/**
|
|
66
|
+
* A mapping that approximates log2 with a quadratic in the float's
|
|
67
|
+
* significand: between {@link linearMapping} and {@link cubicMapping} in
|
|
68
|
+
* bins per accuracy. Matches sketches-java, the reference that has it.
|
|
69
|
+
*
|
|
70
|
+
* @param relativeAccuracy - Relative error bound, in `(0, 1)`.
|
|
71
|
+
* @throws {@link ParamError} when `relativeAccuracy` is outside `(0, 1)`, or
|
|
72
|
+
* so small that no value is indexable.
|
|
73
|
+
*/
|
|
74
|
+
declare function quadraticMapping(relativeAccuracy: number): IndexMapping;
|
|
75
|
+
/**
|
|
76
|
+
* A mapping that approximates log2 with a cubic in the float's significand:
|
|
77
|
+
* nearly as compact as {@link logMapping}. For matching sketches built with it
|
|
78
|
+
* elsewhere; in V8 it adds slower than the log mapping, `Math.log` being cheap.
|
|
79
|
+
*
|
|
80
|
+
* @param relativeAccuracy - Relative error bound, in `(0, 1)`.
|
|
81
|
+
* @throws {@link ParamError} when `relativeAccuracy` is outside `(0, 1)`, or
|
|
82
|
+
* so small that no value is indexable.
|
|
83
|
+
*/
|
|
84
|
+
declare function cubicMapping(relativeAccuracy: number): IndexMapping;
|
|
85
|
+
//#endregion
|
|
86
|
+
//#region src/ddsketch/store.d.ts
|
|
87
|
+
/** How a store lays out its bins and what it gives up to bound memory. */
|
|
88
|
+
type StoreKind = "dense" | "sparse" | "collapsingLowest" | "collapsingHighest";
|
|
89
|
+
/** Counts per bin index for one sign of a sketch. */
|
|
90
|
+
interface Store {
|
|
91
|
+
/** The sum of every count added. */
|
|
92
|
+
readonly total: number;
|
|
93
|
+
/** Adds `count` to the bin at `index`. */
|
|
94
|
+
add(index: number, count: number): void;
|
|
95
|
+
/**
|
|
96
|
+
* The index of the bin holding the value at `rank`, counting from 0 in
|
|
97
|
+
* ascending index order, or descending when `descending` is set.
|
|
98
|
+
*/
|
|
99
|
+
keyAtRank(rank: number, descending?: boolean): number;
|
|
100
|
+
/** Calls `fn` for every non-empty bin, in ascending index order. */
|
|
101
|
+
forEach(fn: (index: number, count: number) => void): void;
|
|
102
|
+
/** Adds every bin of `other`, as adding them in ascending index order would. */
|
|
103
|
+
merge(other: Store): void;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Builds the stores a sketch keeps, one per sign, both with the same policy.
|
|
107
|
+
* Passed to {@link DDSketch.create} as `store`. Built by this module's
|
|
108
|
+
* factories only: a sketch serializes its store by `kind` and `maxBins`, so a
|
|
109
|
+
* custom one would be read back as the built-in store of that kind.
|
|
110
|
+
*/
|
|
111
|
+
interface StoreFactory {
|
|
112
|
+
/** Which store this builds. */
|
|
113
|
+
readonly kind: StoreKind;
|
|
114
|
+
/** The most bins a store keeps, or 0 when unbounded. */
|
|
115
|
+
readonly maxBins: number;
|
|
116
|
+
/** A new, empty store. */
|
|
117
|
+
create(): Store;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Bins over one contiguous range of indices that grows to fit, with no bound
|
|
121
|
+
* on memory: a stream spanning a wide range of magnitudes keeps every bin.
|
|
122
|
+
*/
|
|
123
|
+
declare function denseStore(): StoreFactory;
|
|
124
|
+
/**
|
|
125
|
+
* Bins only where values landed, so memory follows the number of distinct
|
|
126
|
+
* bins rather than the range between the smallest and largest.
|
|
127
|
+
*/
|
|
128
|
+
declare function sparseStore(): StoreFactory;
|
|
129
|
+
/**
|
|
130
|
+
* A dense store that never spans more than `maxBins` bins. Past that it folds
|
|
131
|
+
* the lowest bins into the lowest one it keeps, giving up accuracy on the
|
|
132
|
+
* smallest magnitudes, near zero on either sign, and keeping it for the
|
|
133
|
+
* largest. The default, since the tails are what quantiles are read for.
|
|
134
|
+
*
|
|
135
|
+
* @param maxBins - The most bins kept per sign; a positive integer.
|
|
136
|
+
* @throws {@link ParamError} when `maxBins` is not a positive integer.
|
|
137
|
+
*/
|
|
138
|
+
declare function collapsingLowestStore(maxBins: number): StoreFactory;
|
|
139
|
+
/**
|
|
140
|
+
* A dense store that never spans more than `maxBins` bins. Past that it folds
|
|
141
|
+
* the highest bins into the highest one it keeps, giving up accuracy on the
|
|
142
|
+
* largest magnitudes and keeping it for the smallest.
|
|
143
|
+
*
|
|
144
|
+
* @param maxBins - The most bins kept per sign; a positive integer.
|
|
145
|
+
* @throws {@link ParamError} when `maxBins` is not a positive integer.
|
|
146
|
+
*/
|
|
147
|
+
declare function collapsingHighestStore(maxBins: number): StoreFactory;
|
|
148
|
+
//#endregion
|
|
149
|
+
//#region src/ddsketch/ddsketch.d.ts
|
|
150
|
+
/** Options for {@link DDSketch.create}. */
|
|
151
|
+
interface DDSketchOptions {
|
|
152
|
+
/**
|
|
153
|
+
* The mapping factory that bins values. Defaults to {@link bitwiseMapping},
|
|
154
|
+
* the mapping sketches-java's fast sketch uses and the fastest, adding about
|
|
155
|
+
* twice as fast as the log mapping in the benchmarks; take {@link logMapping}
|
|
156
|
+
* for the fewest bins. The interpolated mappings exist to
|
|
157
|
+
* match sketches built with them by Datadog's libraries.
|
|
158
|
+
*/
|
|
159
|
+
mapping?: (relativeAccuracy: number) => IndexMapping;
|
|
160
|
+
/**
|
|
161
|
+
* The store factory that holds each sign's bins. Defaults to
|
|
162
|
+
* {@link collapsingLowestStore} at 4096 bins, about 19 orders of magnitude
|
|
163
|
+
* at 1% with the default mapping, which bounds memory while keeping the
|
|
164
|
+
* tails accurate.
|
|
165
|
+
*/
|
|
166
|
+
store?: StoreFactory;
|
|
167
|
+
}
|
|
168
|
+
/** Thrown by {@link DDSketch.union} when the two sketches' bins differ. */
|
|
169
|
+
declare class DDSketchParamMismatchError extends Error {
|
|
170
|
+
/** Discriminates this error from other `Error`s. */
|
|
171
|
+
override readonly name = "DDSketchParamMismatchError";
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* A quantile sketch whose every answer is within a relative error of the true
|
|
175
|
+
* value at that quantile, tails included.
|
|
176
|
+
*/
|
|
177
|
+
declare class DDSketch {
|
|
178
|
+
#private;
|
|
179
|
+
/**
|
|
180
|
+
* Builds an empty sketch.
|
|
181
|
+
*
|
|
182
|
+
* @param relativeAccuracy - Relative error bound on every quantile, in `(0, 1)`.
|
|
183
|
+
* @param options - Optional mapping and store factories.
|
|
184
|
+
* @throws {@link ParamError} when `relativeAccuracy` is outside `(0, 1)`, or
|
|
185
|
+
* so small that the mapping indexes no value.
|
|
186
|
+
*/
|
|
187
|
+
static create(relativeAccuracy: number, options?: DDSketchOptions): DDSketch;
|
|
188
|
+
/**
|
|
189
|
+
* Builds a sketch holding `values`.
|
|
190
|
+
*
|
|
191
|
+
* @param values - Finite numbers within the mapping's indexable range.
|
|
192
|
+
* @param relativeAccuracy - Relative error bound on every quantile, in `(0, 1)`.
|
|
193
|
+
* @param options - Optional mapping and store factories.
|
|
194
|
+
* @throws {@link ParamError} when `relativeAccuracy` is outside `(0, 1)` or
|
|
195
|
+
* so small that the mapping indexes no value, or a value cannot be recorded.
|
|
196
|
+
*/
|
|
197
|
+
static from(values: Iterable<number>, relativeAccuracy: number, options?: DDSketchOptions): DDSketch;
|
|
198
|
+
/**
|
|
199
|
+
* Restores a sketch from its {@link DDSketch.toBytes} serialization.
|
|
200
|
+
*
|
|
201
|
+
* @param bytes - The serialized sketch.
|
|
202
|
+
* @returns The reconstructed sketch.
|
|
203
|
+
* @throws {@link SerializationError} when the frame is malformed or not a
|
|
204
|
+
* DDSketch.
|
|
205
|
+
*/
|
|
206
|
+
static fromBytes(bytes: Uint8Array): DDSketch;
|
|
207
|
+
/** See {@link DDSketch.create}. */
|
|
208
|
+
constructor(relativeAccuracy: number, options?: DDSketchOptions);
|
|
209
|
+
/** The relative error bound the sketch was built for. */
|
|
210
|
+
get relativeAccuracy(): number;
|
|
211
|
+
/** The mapping that bins values. */
|
|
212
|
+
get mapping(): IndexMapping;
|
|
213
|
+
/** The store factory holding each sign's bins. */
|
|
214
|
+
get store(): StoreFactory;
|
|
215
|
+
/** How many values have been added. */
|
|
216
|
+
get count(): number;
|
|
217
|
+
/**
|
|
218
|
+
* The sum of every value added. Past the largest double it is `Infinity`
|
|
219
|
+
* or `-Infinity`, and NaN once both signs have overflowed.
|
|
220
|
+
*/
|
|
221
|
+
get sum(): number;
|
|
222
|
+
/** The smallest value added, exactly; `NaN` when empty. */
|
|
223
|
+
get min(): number;
|
|
224
|
+
/** The largest value added, exactly; `NaN` when empty. */
|
|
225
|
+
get max(): number;
|
|
226
|
+
/**
|
|
227
|
+
* Returns a new sketch holding everything this one and `other` have
|
|
228
|
+
* recorded: the same bins, count, min and max one sketch over both streams
|
|
229
|
+
* would hold, with `sum` equal up to float rounding. It takes this sketch's
|
|
230
|
+
* accuracy, mapping and store; both operands are left untouched.
|
|
231
|
+
*
|
|
232
|
+
* @param other - A sketch whose mapping bins values identically.
|
|
233
|
+
* @returns A new sketch holding both streams.
|
|
234
|
+
* @throws {@link DDSketchParamMismatchError} when the mappings differ in
|
|
235
|
+
* kind, or in `gamma` or `indexOffset` by more than 1e-12 relative.
|
|
236
|
+
*/
|
|
237
|
+
union(other: DDSketch): DDSketch;
|
|
238
|
+
/**
|
|
239
|
+
* Serializes the sketch into a self-describing DSTL frame (type 10): its
|
|
240
|
+
* mapping and store, summaries, and each sign's non-empty bins in ascending
|
|
241
|
+
* index order, so equal sketches give equal bytes.
|
|
242
|
+
*
|
|
243
|
+
* @returns The serialized sketch, readable by {@link DDSketch.fromBytes}.
|
|
244
|
+
*/
|
|
245
|
+
toBytes(): Uint8Array;
|
|
246
|
+
/**
|
|
247
|
+
* Tests structural equality: `true` when `other` serializes to identical
|
|
248
|
+
* bytes, meaning the same mapping, store, summaries and bins.
|
|
249
|
+
*
|
|
250
|
+
* @param other - The sketch to compare against.
|
|
251
|
+
* @returns `true` if the two sketches are byte-for-byte identical.
|
|
252
|
+
*/
|
|
253
|
+
equals(other: DDSketch): boolean;
|
|
254
|
+
/**
|
|
255
|
+
* Serializes the sketch into the JSON envelope: the base64 of
|
|
256
|
+
* {@link DDSketch.toBytes}.
|
|
257
|
+
*
|
|
258
|
+
* @returns The envelope, readable by {@link DDSketch.fromJSON}.
|
|
259
|
+
*/
|
|
260
|
+
toJSON(): FilterJSON;
|
|
261
|
+
/**
|
|
262
|
+
* Restores a sketch from its {@link DDSketch.toJSON} envelope.
|
|
263
|
+
*
|
|
264
|
+
* @param value - The parsed envelope.
|
|
265
|
+
* @returns The reconstructed sketch.
|
|
266
|
+
* @throws {@link SerializationError} when the envelope or frame is malformed.
|
|
267
|
+
*/
|
|
268
|
+
static fromJSON(value: unknown): DDSketch;
|
|
269
|
+
/**
|
|
270
|
+
* The value at quantile `q`, within `relativeAccuracy` of the exact value at
|
|
271
|
+
* rank `floor(q * (count - 1))`. `q = 0` and `q = 1` give `min` and `max`
|
|
272
|
+
* exactly.
|
|
273
|
+
*
|
|
274
|
+
* @param q - The quantile, in `[0, 1]`.
|
|
275
|
+
* @returns The estimate, or `NaN` when the sketch is empty.
|
|
276
|
+
* @throws {@link ParamError} when `q` is outside `[0, 1]`.
|
|
277
|
+
*/
|
|
278
|
+
quantile(q: number): number;
|
|
279
|
+
/** {@link DDSketch.quantile} for each of `qs`, in order. */
|
|
280
|
+
quantiles(qs: readonly number[]): number[];
|
|
281
|
+
/**
|
|
282
|
+
* Records a value.
|
|
283
|
+
*
|
|
284
|
+
* @param value - Any finite number within the mapping's indexable range.
|
|
285
|
+
* @param count - How many times to record it; finite and positive.
|
|
286
|
+
* @throws {@link ParamError} when `value` is not finite or beyond
|
|
287
|
+
* `mapping.maxIndexableValue` in magnitude, or `count` is not a finite
|
|
288
|
+
* positive number. Nothing is recorded.
|
|
289
|
+
*/
|
|
290
|
+
add(value: number, count?: number): void;
|
|
291
|
+
}
|
|
292
|
+
//#endregion
|
|
293
|
+
export { quadraticMapping as _, StoreFactory as a, collapsingLowestStore as c, IndexMapping as d, MappingKind as f, logMapping as g, linearMapping as h, Store as i, denseStore as l, cubicMapping as m, DDSketchOptions as n, StoreKind as o, bitwiseMapping as p, DDSketchParamMismatchError as r, collapsingHighestStore as s, DDSketch as t, sparseStore as u };
|