| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.doDecode = exports.decompress = exports.inflate = exports.deflate = void 0;
- /*
- * This is a TypeScript port of the original Java version, which was written by
- * Gil Tene as described in
- * https://github.com/HdrHistogram/HdrHistogram
- * and released to the public domain, as explained at
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
- // @ts-ignore
- const base64 = require("base64-js");
- // @ts-ignore
- const pako = require("pako");
- const JsHistogram_1 = require("./JsHistogram");
- const ByteBuffer_1 = require("./ByteBuffer");
- const JsHistogramFactory_1 = require("./JsHistogramFactory");
- const ZigZagEncoding_1 = require("./ZigZagEncoding");
- const { max } = Math;
- const V2EncodingCookieBase = 0x1c849303;
- const V2CompressedEncodingCookieBase = 0x1c849304;
- const V2maxWordSizeInBytes = 9; // LEB128-64b9B + ZigZag require up to 9 bytes per word
- const encodingCookie = V2EncodingCookieBase | 0x10; // LSBit of wordsize byte indicates TLZE Encoding
- const compressedEncodingCookie = V2CompressedEncodingCookieBase | 0x10; // LSBit of wordsize byte indicates TLZE Encoding
- function fillBufferFromCountsArray(self, buffer) {
- const countsLimit = self.countsArrayIndex(self.maxValue) + 1;
- let srcIndex = 0;
- while (srcIndex < countsLimit) {
- // V2 encoding format uses a ZigZag LEB128-64b9B encoded long. Positive values are counts,
- // while negative values indicate a repeat zero counts.
- const count = self.getCountAtIndex(srcIndex++);
- if (count < 0) {
- throw new Error("Cannot encode histogram containing negative counts (" +
- count +
- ") at index " +
- srcIndex +
- ", corresponding the value range [" +
- self.lowestEquivalentValue(self.valueFromIndex(srcIndex)) +
- "," +
- self.nextNonEquivalentValue(self.valueFromIndex(srcIndex)) +
- ")");
- }
- // Count trailing 0s (which follow this count):
- let zerosCount = 0;
- if (count == 0) {
- zerosCount = 1;
- while (srcIndex < countsLimit && self.getCountAtIndex(srcIndex) == 0) {
- zerosCount++;
- srcIndex++;
- }
- }
- if (zerosCount > 1) {
- ZigZagEncoding_1.default.encode(buffer, -zerosCount);
- }
- else {
- ZigZagEncoding_1.default.encode(buffer, count);
- }
- }
- }
- /**
- * Encode this histogram into a ByteBuffer
- * @param self this histogram
- * @param buffer The buffer to encode into
- * @return The number of bytes written to the buffer
- */
- function encodeIntoByteBuffer(self, buffer) {
- const initialPosition = buffer.position;
- buffer.putInt32(encodingCookie);
- buffer.putInt32(0); // Placeholder for payload length in bytes.
- buffer.putInt32(1);
- buffer.putInt32(self.numberOfSignificantValueDigits);
- buffer.putInt64(self.lowestDiscernibleValue);
- buffer.putInt64(self.highestTrackableValue);
- buffer.putInt64(1);
- const payloadStartPosition = buffer.position;
- fillBufferFromCountsArray(self, buffer);
- const backupIndex = buffer.position;
- buffer.position = initialPosition + 4;
- buffer.putInt32(backupIndex - payloadStartPosition); // Record the payload length
- buffer.position = backupIndex;
- return backupIndex - initialPosition;
- }
- function fillCountsArrayFromSourceBuffer(self, sourceBuffer, lengthInBytes, wordSizeInBytes) {
- if (wordSizeInBytes != 2 &&
- wordSizeInBytes != 4 &&
- wordSizeInBytes != 8 &&
- wordSizeInBytes != V2maxWordSizeInBytes) {
- throw new Error("word size must be 2, 4, 8, or V2maxWordSizeInBytes (" +
- V2maxWordSizeInBytes +
- ") bytes");
- }
- let dstIndex = 0;
- const endPosition = sourceBuffer.position + lengthInBytes;
- while (sourceBuffer.position < endPosition) {
- let zerosCount = 0;
- let count = ZigZagEncoding_1.default.decode(sourceBuffer);
- if (count < 0) {
- zerosCount = -count;
- dstIndex += zerosCount; // No need to set zeros in array. Just skip them.
- }
- else {
- self.setCountAtIndex(dstIndex++, count);
- }
- }
- return dstIndex; // this is the destination length
- }
- function getCookieBase(cookie) {
- return cookie & ~0xf0;
- }
- function getWordSizeInBytesFromCookie(cookie) {
- if (getCookieBase(cookie) == V2EncodingCookieBase ||
- getCookieBase(cookie) == V2CompressedEncodingCookieBase) {
- return V2maxWordSizeInBytes;
- }
- const sizeByte = (cookie & 0xf0) >> 4;
- return sizeByte & 0xe;
- }
- function findDeflateFunction() {
- try {
- return eval('require("zlib").deflateSync');
- }
- catch (error) {
- return !!pako ? pako.deflate : () => { throw new Error('pako library is mandatory for encoding/deconding on the browser side'); };
- }
- }
- function findInflateFunction() {
- try {
- return eval('require("zlib").inflateSync');
- }
- catch (error) {
- return !!pako ? pako.inflate : () => { throw new Error('pako library is mandatory for encoding/deconding on the browser side'); };
- }
- }
- exports.deflate = findDeflateFunction();
- exports.inflate = findInflateFunction();
- function decompress(data) {
- const buffer = new ByteBuffer_1.default(data);
- const initialTargetPosition = buffer.position;
- const cookie = buffer.getInt32();
- if ((cookie & ~0xf0) !== V2CompressedEncodingCookieBase) {
- throw new Error("Encoding not supported, only V2 is supported");
- }
- const lengthOfCompressedContents = buffer.getInt32();
- const uncompressedBuffer = exports.inflate(buffer.data.slice(initialTargetPosition + 8, initialTargetPosition + 8 + lengthOfCompressedContents));
- return uncompressedBuffer;
- }
- exports.decompress = decompress;
- function doDecode(data, bitBucketSize = 32, minBarForHighestTrackableValue = 0) {
- const buffer = new ByteBuffer_1.default(data);
- const cookie = buffer.getInt32();
- let payloadLengthInBytes;
- let numberOfSignificantValueDigits;
- let lowestTrackableUnitValue;
- let highestTrackableValue;
- if (getCookieBase(cookie) === V2EncodingCookieBase) {
- if (getWordSizeInBytesFromCookie(cookie) != V2maxWordSizeInBytes) {
- throw new Error("The buffer does not contain a Histogram (no valid cookie found)");
- }
- payloadLengthInBytes = buffer.getInt32();
- buffer.getInt32(); // normalizingIndexOffset not used
- numberOfSignificantValueDigits = buffer.getInt32();
- lowestTrackableUnitValue = buffer.getInt64();
- highestTrackableValue = buffer.getInt64();
- buffer.getInt64(); // integerToDoubleValueConversionRatio not used
- }
- else {
- throw new Error("The buffer does not contain a Histogram (no valid V2 encoding cookie found)");
- }
- highestTrackableValue = max(highestTrackableValue, minBarForHighestTrackableValue);
- const histogramConstr = JsHistogramFactory_1.constructorFromBucketSize(bitBucketSize);
- const histogram = new histogramConstr(lowestTrackableUnitValue, highestTrackableValue, numberOfSignificantValueDigits);
- const filledLength = fillCountsArrayFromSourceBuffer(histogram, buffer, payloadLengthInBytes, V2maxWordSizeInBytes);
- histogram.establishInternalTackingValues(filledLength);
- return histogram;
- }
- exports.doDecode = doDecode;
- function doEncodeIntoCompressedBase64(compressionLevel) {
- const compressionOptions = compressionLevel
- ? { level: compressionLevel }
- : {};
- const self = this;
- const targetBuffer = ByteBuffer_1.default.allocate();
- targetBuffer.putInt32(compressedEncodingCookie);
- const intermediateUncompressedByteBuffer = ByteBuffer_1.default.allocate();
- const uncompressedLength = encodeIntoByteBuffer(self, intermediateUncompressedByteBuffer);
- const data = intermediateUncompressedByteBuffer.data.slice(0, uncompressedLength);
- const compressedData = exports.deflate(data, compressionOptions);
- targetBuffer.putInt32(compressedData.byteLength);
- targetBuffer.putArray(compressedData);
- return base64.fromByteArray(targetBuffer.data);
- }
- JsHistogram_1.JsHistogram.decode = doDecode;
- JsHistogram_1.JsHistogram.prototype.encodeIntoCompressedBase64 = doEncodeIntoCompressedBase64;
- //# sourceMappingURL=JsHistogram.encoding.js.map
|