source: trip-planner-front/node_modules/hdr-histogram-js/src/wasm/index.ts@ fa375fe

Last change on this file since fa375fe was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 8.0 KB
Line 
1import { BINARY } from "./generated-wasm";
2import Histogram, {
3 NO_TAG,
4 BitBucketSize,
5 toSummary,
6 HistogramSummary
7} from "../Histogram";
8// @ts-ignore
9import * as base64 from "base64-js";
10// @ts-ignore
11import * as pako from "pako";
12// @ts-ignore
13import * as loader from "@assemblyscript/loader";
14import { BuildRequest } from "../HistogramBuilder";
15
16const isNode = typeof process !== "undefined" && process.version;
17// @ts-ignore
18const isWorker = typeof importScripts === "function";
19export const webAssemblyAvailable = (() => {
20 let available = false;
21 if (isNode) {
22 // nodejs
23 available = "WebAssembly" in global;
24 } else {
25 // browser
26 // @ts-ignore
27 available = isWorker || "WebAssembly" in window;
28 }
29 return available;
30})();
31
32let wasm: any = undefined;
33
34export const initWebAssembly = async (): Promise<void> => {
35 if (!webAssemblyAvailable) {
36 throw new Error("WebAssembly not available here!");
37 }
38 if (!!wasm) {
39 return;
40 }
41 return loader
42 .instantiate(pako.inflate(base64.toByteArray(BINARY)))
43 .then((w: any) => (wasm = w.exports || w));
44};
45
46export const initWebAssemblySync = () => {
47 if (!!wasm) {
48 return;
49 }
50 const w = loader.instantiateSync(pako.inflate(base64.toByteArray(BINARY)));
51 wasm = w.exports || w;
52};
53
54export const webAssemblyReady = () => !!wasm;
55
56const defaultRequest: BuildRequest = {
57 bitBucketSize: 32,
58 autoResize: true,
59 lowestDiscernibleValue: 1,
60 highestTrackableValue: 2,
61 numberOfSignificantValueDigits: 3
62};
63
64const remoteHistogramClassFor = (size?: BitBucketSize) =>
65 size === "packed" ? "PackedHistogram" : `Histogram${size}`;
66
67const destroyedWasmHistogram = new Proxy(
68 {},
69 {
70 get: function(obj, prop) {
71 throw new Error("Cannot use a destroyed histogram");
72 }
73 }
74);
75
76export class WasmHistogram implements Histogram {
77 tag: string;
78
79 constructor(
80 private _wasmHistogram: any,
81 private _remoteHistogramClass: string
82 ) {
83 this.tag = NO_TAG;
84 }
85
86 static build(request: BuildRequest = defaultRequest) {
87 if (!webAssemblyReady()) {
88 throw new Error("WebAssembly is not ready yet!");
89 }
90 const parameters = Object.assign({}, defaultRequest, request);
91 const remoteHistogramClass = remoteHistogramClassFor(
92 parameters.bitBucketSize
93 );
94 return new WasmHistogram(
95 new wasm[remoteHistogramClass](
96 parameters.lowestDiscernibleValue,
97 parameters.highestTrackableValue,
98 parameters.numberOfSignificantValueDigits,
99 parameters.autoResize
100 ),
101 remoteHistogramClass
102 );
103 }
104
105 static decode(
106 data: Uint8Array,
107 bitBucketSize: 8 | 16 | 32 | 64 | "packed" = 32,
108 minBarForHighestTrackableValue: number = 0
109 ): Histogram {
110 if (!webAssemblyReady()) {
111 throw new Error("WebAssembly is not ready yet!");
112 }
113 const remoteHistogramClass = remoteHistogramClassFor(bitBucketSize);
114 const decodeFunc = `decode${remoteHistogramClass}`;
115 const ptrArr = wasm.__retain(wasm.__allocArray(wasm.UINT8ARRAY_ID, data));
116 const wasmHistogram = new WasmHistogram(
117 wasm[remoteHistogramClass].wrap(
118 wasm[decodeFunc](ptrArr, minBarForHighestTrackableValue)
119 ),
120 remoteHistogramClass
121 );
122 wasm.__release(ptrArr);
123 return wasmHistogram;
124 }
125
126 public get numberOfSignificantValueDigits(): number {
127 return this._wasmHistogram.numberOfSignificantValueDigits;
128 }
129
130 public get autoResize(): boolean {
131 return !!this._wasmHistogram.autoResize;
132 }
133
134 public set autoResize(resize: boolean) {
135 this._wasmHistogram.autoResize = resize;
136 }
137
138 public get highestTrackableValue(): number {
139 return this._wasmHistogram.highestTrackableValue;
140 }
141
142 public set highestTrackableValue(value: number) {
143 this._wasmHistogram.highestTrackableValue = value;
144 }
145
146 public get startTimeStampMsec(): number {
147 return this._wasmHistogram.startTimeStampMsec;
148 }
149
150 public set startTimeStampMsec(value: number) {
151 this._wasmHistogram.startTimeStampMsec = value;
152 }
153
154 public get endTimeStampMsec(): number {
155 return this._wasmHistogram.endTimeStampMsec;
156 }
157
158 public set endTimeStampMsec(value: number) {
159 this._wasmHistogram.endTimeStampMsec = value;
160 }
161
162 public get totalCount(): number {
163 return this._wasmHistogram.totalCount;
164 }
165 public get stdDeviation(): number {
166 return this._wasmHistogram.stdDeviation;
167 }
168 public get mean(): number {
169 return this._wasmHistogram.mean;
170 }
171 public get estimatedFootprintInBytes(): number {
172 return 192 + this._wasmHistogram.estimatedFootprintInBytes;
173 }
174
175 public get minNonZeroValue(): number {
176 return this._wasmHistogram.minNonZeroValue;
177 }
178 public get maxValue(): number {
179 return this._wasmHistogram.maxValue;
180 }
181
182 recordValue(value: number) {
183 this._wasmHistogram.recordValue(value);
184 }
185
186 recordValueWithCount(value: number, count: number): void {
187 this._wasmHistogram.recordValueWithCount(value, count);
188 }
189
190 recordValueWithExpectedInterval(
191 value: number,
192 expectedIntervalBetweenValueSamples: number
193 ) {
194 this._wasmHistogram.recordValueWithExpectedInterval(
195 value,
196 expectedIntervalBetweenValueSamples
197 );
198 }
199
200 getValueAtPercentile(percentile: number): number {
201 return this._wasmHistogram.getValueAtPercentile(percentile);
202 }
203
204 outputPercentileDistribution(
205 percentileTicksPerHalfDistance = 5,
206 outputValueUnitScalingRatio = 1,
207 useCsvFormat = false
208 ): string {
209 // TODO csv
210 if (useCsvFormat) {
211 throw new Error("CSV output not supported by wasm histograms");
212 }
213 return wasm.__getString(
214 this._wasmHistogram.outputPercentileDistribution(
215 percentileTicksPerHalfDistance,
216 outputValueUnitScalingRatio
217 )
218 );
219 }
220
221 private isDestroyed() {
222 return this._wasmHistogram === destroyedWasmHistogram;
223 }
224
225 get summary(): HistogramSummary {
226 return toSummary(this);
227 }
228
229 toJSON(): HistogramSummary {
230 return this.summary;
231 }
232
233 toString() {
234 if (this.isDestroyed()) {
235 return "Destroyed WASM histogram";
236 }
237 return `WASM ${this._remoteHistogramClass} ${JSON.stringify(
238 this,
239 null,
240 2
241 )}`;
242 }
243
244 inspect() {
245 return this.toString();
246 }
247
248 [Symbol.for("nodejs.util.inspect.custom")]() {
249 return this.toString();
250 }
251
252 addWhileCorrectingForCoordinatedOmission(
253 otherHistogram: WasmHistogram,
254 expectedIntervalBetweenValueSamples: number
255 ): void {
256 this._wasmHistogram.addWhileCorrectingForCoordinatedOmission(
257 otherHistogram,
258 expectedIntervalBetweenValueSamples
259 );
260 }
261
262 copyCorrectedForCoordinatedOmission(
263 expectedIntervalBetweenValueSamples: number
264 ): WasmHistogram {
265 return new WasmHistogram(
266 wasm[this._remoteHistogramClass].wrap(
267 this._wasmHistogram.copyCorrectedForCoordinatedOmission(
268 expectedIntervalBetweenValueSamples
269 )
270 ),
271 this._remoteHistogramClass
272 );
273 }
274
275 add(otherHistogram: WasmHistogram): void {
276 if (!(otherHistogram instanceof WasmHistogram)) {
277 // should be impossible to be in this situation but actually
278 // TypeScript has some flaws...
279 throw new Error("Cannot add a regular JS histogram to a WASM histogram");
280 }
281 this._wasmHistogram[`add${otherHistogram._remoteHistogramClass}`](
282 otherHistogram._wasmHistogram
283 );
284 }
285
286 subtract(otherHistogram: WasmHistogram): void {
287 if (!(otherHistogram instanceof WasmHistogram)) {
288 // should be impossible to be in this situation but actually
289 // TypeScript has some flaws...
290 throw new Error(
291 "Cannot subtract a regular JS histogram to a WASM histogram"
292 );
293 }
294 this._wasmHistogram[`subtract${otherHistogram._remoteHistogramClass}`](
295 otherHistogram._wasmHistogram
296 );
297 }
298
299 encode(): Uint8Array {
300 const ptrArray = this._wasmHistogram.encode();
301 const array = wasm.__getUint8Array(ptrArray);
302 wasm.__release(ptrArray);
303 return array;
304 }
305
306 reset(): void {
307 this.tag = NO_TAG;
308 this._wasmHistogram.reset();
309 }
310
311 destroy(): void {
312 wasm.__release(this._wasmHistogram);
313 this._wasmHistogram = destroyedWasmHistogram;
314 }
315}
Note: See TracBrowser for help on using the repository browser.