1 | /*
|
---|
2 | * This is a TypeScript port of the original Java version, which was written by
|
---|
3 | * Gil Tene as described in
|
---|
4 | * https://github.com/HdrHistogram/HdrHistogram
|
---|
5 | * and released to the public domain, as explained at
|
---|
6 | * http://creativecommons.org/publicdomain/zero/1.0/
|
---|
7 | */
|
---|
8 | import { JsHistogram } from "./JsHistogram";
|
---|
9 | import ByteBuffer from "./ByteBuffer";
|
---|
10 | import Histogram from "./Histogram";
|
---|
11 | import { WasmHistogram } from "./wasm";
|
---|
12 |
|
---|
13 | // @ts-ignore
|
---|
14 | import * as base64 from "base64-js";
|
---|
15 | import { inflate, deflate } from "./JsHistogram.encoding";
|
---|
16 |
|
---|
17 | const V2CompressedEncodingCookieBase = 0x1c849304;
|
---|
18 | const compressedEncodingCookie = V2CompressedEncodingCookieBase | 0x10; // LSBit of wordsize byte indicates TLZE Encoding
|
---|
19 |
|
---|
20 | export function decompress(data: Uint8Array): Uint8Array {
|
---|
21 | const buffer = new ByteBuffer(data);
|
---|
22 | const initialTargetPosition = buffer.position;
|
---|
23 |
|
---|
24 | const cookie = buffer.getInt32();
|
---|
25 |
|
---|
26 | if ((cookie & ~0xf0) !== V2CompressedEncodingCookieBase) {
|
---|
27 | throw new Error("Encoding not supported, only V2 is supported");
|
---|
28 | }
|
---|
29 |
|
---|
30 | const lengthOfCompressedContents = buffer.getInt32();
|
---|
31 |
|
---|
32 | const uncompressedBuffer: Uint8Array = inflate(
|
---|
33 | buffer.data.slice(
|
---|
34 | initialTargetPosition + 8,
|
---|
35 | initialTargetPosition + 8 + lengthOfCompressedContents
|
---|
36 | )
|
---|
37 | );
|
---|
38 | return uncompressedBuffer;
|
---|
39 | }
|
---|
40 |
|
---|
41 | export const decodeFromCompressedBase64 = (
|
---|
42 | base64String: string,
|
---|
43 | bitBucketSize: 8 | 16 | 32 | 64 | "packed" = 32,
|
---|
44 | useWebAssembly: boolean = false,
|
---|
45 | minBarForHighestTrackableValue: number = 0
|
---|
46 | ): Histogram => {
|
---|
47 | const data = base64.toByteArray(base64String.trim());
|
---|
48 | const uncompressedData = decompress(data);
|
---|
49 | if (useWebAssembly) {
|
---|
50 | return WasmHistogram.decode(
|
---|
51 | uncompressedData,
|
---|
52 | bitBucketSize,
|
---|
53 | minBarForHighestTrackableValue
|
---|
54 | );
|
---|
55 | }
|
---|
56 | return JsHistogram.decode(
|
---|
57 | uncompressedData,
|
---|
58 | bitBucketSize,
|
---|
59 | minBarForHighestTrackableValue
|
---|
60 | );
|
---|
61 | };
|
---|
62 |
|
---|
63 | function encodeWasmIntoCompressedBase64(compressionLevel?: number): string {
|
---|
64 | const compressionOptions = compressionLevel
|
---|
65 | ? { level: compressionLevel }
|
---|
66 | : {};
|
---|
67 | const self: WasmHistogram = this as any;
|
---|
68 |
|
---|
69 | const targetBuffer = ByteBuffer.allocate();
|
---|
70 | targetBuffer.putInt32(compressedEncodingCookie);
|
---|
71 |
|
---|
72 | const uncompressedData = self.encode();
|
---|
73 | const compressedData: Uint8Array = deflate(
|
---|
74 | uncompressedData,
|
---|
75 | compressionOptions
|
---|
76 | );
|
---|
77 |
|
---|
78 | targetBuffer.putInt32(compressedData.byteLength);
|
---|
79 | targetBuffer.putArray(compressedData);
|
---|
80 |
|
---|
81 | return base64.fromByteArray(targetBuffer.data);
|
---|
82 | }
|
---|
83 |
|
---|
84 | declare module "./wasm" {
|
---|
85 | interface WasmHistogram {
|
---|
86 | encodeIntoCompressedBase64: typeof encodeWasmIntoCompressedBase64;
|
---|
87 | }
|
---|
88 | }
|
---|
89 |
|
---|
90 | WasmHistogram.prototype.encodeIntoCompressedBase64 = encodeWasmIntoCompressedBase64;
|
---|
91 |
|
---|
92 | export const encodeIntoCompressedBase64 = (
|
---|
93 | histogram: Histogram,
|
---|
94 | compressionLevel?: number
|
---|
95 | ): string => {
|
---|
96 | if (histogram instanceof WasmHistogram) {
|
---|
97 | return histogram.encodeIntoCompressedBase64(compressionLevel);
|
---|
98 | }
|
---|
99 | if (histogram instanceof JsHistogram) {
|
---|
100 | return histogram.encodeIntoCompressedBase64(compressionLevel);
|
---|
101 | }
|
---|
102 | throw new Error("Unsupported Histogram implementation");
|
---|
103 | };
|
---|