[6a3a178] | 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 | };
|
---|