Updated the files.

This commit is contained in:
Batuhan Berk Başoğlu 2024-02-08 19:38:41 -05:00
parent 1553e6b971
commit 753967d4f5
23418 changed files with 3784666 additions and 0 deletions

20
my-app/node_modules/hdr-histogram-js/dist/ByteBuffer.d.ts generated vendored Executable file
View file

@ -0,0 +1,20 @@
/**
* Mimic Java's ByteBufffer with big endian order
*/
declare class ByteBuffer {
position: number;
data: Uint8Array;
int32ArrayForConvert: Uint32Array;
int8ArrayForConvert: Uint8Array;
static allocate(size?: number): ByteBuffer;
constructor(data: Uint8Array);
put(value: number): void;
putInt32(value: number): void;
putInt64(value: number): void;
putArray(array: Uint8Array): void;
get(): number;
getInt32(): number;
getInt64(): number;
resetPosition(): void;
}
export default ByteBuffer;

71
my-app/node_modules/hdr-histogram-js/dist/ByteBuffer.js generated vendored Executable file
View file

@ -0,0 +1,71 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const { pow, floor } = Math;
const TWO_POW_32 = pow(2, 32);
/**
* Mimic Java's ByteBufffer with big endian order
*/
class ByteBuffer {
constructor(data) {
this.position = 0;
this.data = data;
this.int32ArrayForConvert = new Uint32Array(1);
this.int8ArrayForConvert = new Uint8Array(this.int32ArrayForConvert.buffer);
}
static allocate(size = 16) {
return new ByteBuffer(new Uint8Array(size));
}
put(value) {
if (this.position === this.data.length) {
const oldArray = this.data;
this.data = new Uint8Array(this.data.length * 2);
this.data.set(oldArray);
}
this.data[this.position] = value;
this.position++;
}
putInt32(value) {
if (this.data.length - this.position < 4) {
const oldArray = this.data;
this.data = new Uint8Array(this.data.length * 2 + 4);
this.data.set(oldArray);
}
this.int32ArrayForConvert[0] = value;
this.data.set(this.int8ArrayForConvert.reverse(), this.position);
this.position += 4;
}
putInt64(value) {
this.putInt32(floor(value / TWO_POW_32));
this.putInt32(value);
}
putArray(array) {
if (this.data.length - this.position < array.byteLength) {
const oldArray = this.data;
this.data = new Uint8Array(this.position + array.byteLength);
this.data.set(oldArray);
}
this.data.set(array, this.position);
this.position += array.byteLength;
}
get() {
const value = this.data[this.position];
this.position++;
return value;
}
getInt32() {
this.int8ArrayForConvert.set(this.data.slice(this.position, this.position + 4).reverse());
const value = this.int32ArrayForConvert[0];
this.position += 4;
return value;
}
getInt64() {
const high = this.getInt32();
const low = this.getInt32();
return high * TWO_POW_32 + low;
}
resetPosition() {
this.position = 0;
}
}
exports.default = ByteBuffer;
//# sourceMappingURL=ByteBuffer.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"ByteBuffer.js","sourceRoot":"","sources":["../src/ByteBuffer.ts"],"names":[],"mappings":"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"}

View file

@ -0,0 +1 @@
export {};

121
my-app/node_modules/hdr-histogram-js/dist/ByteBuffer.spec.js generated vendored Executable file
View file

@ -0,0 +1,121 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const ByteBuffer_1 = require("./ByteBuffer");
describe("ByteBuffer", () => {
it("should put value moving the position", () => {
// given
const buffer = ByteBuffer_1.default.allocate(3);
// when
buffer.put(123);
// then
expect(buffer.data[0]).toBe(123);
expect(buffer.position).toBe(1);
});
it("should resize when values overflow ", () => {
// given
const buffer = ByteBuffer_1.default.allocate(1);
buffer.put(123);
// when
buffer.put(42);
// then
expect(buffer.data[0]).toBe(123);
expect(buffer.data[1]).toBe(42);
});
it("should get value moving the position", () => {
// given
const buffer = ByteBuffer_1.default.allocate(1);
buffer.put(123);
buffer.resetPosition();
// when
const value = buffer.get();
// then
expect(value).toBe(123);
expect(buffer.position).toBe(1);
});
it("should put int32 value moving the position", () => {
// given
const buffer = ByteBuffer_1.default.allocate(8);
// when
buffer.putInt32(123);
// then
expect(buffer.data[3]).toBe(123);
expect(buffer.position).toBe(4);
});
it("should resize when int32 values overflow ", () => {
// given
const buffer = ByteBuffer_1.default.allocate(1);
// when
buffer.putInt32(42);
// then
expect(buffer.data[3]).toBe(42);
expect(buffer.position).toBe(4);
});
it("should get int32 value moving the position", () => {
// given
const buffer = ByteBuffer_1.default.allocate(1);
buffer.putInt32(123);
buffer.resetPosition();
// when
const value = buffer.getInt32();
// then
expect(value).toBe(123);
expect(buffer.position).toBe(4);
});
it("should put int64 value moving the position", () => {
// given
const buffer = ByteBuffer_1.default.allocate(8);
// when
buffer.putInt64(123);
// then
expect(buffer.data[7]).toBe(123);
expect(buffer.position).toBe(8);
});
it("should resize when int64 values overflow ", () => {
// given
const buffer = ByteBuffer_1.default.allocate(1);
// when
buffer.putInt64(42);
// then
expect(buffer.data[7]).toBe(42);
expect(buffer.position).toBe(8);
});
it("should get int64 value moving the position", () => {
// given
const buffer = ByteBuffer_1.default.allocate(1);
buffer.putInt64(Number.MAX_SAFE_INTEGER);
buffer.resetPosition();
// when
const value = buffer.getInt64();
// then
expect(value).toBe(Number.MAX_SAFE_INTEGER);
expect(buffer.position).toBe(8);
});
it("should copy all data when putting array", () => {
// given
const buffer = ByteBuffer_1.default.allocate(1024);
const array = new Uint8Array([1, 2, 3, 4]);
// when
buffer.putArray(array);
// then
buffer.resetPosition();
expect(buffer.get()).toBe(1);
expect(buffer.get()).toBe(2);
expect(buffer.get()).toBe(3);
expect(buffer.get()).toBe(4);
});
it("should resize when putting array bigger than capacity", () => {
// given
const buffer = ByteBuffer_1.default.allocate(1024);
const array = new Uint8Array([1, 2, 3, 4]);
// when
buffer.position = 1022;
buffer.putArray(array);
// then
buffer.position = 1022;
expect(buffer.get()).toBe(1);
expect(buffer.get()).toBe(2);
expect(buffer.get()).toBe(3);
expect(buffer.get()).toBe(4);
});
});
//# sourceMappingURL=ByteBuffer.spec.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"ByteBuffer.spec.js","sourceRoot":"","sources":["../src/ByteBuffer.spec.ts"],"names":[],"mappings":"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"}

View file

@ -0,0 +1,2 @@
export declare abstract class EncodableHistogram {
}

View file

@ -0,0 +1,14 @@
"use strict";
/*
* 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/
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.EncodableHistogram = void 0;
class EncodableHistogram {
}
exports.EncodableHistogram = EncodableHistogram;
//# sourceMappingURL=EncodableHistogram.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"EncodableHistogram.js","sourceRoot":"","sources":["../src/EncodableHistogram.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,MAAsB,kBAAkB;CAAG;AAA3C,gDAA2C"}

View file

@ -0,0 +1,5 @@
import TypedArrayHistogram from "./TypedArrayHistogram";
declare class Float64Histogram extends TypedArrayHistogram {
constructor(lowestDiscernibleValue: number, highestTrackableValue: number, numberOfSignificantValueDigits: number);
}
export default Float64Histogram;

View file

@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*
* 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/
*/
const TypedArrayHistogram_1 = require("./TypedArrayHistogram");
class Float64Histogram extends TypedArrayHistogram_1.default {
constructor(lowestDiscernibleValue, highestTrackableValue, numberOfSignificantValueDigits) {
super(Float64Array, lowestDiscernibleValue, highestTrackableValue, numberOfSignificantValueDigits);
}
}
exports.default = Float64Histogram;
//# sourceMappingURL=Float64Histogram.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"Float64Histogram.js","sourceRoot":"","sources":["../src/Float64Histogram.ts"],"names":[],"mappings":";;AAAA;;;;;;GAMG;AACH,+DAAwD;AAExD,MAAM,gBAAiB,SAAQ,6BAAmB;IAChD,YACE,sBAA8B,EAC9B,qBAA6B,EAC7B,8BAAsC;QAEtC,KAAK,CACH,YAAY,EACZ,sBAAsB,EACtB,qBAAqB,EACrB,8BAA8B,CAC/B,CAAC;IACJ,CAAC;CACF;AAED,kBAAe,gBAAgB,CAAC"}

195
my-app/node_modules/hdr-histogram-js/dist/Histogram.d.ts generated vendored Executable file
View file

@ -0,0 +1,195 @@
export declare const NO_TAG = "NO TAG";
export declare type BitBucketSize = 8 | 16 | 32 | 64 | "packed";
export interface HistogramSummary {
p50: number;
p75: number;
p90: number;
p97_5: number;
p99: number;
p99_9: number;
p99_99: number;
p99_999: number;
max: number;
totalCount: number;
}
export default interface Histogram {
/**
* Flag to enable automatic resizing of the underlying array
*/
autoResize: boolean;
/**
* The current highest trackable value. May change if autoresize flag is set to true
*/
readonly highestTrackableValue: number;
/**
* Total count of all recorded values in the histogram
*/
readonly totalCount: number;
/**
* The computed standard deviation of all recorded values in the histogram
*/
readonly stdDeviation: number;
/**
* The computed mean value of all recorded values in the histogram
*/
readonly mean: number;
/**
* Main percentiles, max value and total number of recorded values
*/
readonly summary: HistogramSummary;
/**
* A (conservatively high) estimate of the Histogram's total footprint in bytes
*/
readonly estimatedFootprintInBytes: number;
readonly maxValue: number;
readonly minNonZeroValue: number;
readonly numberOfSignificantValueDigits: number;
startTimeStampMsec: number;
endTimeStampMsec: number;
tag: string;
/**
* Record a value in the histogram
*
* @param value The value to be recorded
* @throws may throw Error if value is exceeds highestTrackableValue
*/
recordValue(value: number): void;
/**
* Record a value in the histogram (adding to the value's current count)
*
* @param value The value to be recorded
* @param count The number of occurrences of this value to record
* @throws ArrayIndexOutOfBoundsException (may throw) if value is exceeds highestTrackableValue
*/
recordValueWithCount(value: number, count: number): void;
/**
* Get the value at a given percentile.
* When the given percentile is &gt; 0.0, the value returned is the value that the given
* percentage of the overall recorded value entries in the histogram are either smaller than
* or equivalent to. When the given percentile is 0.0, the value returned is the value that all value
* entries in the histogram are either larger than or equivalent to.
* <p>
* Note that two values are "equivalent" in this statement if
* {@link org.HdrHistogram.JsHistogram#valuesAreEquivalent} would return true.
*
* @param percentile The percentile for which to return the associated value
* @return The value that the given percentage of the overall recorded value entries in the
* histogram are either smaller than or equivalent to. When the percentile is 0.0, returns the
* value that all value entries in the histogram are either larger than or equivalent to.
*/
getValueAtPercentile(percentile: number): number;
/**
* Produce textual representation of the value distribution of histogram data by percentile. The distribution is
* output with exponentially increasing resolution, with each exponentially decreasing half-distance containing
* <i>dumpTicksPerHalf</i> percentile reporting tick points.
*
* @param printStream Stream into which the distribution will be output
* <p>
* @param percentileTicksPerHalfDistance The number of reporting points per exponentially decreasing half-distance
* <p>
* @param outputValueUnitScalingRatio The scaling factor by which to divide histogram recorded values units in
* output
* @param useCsvFormat Output in CSV format if true. Otherwise use plain text form.
*/
outputPercentileDistribution(percentileTicksPerHalfDistance?: number, outputValueUnitScalingRatio?: number, useCsvFormat?: false): string;
toJSON(): HistogramSummary;
/**
* Record a value in the histogram.
* <p>
* To compensate for the loss of sampled values when a recorded value is larger than the expected
* interval between value samples, Histogram will auto-generate an additional series of decreasingly-smaller
* (down to the expectedIntervalBetweenValueSamples) value records.
* <p>
* Note: This is a at-recording correction method, as opposed to the post-recording correction method provided
* by {@link #copyCorrectedForCoordinatedOmission(long)}.
* The two methods are mutually exclusive, and only one of the two should be be used on a given data set to correct
* for the same coordinated omission issue.
* <p>
* See notes in the description of the Histogram calls for an illustration of why this corrective behavior is
* important.
*
* @param value The value to record
* @param expectedIntervalBetweenValueSamples If expectedIntervalBetweenValueSamples is larger than 0, add
* auto-generated value records as appropriate if value is larger
* than expectedIntervalBetweenValueSamples
* @throws ArrayIndexOutOfBoundsException (may throw) if value is exceeds highestTrackableValue
*/
recordValueWithExpectedInterval(value: number, expectedIntervalBetweenValueSamples: number): void;
/**
* Add the contents of another histogram to this one, while correcting the incoming data for coordinated omission.
* <p>
* To compensate for the loss of sampled values when a recorded value is larger than the expected
* interval between value samples, the values added will include an auto-generated additional series of
* decreasingly-smaller (down to the expectedIntervalBetweenValueSamples) value records for each count found
* in the current histogram that is larger than the expectedIntervalBetweenValueSamples.
*
* Note: This is a post-recording correction method, as opposed to the at-recording correction method provided
* by {@link #recordValueWithExpectedInterval(long, long) recordValueWithExpectedInterval}. The two
* methods are mutually exclusive, and only one of the two should be be used on a given data set to correct
* for the same coordinated omission issue.
* by
* <p>
* See notes in the description of the Histogram calls for an illustration of why this corrective behavior is
* important.
*
* @param otherHistogram The other histogram. highestTrackableValue and largestValueWithSingleUnitResolution must match.
* @param expectedIntervalBetweenValueSamples If expectedIntervalBetweenValueSamples is larger than 0, add
* auto-generated value records as appropriate if value is larger
* than expectedIntervalBetweenValueSamples
* @throws ArrayIndexOutOfBoundsException (may throw) if values exceed highestTrackableValue
*/
addWhileCorrectingForCoordinatedOmission(otherHistogram: Histogram, expectedIntervalBetweenValueSamples: number): void;
/**
* Get a copy of this histogram, corrected for coordinated omission.
* <p>
* To compensate for the loss of sampled values when a recorded value is larger than the expected
* interval between value samples, the new histogram will include an auto-generated additional series of
* decreasingly-smaller (down to the expectedIntervalBetweenValueSamples) value records for each count found
* in the current histogram that is larger than the expectedIntervalBetweenValueSamples.
*
* Note: This is a post-correction method, as opposed to the at-recording correction method provided
* by {@link #recordValueWithExpectedInterval(long, long) recordValueWithExpectedInterval}. The two
* methods are mutually exclusive, and only one of the two should be be used on a given data set to correct
* for the same coordinated omission issue.
* by
* <p>
* See notes in the description of the Histogram calls for an illustration of why this corrective behavior is
* important.
*
* @param expectedIntervalBetweenValueSamples If expectedIntervalBetweenValueSamples is larger than 0, add
* auto-generated value records as appropriate if value is larger
* than expectedIntervalBetweenValueSamples
* @return a copy of this histogram, corrected for coordinated omission.
*/
copyCorrectedForCoordinatedOmission(expectedIntervalBetweenValueSamples: number): Histogram;
/**
* Add the contents of another histogram to this one.
* <p>
* As part of adding the contents, the start/end timestamp range of this histogram will be
* extended to include the start/end timestamp range of the other histogram.
*
* @param otherHistogram The other histogram.
* @throws (may throw) if values in fromHistogram's are
* higher than highestTrackableValue.
*/
add(otherHistogram: Histogram): void;
/**
* Subtract the contents of another histogram from this one.
* <p>
* The start/end timestamps of this histogram will remain unchanged.
*
* @param otherHistogram The other histogram.
* @throws ArrayIndexOutOfBoundsException (may throw) if values in otherHistogram's are higher than highestTrackableValue.
*
*/
subtract(otherHistogram: Histogram): void;
reset(): void;
/**
* Clean up memory associated to this histogram. Useful for WebAssembly implementations
*/
destroy(): void;
}
export interface HistogramConstructor {
new (lowestDiscernibleValue: number, highestTrackableValue: number, numberOfSignificantValueDigits: number): Histogram;
}
export declare const toSummary: (histogram: Histogram) => HistogramSummary;

View file

@ -0,0 +1 @@
export {};

View file

@ -0,0 +1,146 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
/*
* 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/
*/
const fc = require("fast-check");
const hdr = require("./index");
const wasm_1 = require("./wasm");
const runFromStryker = __dirname.includes("stryker");
const runnerOptions = {
numRuns: runFromStryker ? 10 : 1000,
verbose: true,
};
describe("Histogram percentile computation", () => {
beforeAll(wasm_1.initWebAssembly);
const numberOfSignificantValueDigits = 3;
[true, false].forEach((useWebAssembly) => [16, "packed"].forEach((bitBucketSize) => it(`Histogram ${bitBucketSize} (wasm: ${useWebAssembly}) should be accurate according to its significant figures`, () => __awaiter(void 0, void 0, void 0, function* () {
yield wasm_1.initWebAssembly();
fc.assert(fc.property(arbData(2000), (numbers) => {
const histogram = hdr.build({
bitBucketSize,
numberOfSignificantValueDigits,
useWebAssembly,
});
numbers.forEach((n) => histogram.recordValue(n));
const actual = quantile(numbers, 90);
const got = histogram.getValueAtPercentile(90);
const relativeError = Math.abs(1 - got / actual);
const variation = Math.pow(10, -numberOfSignificantValueDigits);
histogram.destroy();
return relativeError < variation;
}), runnerOptions);
}))));
});
describe("Histogram percentile computation (packed vs classic)", () => {
const numberOfSignificantValueDigits = 3;
const classicHistogram = hdr.build({
numberOfSignificantValueDigits,
});
const histogram = hdr.build({
numberOfSignificantValueDigits,
bitBucketSize: "packed",
useWebAssembly: false,
});
it(`should be accurate according to its significant figures`, () => {
fc.assert(fc.property(arbData(5), (numbers) => {
histogram.reset();
classicHistogram.reset();
numbers.forEach((n) => histogram.recordValue(n));
numbers.forEach((n) => classicHistogram.recordValue(n));
const actual = classicHistogram.getValueAtPercentile(90);
const got = histogram.getValueAtPercentile(90);
return actual === got;
}), runnerOptions);
});
});
describe("Histogram percentile computation with CO correction (wasm vs js)", () => {
beforeAll(wasm_1.initWebAssembly);
let jsHistogram;
let wasmHistogram;
beforeEach(() => {
jsHistogram = hdr.build({
useWebAssembly: false,
});
wasmHistogram = hdr.build({
useWebAssembly: true,
});
});
afterEach(() => {
jsHistogram.destroy();
wasmHistogram.destroy();
});
it(`should be accurate according to its significant figures`, () => {
fc.assert(fc.property(arbData(1, 100 * 1000), (numbers) => {
jsHistogram.reset();
wasmHistogram.reset();
numbers.forEach((n) => {
jsHistogram.recordValueWithExpectedInterval(n, 1000);
});
numbers.forEach((n) => {
wasmHistogram.recordValueWithExpectedInterval(n, 1000);
});
const js = jsHistogram.getValueAtPercentile(90);
const wasm = wasmHistogram.getValueAtPercentile(90);
const relativeError = Math.abs(1 - js / wasm);
const variation = Math.pow(10, -3);
if (relativeError >= variation) {
console.log({ js, wasm });
}
return relativeError < variation;
}), runnerOptions);
});
});
describe("Histogram encoding/decoding", () => {
beforeAll(wasm_1.initWebAssembly);
const numberOfSignificantValueDigits = 3;
[true, false].forEach((useWebAssembly) => [8, 16, 32, 64, "packed"].forEach((bitBucketSize) => {
it(`Histogram ${bitBucketSize} (wasm: ${useWebAssembly}) should keep all data after an encoding/decoding roundtrip`, () => {
fc.assert(fc.property(arbData(1), fc.double(50, 100), (numbers, percentile) => {
const histogram = hdr.build({
bitBucketSize,
numberOfSignificantValueDigits,
useWebAssembly,
});
numbers.forEach((n) => histogram.recordValue(n));
const encodedHistogram = hdr.encodeIntoCompressedBase64(histogram);
const decodedHistogram = hdr.decodeFromCompressedBase64(encodedHistogram);
const actual = histogram.getValueAtPercentile(percentile);
const got = decodedHistogram.getValueAtPercentile(percentile);
histogram.destroy();
decodedHistogram.destroy();
return actual === got;
}), runnerOptions);
});
}));
});
const arbData = (size, max = Number.MAX_SAFE_INTEGER) => fc.array(fc.integer(1, max), size, size);
// reference implementation
const quantile = (inputData, percentile) => {
const data = [...inputData].sort((a, b) => a - b);
const index = (percentile / 100) * (data.length - 1);
let result;
if (Math.floor(index) === index) {
result = data[index];
}
else {
const i = Math.floor(index);
const fraction = index - i;
result = data[i] + (data[i + 1] - data[i]) * fraction;
}
return result;
};
//# sourceMappingURL=Histogram.fc.spec.js.map

File diff suppressed because one or more lines are too long

22
my-app/node_modules/hdr-histogram-js/dist/Histogram.js generated vendored Executable file
View file

@ -0,0 +1,22 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.toSummary = exports.NO_TAG = void 0;
const formatters_1 = require("./formatters");
exports.NO_TAG = "NO TAG";
exports.toSummary = (histogram) => {
const { totalCount, maxValue, numberOfSignificantValueDigits } = histogram;
const round = formatters_1.keepSignificantDigits(numberOfSignificantValueDigits);
return {
p50: round(histogram.getValueAtPercentile(50)),
p75: round(histogram.getValueAtPercentile(75)),
p90: round(histogram.getValueAtPercentile(90)),
p97_5: round(histogram.getValueAtPercentile(97.5)),
p99: round(histogram.getValueAtPercentile(99)),
p99_9: round(histogram.getValueAtPercentile(99.9)),
p99_99: round(histogram.getValueAtPercentile(99.99)),
p99_999: round(histogram.getValueAtPercentile(99.999)),
max: maxValue,
totalCount,
};
};
//# sourceMappingURL=Histogram.js.map

1
my-app/node_modules/hdr-histogram-js/dist/Histogram.js.map generated vendored Executable file
View file

@ -0,0 +1 @@
{"version":3,"file":"Histogram.js","sourceRoot":"","sources":["../src/Histogram.ts"],"names":[],"mappings":";;;AAAA,6CAAqD;AAExC,QAAA,MAAM,GAAG,QAAQ,CAAC;AA6OlB,QAAA,SAAS,GAAG,CAAC,SAAoB,EAAoB,EAAE;IAClE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,8BAA8B,EAAE,GAAG,SAAS,CAAC;IAC3E,MAAM,KAAK,GAAG,kCAAqB,CAAC,8BAA8B,CAAC,CAAC;IACpE,OAAO;QACL,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;QAC9C,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;QAC9C,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;QAC9C,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAClD,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;QAC9C,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;QACpD,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;QACtD,GAAG,EAAE,QAAQ;QACb,UAAU;KACX,CAAC;AACJ,CAAC,CAAC"}

View file

@ -0,0 +1 @@
export {};

473
my-app/node_modules/hdr-histogram-js/dist/Histogram.spec.js generated vendored Executable file
View file

@ -0,0 +1,473 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const _1 = require(".");
const JsHistogram_1 = require("./JsHistogram");
const Histogram_1 = require("./Histogram");
const Int32Histogram_1 = require("./Int32Histogram");
const wasm_1 = require("./wasm");
class HistogramForTests extends JsHistogram_1.default {
//constructor() {}
clearCounts() { }
incrementCountAtIndex(index) { }
incrementTotalCount() { }
addToTotalCount(value) { }
setTotalCount(totalCount) { }
resize(newHighestTrackableValue) {
this.establishSize(newHighestTrackableValue);
}
addToCountAtIndex(index, value) { }
setCountAtIndex(index, value) { }
getTotalCount() {
return 0;
}
getCountAtIndex(index) {
return 0;
}
_getEstimatedFootprintInBytes() {
return 42;
}
copyCorrectedForCoordinatedOmission(expectedIntervalBetweenValueSamples) {
return this;
}
}
describe("Histogram initialization", () => {
let histogram;
beforeEach(() => {
histogram = new HistogramForTests(1, Number.MAX_SAFE_INTEGER, 3);
});
it("should set sub bucket size", () => {
expect(histogram.subBucketCount).toBe(2048);
});
it("should set resize to false when max value specified", () => {
expect(histogram.autoResize).toBe(false);
});
it("should compute counts array length", () => {
expect(histogram.countsArrayLength).toBe(45056);
});
it("should compute bucket count", () => {
expect(histogram.bucketCount).toBe(43);
});
it("should set min non zero value", () => {
expect(histogram.minNonZeroValue).toBe(Number.MAX_SAFE_INTEGER);
});
it("should set max value", () => {
expect(histogram.maxValue).toBe(0);
});
});
describe("Histogram recording values", () => {
it("should compute count index when value in first bucket", () => {
// given
const histogram = new HistogramForTests(1, Number.MAX_SAFE_INTEGER, 3);
// when
const index = histogram.countsArrayIndex(2000); // 2000 < 2048
expect(index).toBe(2000);
});
it("should compute count index when value outside first bucket", () => {
// given
const histogram = new HistogramForTests(1, Number.MAX_SAFE_INTEGER, 3);
// when
const index = histogram.countsArrayIndex(2050); // 2050 > 2048
// then
expect(index).toBe(2049);
});
it("should compute count index taking into account lowest discernible value", () => {
// given
const histogram = new HistogramForTests(2000, Number.MAX_SAFE_INTEGER, 2);
// when
const index = histogram.countsArrayIndex(16000);
// then
expect(index).toBe(15);
});
it("should compute count index of a big value taking into account lowest discernible value", () => {
// given
const histogram = new HistogramForTests(2000, Number.MAX_SAFE_INTEGER, 2);
// when
const bigValue = Number.MAX_SAFE_INTEGER - 1;
const index = histogram.countsArrayIndex(bigValue);
// then
expect(index).toBe(4735);
});
it("should update min non zero value", () => {
// given
const histogram = new HistogramForTests(1, Number.MAX_SAFE_INTEGER, 3);
// when
histogram.recordValue(123);
// then
expect(histogram.minNonZeroValue).toBe(123);
});
it("should update max value", () => {
// given
const histogram = new HistogramForTests(1, Number.MAX_SAFE_INTEGER, 3);
// when
histogram.recordValue(123);
// then
expect(histogram.maxValue).toBe(123);
});
it("should throw an error when value bigger than highest trackable value", () => {
// given
const histogram = new HistogramForTests(1, 4096, 3);
// when then
expect(() => histogram.recordValue(9000)).toThrowError();
});
it("should not throw an error when autoresize enable and value bigger than highest trackable value", () => {
// given
const histogram = new HistogramForTests(1, 4096, 3);
histogram.autoResize = true;
// when then
expect(() => histogram.recordValue(9000)).not.toThrowError();
});
it("should increase counts array size when recording value bigger than highest trackable value", () => {
// given
const histogram = new HistogramForTests(1, 4096, 3);
histogram.autoResize = true;
// when
histogram.recordValue(9000);
// then
expect(histogram.highestTrackableValue).toBeGreaterThan(9000);
});
});
describe("Histogram computing statistics", () => {
const histogram = new Int32Histogram_1.default(1, Number.MAX_SAFE_INTEGER, 3);
it("should compute mean value", () => {
// given
histogram.reset();
// when
histogram.recordValue(25);
histogram.recordValue(50);
histogram.recordValue(75);
// then
expect(histogram.mean).toBe(50);
});
it("should compute standard deviation", () => {
// given
histogram.reset();
// when
histogram.recordValue(25);
histogram.recordValue(50);
histogram.recordValue(75);
// then
expect(histogram.stdDeviation).toBeGreaterThan(20.4124);
expect(histogram.stdDeviation).toBeLessThan(20.4125);
});
it("should compute percentile distribution", () => {
// given
histogram.reset();
// when
histogram.recordValue(25);
histogram.recordValue(50);
histogram.recordValue(75);
// then
const expectedResult = ` Value Percentile TotalCount 1/(1-Percentile)
25.000 0.000000000000 1 1.00
25.000 0.100000000000 1 1.11
25.000 0.200000000000 1 1.25
25.000 0.300000000000 1 1.43
50.000 0.400000000000 2 1.67
50.000 0.500000000000 2 2.00
50.000 0.550000000000 2 2.22
50.000 0.600000000000 2 2.50
50.000 0.650000000000 2 2.86
75.000 0.700000000000 3 3.33
75.000 1.000000000000 3
#[Mean = 50.000, StdDeviation = 20.412]
#[Max = 75.000, Total count = 3]
#[Buckets = 43, SubBuckets = 2048]
`;
expect(histogram.outputPercentileDistribution()).toBe(expectedResult);
});
it("should compute percentile distribution in csv format", () => {
// given
histogram.reset();
// when
histogram.recordValue(25);
histogram.recordValue(50);
histogram.recordValue(75);
// then
const expectedResult = `"Value","Percentile","TotalCount","1/(1-Percentile)"
25.000,0.000000000000,1,1.00
25.000,0.100000000000,1,1.11
25.000,0.200000000000,1,1.25
25.000,0.300000000000,1,1.43
50.000,0.400000000000,2,1.67
50.000,0.500000000000,2,2.00
50.000,0.550000000000,2,2.22
50.000,0.600000000000,2,2.50
50.000,0.650000000000,2,2.86
75.000,0.700000000000,3,3.33
75.000,1.000000000000,3,Infinity
`;
expect(histogram.outputPercentileDistribution(undefined, undefined, true)).toBe(expectedResult);
});
it("should compute percentile distribution in JSON format with rounding according to number of significant digits", () => {
// given
histogram.reset();
// when
histogram.recordValue(25042);
histogram.recordValue(50042);
histogram.recordValue(75042);
// then
const { summary } = histogram;
expect(summary.p50).toEqual(50000);
});
});
describe("Histogram correcting coordinated omissions", () => {
const histogram = new Int32Histogram_1.default(1, Number.MAX_SAFE_INTEGER, 3);
it("should generate additional values when recording", () => {
// given
histogram.reset();
// when
histogram.recordValueWithExpectedInterval(207, 100);
// then
expect(histogram.totalCount).toBe(2);
expect(histogram.minNonZeroValue).toBe(107);
expect(histogram.maxValue).toBe(207);
});
it("should generate additional values when correcting after recording", () => {
// given
histogram.reset();
histogram.recordValue(207);
histogram.recordValue(207);
// when
const correctedHistogram = histogram.copyCorrectedForCoordinatedOmission(100);
// then
expect(correctedHistogram.totalCount).toBe(4);
expect(correctedHistogram.minNonZeroValue).toBe(107);
expect(correctedHistogram.maxValue).toBe(207);
});
it("should not generate additional values when correcting after recording", () => {
// given
histogram.reset();
histogram.recordValue(207);
histogram.recordValue(207);
// when
const correctedHistogram = histogram.copyCorrectedForCoordinatedOmission(1000);
// then
expect(correctedHistogram.totalCount).toBe(2);
expect(correctedHistogram.minNonZeroValue).toBe(207);
expect(correctedHistogram.maxValue).toBe(207);
});
});
describe("WASM Histogram not initialized", () => {
it("should throw a clear error message", () => {
expect(() => _1.build({ useWebAssembly: true })).toThrow("WebAssembly is not ready yet");
expect(() => wasm_1.WasmHistogram.build()).toThrow("WebAssembly is not ready yet");
expect(() => wasm_1.WasmHistogram.decode(null)).toThrow("WebAssembly is not ready yet");
});
});
describe("WASM Histogram not happy path", () => {
beforeEach(wasm_1.initWebAssemblySync);
it("should throw a clear error message when used after destroy", () => {
const destroyedHistogram = _1.build({ useWebAssembly: true });
destroyedHistogram.destroy();
expect(() => destroyedHistogram.recordValue(42)).toThrow("Cannot use a destroyed histogram");
});
it("should not crash when displayed after destroy", () => {
const destroyedHistogram = _1.build({ useWebAssembly: true });
destroyedHistogram.destroy();
expect(destroyedHistogram + "").toEqual("Destroyed WASM histogram");
});
it("should throw a clear error message when added to a JS regular Histogram", () => {
const wasmHistogram = _1.build({ useWebAssembly: true });
const jsHistogram = _1.build({ useWebAssembly: false });
expect(() => jsHistogram.add(wasmHistogram)).toThrow("Cannot add a WASM histogram to a regular JS histogram");
});
it("should throw a clear error message when trying to add a JS regular Histogram", () => {
const wasmHistogram = _1.build({ useWebAssembly: true });
const jsHistogram = _1.build({ useWebAssembly: false });
expect(() => wasmHistogram.add(jsHistogram)).toThrow("Cannot add a regular JS histogram to a WASM histogram");
});
it("should throw a clear error message when substracted to a JS regular Histogram", () => {
const wasmHistogram = _1.build({ useWebAssembly: true });
const jsHistogram = _1.build({ useWebAssembly: false });
expect(() => jsHistogram.subtract(wasmHistogram)).toThrow("Cannot subtract a WASM histogram to a regular JS histogram");
});
it("should throw a clear error message when trying to add a JS regular Histogram", () => {
const wasmHistogram = _1.build({ useWebAssembly: true });
const jsHistogram = _1.build({ useWebAssembly: false });
expect(() => wasmHistogram.subtract(jsHistogram)).toThrow("Cannot subtract a regular JS histogram to a WASM histogram");
});
});
describe("WASM estimated memory footprint", () => {
let wasmHistogram;
beforeAll(wasm_1.initWebAssembly);
afterEach(() => wasmHistogram.destroy());
it("should be a little bit more than js footprint for packed histograms", () => {
wasmHistogram = _1.build({ useWebAssembly: true, bitBucketSize: "packed" });
expect(wasmHistogram.estimatedFootprintInBytes).toBeGreaterThan(_1.build({ bitBucketSize: "packed" }).estimatedFootprintInBytes);
});
});
describe("WASM Histogram correcting coordinated omissions", () => {
let histogram;
beforeAll(wasm_1.initWebAssembly);
beforeEach(() => {
histogram = _1.build({ useWebAssembly: true });
});
afterEach(() => histogram.destroy());
it("should generate additional values when recording", () => {
// given
histogram.reset();
// when
histogram.recordValueWithExpectedInterval(207, 100);
// then
expect(histogram.totalCount).toBe(2);
expect(histogram.minNonZeroValue).toBe(107);
expect(histogram.maxValue).toBe(207);
});
it("should generate additional values when correcting after recording", () => {
// given
histogram.reset();
histogram.recordValue(207);
histogram.recordValue(207);
// when
const correctedHistogram = histogram.copyCorrectedForCoordinatedOmission(100);
// then
expect(correctedHistogram.totalCount).toBe(4);
expect(correctedHistogram.minNonZeroValue).toBe(107);
expect(correctedHistogram.maxValue).toBe(207);
});
it("should not generate additional values when correcting after recording", () => {
// given
histogram.reset();
histogram.recordValue(207);
histogram.recordValue(207);
// when
const correctedHistogram = histogram.copyCorrectedForCoordinatedOmission(1000);
// then
expect(correctedHistogram.totalCount).toBe(2);
expect(correctedHistogram.minNonZeroValue).toBe(207);
expect(correctedHistogram.maxValue).toBe(207);
});
});
describe("Histogram add & substract", () => {
beforeAll(wasm_1.initWebAssembly);
it("should add histograms of same size", () => {
// given
const histogram = new Int32Histogram_1.default(1, Number.MAX_SAFE_INTEGER, 2);
const histogram2 = new Int32Histogram_1.default(1, Number.MAX_SAFE_INTEGER, 2);
histogram.recordValue(42);
histogram2.recordValue(158);
// when
histogram.add(histogram2);
// then
expect(histogram.totalCount).toBe(2);
expect(histogram.mean).toBe(100);
});
it("should add histograms of different sizes & precisions", () => {
// given
const histogram = _1.build({
lowestDiscernibleValue: 1,
highestTrackableValue: 1024,
autoResize: true,
numberOfSignificantValueDigits: 2,
bitBucketSize: "packed",
useWebAssembly: true,
});
const histogram2 = _1.build({
lowestDiscernibleValue: 1,
highestTrackableValue: 1024,
autoResize: true,
numberOfSignificantValueDigits: 3,
bitBucketSize: 32,
useWebAssembly: true,
});
//histogram2.autoResize = true;
histogram.recordValue(42000);
histogram2.recordValue(1000);
// when
histogram.add(histogram2);
// then
expect(histogram.totalCount).toBe(2);
expect(Math.floor(histogram.mean / 100)).toBe(215);
});
it("should add histograms of different sizes", () => {
// given
const histogram = new Int32Histogram_1.default(1, Number.MAX_SAFE_INTEGER, 2);
const histogram2 = new Int32Histogram_1.default(1, 1024, 2);
histogram2.autoResize = true;
histogram.recordValue(42000);
histogram2.recordValue(1000);
// when
histogram.add(histogram2);
// then
expect(histogram.totalCount).toBe(2);
expect(Math.floor(histogram.mean / 100)).toBe(215);
});
it("should be equal when another histogram of lower precision is added then subtracted", () => {
// given
const histogram = _1.build({ numberOfSignificantValueDigits: 5 });
const histogram2 = _1.build({ numberOfSignificantValueDigits: 3 });
histogram.recordValue(100);
histogram2.recordValue(42000);
// when
const before = histogram.summary;
histogram.add(histogram2);
histogram.subtract(histogram2);
// then
expect(histogram.summary).toStrictEqual(before);
});
it("should update percentiles when another histogram of same characteristics is substracted", () => {
// given
const histogram = _1.build({ numberOfSignificantValueDigits: 3 });
const histogram2 = _1.build({ numberOfSignificantValueDigits: 3 });
histogram.recordValueWithCount(100, 2);
histogram2.recordValueWithCount(100, 1);
histogram.recordValueWithCount(200, 2);
histogram2.recordValueWithCount(200, 1);
histogram.recordValueWithCount(300, 2);
histogram2.recordValueWithCount(300, 1);
// when
histogram.subtract(histogram2);
// then
expect(histogram.getValueAtPercentile(50)).toBe(200);
});
});
describe("Histogram clearing support", () => {
beforeAll(wasm_1.initWebAssembly);
it("should reset data in order to reuse histogram", () => {
// given
const histogram = _1.build({
lowestDiscernibleValue: 1,
highestTrackableValue: Number.MAX_SAFE_INTEGER,
numberOfSignificantValueDigits: 5,
useWebAssembly: true,
});
histogram.startTimeStampMsec = 42;
histogram.endTimeStampMsec = 56;
histogram.tag = "blabla";
histogram.recordValue(1000);
// when
histogram.reset();
// then
expect(histogram.totalCount).toBe(0);
expect(histogram.startTimeStampMsec).toBe(0);
expect(histogram.endTimeStampMsec).toBe(0);
expect(histogram.tag).toBe(Histogram_1.NO_TAG);
expect(histogram.maxValue).toBe(0);
expect(histogram.minNonZeroValue).toBeGreaterThan(Number.MAX_SAFE_INTEGER);
expect(histogram.getValueAtPercentile(99.999)).toBe(0);
});
it("should behave as new when reseted", () => {
// given
const histogram = _1.build({
lowestDiscernibleValue: 1,
highestTrackableValue: 15000,
numberOfSignificantValueDigits: 2,
});
const histogram2 = _1.build({
lowestDiscernibleValue: 1,
highestTrackableValue: 15000,
numberOfSignificantValueDigits: 2,
});
histogram.recordValue(1);
histogram.recordValue(100);
histogram.recordValue(2000);
histogram.reset();
// when
histogram.recordValue(1000);
histogram2.recordValue(1000);
// then
expect(histogram.mean).toBe(histogram2.mean);
});
});
//# sourceMappingURL=Histogram.spec.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,41 @@
import Histogram, { BitBucketSize } from "./Histogram";
export interface BuildRequest {
/**
* The size in bit of each count bucket
* Default value is 32
*/
bitBucketSize?: BitBucketSize;
/**
* Control whether or not the histogram can auto-resize and auto-adjust it's
* highestTrackableValue
* Default value is true
*/
autoResize?: boolean;
/**
* The lowest value that can be discerned (distinguished from 0) by the histogram.
* Must be a positive integer that is {@literal >=} 1. May be internally rounded
* down to nearest power of 2.
* Default value is 1
*/
lowestDiscernibleValue?: number;
/**
* The highest value to be tracked by the histogram. Must be a positive
* integer that is {@literal >=} (2 * lowestDiscernibleValue).
* Default value is Number.MAX_SAFE_INTEGER
*/
highestTrackableValue?: number;
/**
* The number of significant decimal digits to which the histogram will
* maintain value resolution and separation. Must be a non-negative
* integer between 0 and 5.
* Default value is 3
*/
numberOfSignificantValueDigits?: 1 | 2 | 3 | 4 | 5;
/**
* Is WebAssembly used to speed up computations.
* Default value is false
*/
useWebAssembly?: boolean;
}
export declare const defaultRequest: BuildRequest;
export declare const build: (request?: BuildRequest) => Histogram;

View file

@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.build = exports.defaultRequest = void 0;
const JsHistogramFactory_1 = require("./JsHistogramFactory");
const wasm_1 = require("./wasm");
exports.defaultRequest = {
bitBucketSize: 32,
autoResize: true,
lowestDiscernibleValue: 1,
highestTrackableValue: 2,
numberOfSignificantValueDigits: 3,
useWebAssembly: false,
};
exports.build = (request = exports.defaultRequest) => {
const parameters = Object.assign({}, exports.defaultRequest, request);
if (request.useWebAssembly && wasm_1.webAssemblyAvailable) {
return wasm_1.WasmHistogram.build(parameters);
}
const histogramConstr = JsHistogramFactory_1.constructorFromBucketSize(parameters.bitBucketSize);
const histogram = new histogramConstr(parameters.lowestDiscernibleValue, parameters.highestTrackableValue, parameters.numberOfSignificantValueDigits);
histogram.autoResize = parameters.autoResize;
return histogram;
};
//# sourceMappingURL=HistogramBuilder.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"HistogramBuilder.js","sourceRoot":"","sources":["../src/HistogramBuilder.ts"],"names":[],"mappings":";;;AACA,6DAAiE;AACjE,iCAA+E;AAyClE,QAAA,cAAc,GAAiB;IAC1C,aAAa,EAAE,EAAE;IACjB,UAAU,EAAE,IAAI;IAChB,sBAAsB,EAAE,CAAC;IACzB,qBAAqB,EAAE,CAAC;IACxB,8BAA8B,EAAE,CAAC;IACjC,cAAc,EAAE,KAAK;CACtB,CAAC;AAEW,QAAA,KAAK,GAAG,CAAC,OAAO,GAAG,sBAAc,EAAa,EAAE;IAC3D,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,sBAAc,EAAE,OAAO,CAAC,CAAC;IAC9D,IAAI,OAAO,CAAC,cAAc,IAAI,2BAAoB,EAAE;QAClD,OAAO,oBAAa,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;KACxC;IAED,MAAM,eAAe,GAAG,8CAAyB,CAC/C,UAAU,CAAC,aAA8B,CAC1C,CAAC;IAEF,MAAM,SAAS,GAAG,IAAI,eAAe,CACnC,UAAU,CAAC,sBAAgC,EAC3C,UAAU,CAAC,qBAA+B,EAC1C,UAAU,CAAC,8BAAwC,CACpD,CAAC;IACF,SAAS,CAAC,UAAU,GAAG,UAAU,CAAC,UAAqB,CAAC;IACxD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC"}

View file

@ -0,0 +1,38 @@
/**
* Represents a value point iterated through in a Histogram, with associated stats.
* <ul>
* <li><b><code>valueIteratedTo</code></b> :<br> The actual value level that was iterated to by the iterator</li>
* <li><b><code>prevValueIteratedTo</code></b> :<br> The actual value level that was iterated from by the iterator</li>
* <li><b><code>countAtValueIteratedTo</code></b> :<br> The count of recorded values in the histogram that
* exactly match this [lowestEquivalentValue(valueIteratedTo)...highestEquivalentValue(valueIteratedTo)] value
* range.</li>
* <li><b><code>countAddedInThisIterationStep</code></b> :<br> The count of recorded values in the histogram that
* were added to the totalCountToThisValue (below) as a result on this iteration step. Since multiple iteration
* steps may occur with overlapping equivalent value ranges, the count may be lower than the count found at
* the value (e.g. multiple linear steps or percentile levels can occur within a single equivalent value range)</li>
* <li><b><code>totalCountToThisValue</code></b> :<br> The total count of all recorded values in the histogram at
* values equal or smaller than valueIteratedTo.</li>
* <li><b><code>totalValueToThisValue</code></b> :<br> The sum of all recorded values in the histogram at values
* equal or smaller than valueIteratedTo.</li>
* <li><b><code>percentile</code></b> :<br> The percentile of recorded values in the histogram at values equal
* or smaller than valueIteratedTo.</li>
* <li><b><code>percentileLevelIteratedTo</code></b> :<br> The percentile level that the iterator returning this
* HistogramIterationValue had iterated to. Generally, percentileLevelIteratedTo will be equal to or smaller than
* percentile, but the same value point can contain multiple iteration levels for some iterators. E.g. a
* PercentileIterator can stop multiple times in the exact same value point (if the count at that value covers a
* range of multiple percentiles in the requested percentile iteration points).</li>
* </ul>
*/
declare class HistogramIterationValue {
valueIteratedTo: number;
valueIteratedFrom: number;
countAtValueIteratedTo: number;
countAddedInThisIterationStep: number;
totalCountToThisValue: number;
totalValueToThisValue: number;
percentile: number;
percentileLevelIteratedTo: number;
constructor();
reset(): void;
}
export default HistogramIterationValue;

View file

@ -0,0 +1,51 @@
"use strict";
/*
* 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/
*/
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Represents a value point iterated through in a Histogram, with associated stats.
* <ul>
* <li><b><code>valueIteratedTo</code></b> :<br> The actual value level that was iterated to by the iterator</li>
* <li><b><code>prevValueIteratedTo</code></b> :<br> The actual value level that was iterated from by the iterator</li>
* <li><b><code>countAtValueIteratedTo</code></b> :<br> The count of recorded values in the histogram that
* exactly match this [lowestEquivalentValue(valueIteratedTo)...highestEquivalentValue(valueIteratedTo)] value
* range.</li>
* <li><b><code>countAddedInThisIterationStep</code></b> :<br> The count of recorded values in the histogram that
* were added to the totalCountToThisValue (below) as a result on this iteration step. Since multiple iteration
* steps may occur with overlapping equivalent value ranges, the count may be lower than the count found at
* the value (e.g. multiple linear steps or percentile levels can occur within a single equivalent value range)</li>
* <li><b><code>totalCountToThisValue</code></b> :<br> The total count of all recorded values in the histogram at
* values equal or smaller than valueIteratedTo.</li>
* <li><b><code>totalValueToThisValue</code></b> :<br> The sum of all recorded values in the histogram at values
* equal or smaller than valueIteratedTo.</li>
* <li><b><code>percentile</code></b> :<br> The percentile of recorded values in the histogram at values equal
* or smaller than valueIteratedTo.</li>
* <li><b><code>percentileLevelIteratedTo</code></b> :<br> The percentile level that the iterator returning this
* HistogramIterationValue had iterated to. Generally, percentileLevelIteratedTo will be equal to or smaller than
* percentile, but the same value point can contain multiple iteration levels for some iterators. E.g. a
* PercentileIterator can stop multiple times in the exact same value point (if the count at that value covers a
* range of multiple percentiles in the requested percentile iteration points).</li>
* </ul>
*/
class HistogramIterationValue {
constructor() {
this.reset();
}
reset() {
this.valueIteratedTo = 0;
this.valueIteratedFrom = 0;
this.countAtValueIteratedTo = 0;
this.countAddedInThisIterationStep = 0;
this.totalCountToThisValue = 0;
this.totalValueToThisValue = 0;
this.percentile = 0.0;
this.percentileLevelIteratedTo = 0.0;
}
}
exports.default = HistogramIterationValue;
//# sourceMappingURL=HistogramIterationValue.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"HistogramIterationValue.js","sourceRoot":"","sources":["../src/HistogramIterationValue.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAEH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,uBAAuB;IAU3B;QACE,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;IAED,KAAK;QACH,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,sBAAsB,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,6BAA6B,GAAG,CAAC,CAAC;QACvC,IAAI,CAAC,qBAAqB,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,qBAAqB,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QACtB,IAAI,CAAC,yBAAyB,GAAG,GAAG,CAAC;IACvC,CAAC;CACF;AAED,kBAAe,uBAAuB,CAAC"}

View file

@ -0,0 +1,63 @@
import Histogram, { BitBucketSize } from "./Histogram";
/**
* A histogram log reader.
* <p>
* Histogram logs are used to capture full fidelity, per-time-interval
* histograms of a recorded value.
* <p>
* For example, a histogram log can be used to capture high fidelity
* reaction-time logs for some measured system or subsystem component.
* Such a log would capture a full reaction time histogram for each
* logged interval, and could be used to later reconstruct a full
* HdrHistogram of the measured reaction time behavior for any arbitrary
* time range within the log, by adding [only] the relevant interval
* histograms.
* <h3>Histogram log format:</h3>
* A histogram log file consists of text lines. Lines beginning with
* the "#" character are optional and treated as comments. Lines
* containing the legend (starting with "Timestamp") are also optional
* and ignored in parsing the histogram log. All other lines must
* be valid interval description lines. Text fields are delimited by
* commas, spaces.
* <p>
* A valid interval description line contains an optional Tag=tagString
* text field, followed by an interval description.
* <p>
* A valid interval description must contain exactly four text fields:
* <ul>
* <li>StartTimestamp: The first field must contain a number parse-able as a Double value,
* representing the start timestamp of the interval in seconds.</li>
* <li>intervalLength: The second field must contain a number parse-able as a Double value,
* representing the length of the interval in seconds.</li>
* <li>Interval_Max: The third field must contain a number parse-able as a Double value,
* which generally represents the maximum value of the interval histogram.</li>
* <li>Interval_Compressed_Histogram: The fourth field must contain a text field
* parse-able as a Base64 text representation of a compressed HdrHistogram.</li>
* </ul>
* The log file may contain an optional indication of a starting time. Starting time
* is indicated using a special comments starting with "#[StartTime: " and followed
* by a number parse-able as a double, representing the start time (in seconds)
* that may be added to timestamps in the file to determine an absolute
* timestamp (e.g. since the epoch) for each interval.
*/
declare class HistogramLogReader {
startTimeSec: number;
baseTimeSec: number;
lines: string[];
currentLineIndex: number;
bitBucketSize: BitBucketSize;
useWebAssembly: boolean;
constructor(logContent: string, bitBucketSize?: BitBucketSize, useWebAssembly?: boolean);
/**
* Read the next interval histogram from the log. Returns a Histogram object if
* an interval line was found, or null if not.
* <p>Upon encountering any unexpected format errors in reading the next interval
* from the file, this method will return a null.
* @return a DecodedInterval, or a null if no appropriate interval found
*/
nextIntervalHistogram(rangeStartTimeSec?: number, rangeEndTimeSec?: number): Histogram | null;
private parseStartTimeFromLine;
private parseBaseTimeFromLine;
}
export declare const listTags: (content: string) => string[];
export default HistogramLogReader;

View file

@ -0,0 +1,152 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.listTags = 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/
*/
const Histogram_1 = require("./Histogram");
const encoding_1 = require("./encoding");
const TAG_PREFIX = "Tag=";
const TAG_PREFIX_LENGTH = "Tag=".length;
/**
* A histogram log reader.
* <p>
* Histogram logs are used to capture full fidelity, per-time-interval
* histograms of a recorded value.
* <p>
* For example, a histogram log can be used to capture high fidelity
* reaction-time logs for some measured system or subsystem component.
* Such a log would capture a full reaction time histogram for each
* logged interval, and could be used to later reconstruct a full
* HdrHistogram of the measured reaction time behavior for any arbitrary
* time range within the log, by adding [only] the relevant interval
* histograms.
* <h3>Histogram log format:</h3>
* A histogram log file consists of text lines. Lines beginning with
* the "#" character are optional and treated as comments. Lines
* containing the legend (starting with "Timestamp") are also optional
* and ignored in parsing the histogram log. All other lines must
* be valid interval description lines. Text fields are delimited by
* commas, spaces.
* <p>
* A valid interval description line contains an optional Tag=tagString
* text field, followed by an interval description.
* <p>
* A valid interval description must contain exactly four text fields:
* <ul>
* <li>StartTimestamp: The first field must contain a number parse-able as a Double value,
* representing the start timestamp of the interval in seconds.</li>
* <li>intervalLength: The second field must contain a number parse-able as a Double value,
* representing the length of the interval in seconds.</li>
* <li>Interval_Max: The third field must contain a number parse-able as a Double value,
* which generally represents the maximum value of the interval histogram.</li>
* <li>Interval_Compressed_Histogram: The fourth field must contain a text field
* parse-able as a Base64 text representation of a compressed HdrHistogram.</li>
* </ul>
* The log file may contain an optional indication of a starting time. Starting time
* is indicated using a special comments starting with "#[StartTime: " and followed
* by a number parse-able as a double, representing the start time (in seconds)
* that may be added to timestamps in the file to determine an absolute
* timestamp (e.g. since the epoch) for each interval.
*/
class HistogramLogReader {
constructor(logContent, bitBucketSize = 32, useWebAssembly = false) {
this.lines = splitLines(logContent);
this.currentLineIndex = 0;
this.bitBucketSize = bitBucketSize;
this.useWebAssembly = useWebAssembly;
}
/**
* Read the next interval histogram from the log. Returns a Histogram object if
* an interval line was found, or null if not.
* <p>Upon encountering any unexpected format errors in reading the next interval
* from the file, this method will return a null.
* @return a DecodedInterval, or a null if no appropriate interval found
*/
nextIntervalHistogram(rangeStartTimeSec = 0, rangeEndTimeSec = Number.MAX_VALUE) {
while (this.currentLineIndex < this.lines.length) {
const currentLine = this.lines[this.currentLineIndex];
this.currentLineIndex++;
if (currentLine.startsWith("#[StartTime:")) {
this.parseStartTimeFromLine(currentLine);
}
else if (currentLine.startsWith("#[BaseTime:")) {
this.parseBaseTimeFromLine(currentLine);
}
else if (currentLine.startsWith("#") ||
currentLine.startsWith('"StartTimestamp"')) {
// skip legend & meta data for now
}
else if (currentLine.includes(",")) {
const tokens = currentLine.split(",");
const [firstToken] = tokens;
let tag;
if (firstToken.startsWith(TAG_PREFIX)) {
tag = firstToken.substring(TAG_PREFIX_LENGTH);
tokens.shift();
}
else {
tag = Histogram_1.NO_TAG;
}
const [rawLogTimeStampInSec, rawIntervalLengthSec, , base64Histogram,] = tokens;
const logTimeStampInSec = Number.parseFloat(rawLogTimeStampInSec);
if (!this.baseTimeSec) {
// No explicit base time noted. Deduce from 1st observed time (compared to start time):
if (logTimeStampInSec < this.startTimeSec - 365 * 24 * 3600.0) {
// Criteria Note: if log timestamp is more than a year in the past (compared to
// StartTime), we assume that timestamps in the log are not absolute
this.baseTimeSec = this.startTimeSec;
}
else {
// Timestamps are absolute
this.baseTimeSec = 0.0;
}
}
if (rangeEndTimeSec < logTimeStampInSec) {
return null;
}
if (logTimeStampInSec < rangeStartTimeSec) {
continue;
}
const histogram = encoding_1.decodeFromCompressedBase64(base64Histogram, this.bitBucketSize, this.useWebAssembly);
histogram.startTimeStampMsec =
(this.baseTimeSec + logTimeStampInSec) * 1000;
const intervalLengthSec = Number.parseFloat(rawIntervalLengthSec);
histogram.endTimeStampMsec =
(this.baseTimeSec + logTimeStampInSec + intervalLengthSec) * 1000;
histogram.tag = tag;
return histogram;
}
}
return null;
}
parseStartTimeFromLine(line) {
this.startTimeSec = Number.parseFloat(line.split(" ")[1]);
}
parseBaseTimeFromLine(line) {
this.baseTimeSec = Number.parseFloat(line.split(" ")[1]);
}
}
const splitLines = (logContent) => logContent.split(/\r\n|\r|\n/g);
const shouldIncludeNoTag = (lines) => lines.find((line) => !line.startsWith("#") &&
!line.startsWith('"') &&
!line.startsWith(TAG_PREFIX) &&
line.includes(","));
exports.listTags = (content) => {
const lines = splitLines(content);
const tags = lines
.filter((line) => line.includes(",") && line.startsWith(TAG_PREFIX))
.map((line) => line.substring(TAG_PREFIX_LENGTH, line.indexOf(",")));
const tagsWithoutDuplicates = new Set(tags);
const result = Array.from(tagsWithoutDuplicates);
if (shouldIncludeNoTag(lines)) {
result.unshift("NO TAG");
}
return result;
};
exports.default = HistogramLogReader;
//# sourceMappingURL=HistogramLogReader.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"HistogramLogReader.js","sourceRoot":"","sources":["../src/HistogramLogReader.ts"],"names":[],"mappings":"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"}

View file

@ -0,0 +1 @@
export {};

View file

@ -0,0 +1,212 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const HistogramLogReader_1 = require("./HistogramLogReader");
const wasm_1 = require("./wasm");
const { floor } = Math;
function checkNotNull(actual) {
expect(actual).not.toBeNull();
}
describe("Histogram Log Reader", () => {
let fileContent;
let tagFileContent;
let fileContentWithBaseTime;
let fileContentWithoutHeader;
let fileContentWithTrailingWhitespace;
beforeAll(() => {
// when using mutation testing tool stryker, source code
// is copied in a sandbox directory without the test_files
// directory...
const runFromStryker = __dirname.includes("stryker");
const prefix = runFromStryker ? "../.." : ".";
fileContent = fs.readFileSync(`${prefix}/test_files/jHiccup-2.0.7S.logV2.hlog`, "UTF-8");
fileContentWithBaseTime = fs.readFileSync(`${prefix}/test_files/jHiccup-with-basetime-2.0.7S.logV2.hlog`, "UTF-8");
fileContentWithoutHeader = fs.readFileSync(`${prefix}/test_files/jHiccup-no-header-2.0.7S.logV2.hlog`, "UTF-8");
tagFileContent = fs.readFileSync(`${prefix}/test_files/tagged-Log.logV2.hlog`, "UTF-8");
fileContentWithTrailingWhitespace = fs.readFileSync(`${prefix}/test_files/bug-whitespace.hlog`, "UTF-8");
});
it("should update startTimeSec reading first histogram", () => {
// given
const reader = new HistogramLogReader_1.default(fileContent);
// when
reader.nextIntervalHistogram();
// then
expect(reader.startTimeSec).toBe(1441812279.474);
});
it("should read first histogram starting from the beginning", () => {
// given
const reader = new HistogramLogReader_1.default(fileContent);
// when
const histogram = reader.nextIntervalHistogram();
// then
checkNotNull(histogram);
// if mean is good, strong probability everything else is good as well
expect(floor(histogram.mean)).toBe(301998);
});
it("should read encoded histogram and use provided constructor", () => {
// given
const reader = new HistogramLogReader_1.default(fileContent, "packed");
// when
const histogram = reader.nextIntervalHistogram();
// then
checkNotNull(histogram);
// if mean is good, strong probability everything else is good as well
expect(floor(histogram.mean)).toBe(301998);
});
it("should return null if no histogram in the logs", () => {
// given
const reader = new HistogramLogReader_1.default("# empty");
// when
const histogram = reader.nextIntervalHistogram();
// then
expect(histogram).toBeNull();
});
it("should return next histogram in the logs", () => {
// given
const reader = new HistogramLogReader_1.default(fileContent);
reader.nextIntervalHistogram();
// when
const histogram = reader.nextIntervalHistogram();
// then
checkNotNull(histogram);
// if mean is good, strong probability everything else is good as well
expect(floor(histogram.mean)).toBe(293719);
});
it("should return null if all histograms are after specified time range", () => {
// given
const reader = new HistogramLogReader_1.default(fileContent);
// when
const histogram = reader.nextIntervalHistogram(0.01, 0.1);
// then
expect(histogram).toBeNull();
});
it("should return null if all histograms are before specified time range", () => {
// given
const reader = new HistogramLogReader_1.default(fileContent);
// when
const histogram = reader.nextIntervalHistogram(62, 63);
// then
expect(histogram).toBeNull();
});
it("should parse histogram even if there are trailing whitespaces", () => {
// given
const reader = new HistogramLogReader_1.default(fileContentWithTrailingWhitespace);
// when
const histogram = reader.nextIntervalHistogram();
// then
// no error
});
it("should return histograms within specified time range", () => {
// given
const reader = new HistogramLogReader_1.default(fileContent);
// when
const firstHistogram = reader.nextIntervalHistogram(0, 2);
const secondHistogram = reader.nextIntervalHistogram(0, 2);
const thirdHistogram = reader.nextIntervalHistogram(0, 2);
// then
checkNotNull(firstHistogram);
checkNotNull(secondHistogram);
expect(thirdHistogram).toBeNull();
// if mean is good, strong probability everything else is good as well
expect(floor(firstHistogram.mean)).toBe(301998);
expect(floor(secondHistogram.mean)).toBe(293719);
});
it("should set start timestamp on histogram", () => {
// given
const reader = new HistogramLogReader_1.default(fileContent);
// when
const histogram = reader.nextIntervalHistogram();
// then
checkNotNull(histogram);
expect(histogram.startTimeStampMsec).toBe(1441812279601);
});
it("should set end timestamp on histogram", () => {
// given
const reader = new HistogramLogReader_1.default(fileContent);
// when
const histogram = reader.nextIntervalHistogram();
// then
checkNotNull(histogram);
expect(histogram.endTimeStampMsec).toBe(1441812280608);
});
it("should parse tagged histogram", () => {
// given
const reader = new HistogramLogReader_1.default(tagFileContent);
reader.nextIntervalHistogram();
// when
const histogram = reader.nextIntervalHistogram();
// then
checkNotNull(histogram);
expect(histogram.tag).toBe("A");
expect(floor(histogram.mean)).toBe(301998);
});
it("should use basetime to set timestamps on histogram", () => {
// given
const reader = new HistogramLogReader_1.default(fileContentWithBaseTime);
// when
const histogram = reader.nextIntervalHistogram();
// then
checkNotNull(histogram);
expect(histogram.startTimeStampMsec).toBe(1441812123250);
expect(histogram.endTimeStampMsec).toBe(1441812124257);
});
it("should default startTime using 1st observed time", () => {
// given
const reader = new HistogramLogReader_1.default(fileContentWithoutHeader);
// when
const histogram = reader.nextIntervalHistogram();
// then
checkNotNull(histogram);
expect(histogram.startTimeStampMsec).toBe(127);
expect(histogram.endTimeStampMsec).toBe(1134);
});
it("should list all the tags of a log file", () => {
// given
// when
const tags = HistogramLogReader_1.listTags(tagFileContent);
// then
expect(tags).toEqual(["NO TAG", "A"]);
});
it("should list all the tags of a log file where all histograms are tagged", () => {
// given
const content = `#[Fake log chunk]
#[Histogram log format version 1.2]
#[StartTime: 1441812279.474 (seconds since epoch), Wed Sep 09 08:24:39 PDT 2015]
"StartTimestamp","Interval_Length","Interval_Max","Interval_Compressed_Histogram"
Tag=NOT-EMPTY,0.127,1.007,2.769,HISTFAAAAEV42pNpmSzMwMCgyAABTBDKT4GBgdnNYMcCBvsPEBEJISEuATEZMQ4uASkhIR4nrxg9v2lMaxhvMekILGZkKmcCAEf2CsI=
Tag=A,0.127,1.007,2.769,HISTFAAAAEV42pNpmSzMwMCgyAABTBDKT4GBgdnNYMcCBvsPEBEJISEuATEZMQ4uASkhIR4nrxg9v2lMaxhvMekILGZkKmcCAEf2CsI=
`;
// when
const tags = HistogramLogReader_1.listTags(content);
// then
expect(tags).toEqual(["NOT-EMPTY", "A"]);
});
describe("with WASM", () => {
let accumulatedHistogram;
beforeAll(wasm_1.initWebAssembly);
afterEach(() => {
accumulatedHistogram.destroy();
});
it("should do the whole 9 yards just like the original Java version :-)", () => {
// given
const reader = new HistogramLogReader_1.default(fileContent, 32, true);
accumulatedHistogram = wasm_1.WasmHistogram.build();
let histogram;
let histogramCount = 0;
let totalCount = 0;
// when
while ((histogram = reader.nextIntervalHistogram()) != null) {
histogramCount++;
totalCount += histogram.totalCount;
accumulatedHistogram.add(histogram);
histogram.destroy();
}
// then
expect(histogramCount).toBe(62);
expect(totalCount).toBe(48761);
expect(accumulatedHistogram.getValueAtPercentile(99.9)).toBe(1745879039);
expect(reader.startTimeSec).toBe(1441812279.474);
});
});
});
//# sourceMappingURL=HistogramLogReader.spec.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,47 @@
import Histogram from "./Histogram";
export interface Writable {
(c: string): void;
}
declare class HistogramLogWriter {
private log;
/**
* Base time to subtract from supplied histogram start/end timestamps when
* logging based on histogram timestamps.
* Base time is expected to be in msec since the epoch, as histogram start/end times
* are typically stamped with absolute times in msec since the epoch.
*/
baseTime: number;
constructor(log: Writable);
/**
* Output an interval histogram, with the given timestamp information and the [optional] tag
* associated with the histogram, using a configurable maxValueUnitRatio. (note that the
* specified timestamp information will be used, and the timestamp information in the actual
* histogram will be ignored).
* The max value reported with the interval line will be scaled by the given maxValueUnitRatio.
* @param startTimeStampSec The start timestamp to log with the interval histogram, in seconds.
* @param endTimeStampSec The end timestamp to log with the interval histogram, in seconds.
* @param histogram The interval histogram to log.
* @param maxValueUnitRatio The ratio by which to divide the histogram's max value when reporting on it.
*/
outputIntervalHistogram(histogram: Histogram, startTimeStampSec?: number, endTimeStampSec?: number, maxValueUnitRatio?: number): void;
/**
* Log a comment to the log.
* Comments will be preceded with with the '#' character.
* @param comment the comment string.
*/
outputComment(comment: string): void;
/**
* Log a start time in the log.
* @param startTimeMsec time (in milliseconds) since the absolute start time (the epoch)
*/
outputStartTime(startTimeMsec: number): void;
/**
* Output a legend line to the log.
*/
outputLegend(): void;
/**
* Output a log format version to the log.
*/
outputLogFormatVersion(): void;
}
export default HistogramLogWriter;

View file

@ -0,0 +1,72 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Histogram_1 = require("./Histogram");
const encoding_1 = require("./encoding");
const formatters_1 = require("./formatters");
const HISTOGRAM_LOG_FORMAT_VERSION = "1.3";
const timeFormatter = formatters_1.floatFormatter(5, 3);
class HistogramLogWriter {
constructor(log) {
this.log = log;
/**
* Base time to subtract from supplied histogram start/end timestamps when
* logging based on histogram timestamps.
* Base time is expected to be in msec since the epoch, as histogram start/end times
* are typically stamped with absolute times in msec since the epoch.
*/
this.baseTime = 0;
}
/**
* Output an interval histogram, with the given timestamp information and the [optional] tag
* associated with the histogram, using a configurable maxValueUnitRatio. (note that the
* specified timestamp information will be used, and the timestamp information in the actual
* histogram will be ignored).
* The max value reported with the interval line will be scaled by the given maxValueUnitRatio.
* @param startTimeStampSec The start timestamp to log with the interval histogram, in seconds.
* @param endTimeStampSec The end timestamp to log with the interval histogram, in seconds.
* @param histogram The interval histogram to log.
* @param maxValueUnitRatio The ratio by which to divide the histogram's max value when reporting on it.
*/
outputIntervalHistogram(histogram, startTimeStampSec = (histogram.startTimeStampMsec - this.baseTime) / 1000, endTimeStampSec = (histogram.endTimeStampMsec - this.baseTime) / 1000, maxValueUnitRatio = 1000) {
const base64 = encoding_1.encodeIntoCompressedBase64(histogram);
const start = timeFormatter(startTimeStampSec);
const duration = timeFormatter(endTimeStampSec - startTimeStampSec);
const max = timeFormatter(histogram.maxValue / maxValueUnitRatio);
const lineContent = `${start},${duration},${max},${base64}\n`;
if (histogram.tag && histogram.tag !== Histogram_1.NO_TAG) {
this.log(`Tag=${histogram.tag},${lineContent}`);
}
else {
this.log(lineContent);
}
}
/**
* Log a comment to the log.
* Comments will be preceded with with the '#' character.
* @param comment the comment string.
*/
outputComment(comment) {
this.log(`#${comment}\n`);
}
/**
* Log a start time in the log.
* @param startTimeMsec time (in milliseconds) since the absolute start time (the epoch)
*/
outputStartTime(startTimeMsec) {
this.outputComment(`[StartTime: ${formatters_1.floatFormatter(5, 3)(startTimeMsec / 1000)} (seconds since epoch), ${new Date(startTimeMsec)}]\n`);
}
/**
* Output a legend line to the log.
*/
outputLegend() {
this.log('"StartTimestamp","Interval_Length","Interval_Max","Interval_Compressed_Histogram"\n');
}
/**
* Output a log format version to the log.
*/
outputLogFormatVersion() {
this.outputComment("[Histogram log format version " + HISTOGRAM_LOG_FORMAT_VERSION + "]");
}
}
exports.default = HistogramLogWriter;
//# sourceMappingURL=HistogramLogWriter.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"HistogramLogWriter.js","sourceRoot":"","sources":["../src/HistogramLogWriter.ts"],"names":[],"mappings":";;AAAA,2CAAqC;AACrC,yCAAwD;AACxD,6CAA8C;AAO9C,MAAM,4BAA4B,GAAG,KAAK,CAAC;AAC3C,MAAM,aAAa,GAAG,2BAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAE3C,MAAM,kBAAkB;IAStB,YAAoB,GAAa;QAAb,QAAG,GAAH,GAAG,CAAU;QARjC;;;;;WAKG;QACH,aAAQ,GAAG,CAAC,CAAC;IAEuB,CAAC;IAErC;;;;;;;;;;OAUG;IACH,uBAAuB,CACrB,SAAoB,EACpB,iBAAiB,GAAG,CAAC,SAAS,CAAC,kBAAkB,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,EACzE,eAAe,GAAG,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,EACrE,iBAAiB,GAAG,IAAI;QAExB,MAAM,MAAM,GAAG,qCAA0B,CAAC,SAAS,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,aAAa,CAAC,iBAAiB,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,aAAa,CAAC,eAAe,GAAG,iBAAiB,CAAC,CAAC;QACpE,MAAM,GAAG,GAAG,aAAa,CAAC,SAAS,CAAC,QAAQ,GAAG,iBAAiB,CAAC,CAAC;QAClE,MAAM,WAAW,GAAG,GAAG,KAAK,IAAI,QAAQ,IAAI,GAAG,IAAI,MAAM,IAAI,CAAC;QAC9D,IAAI,SAAS,CAAC,GAAG,IAAI,SAAS,CAAC,GAAG,KAAK,kBAAM,EAAE;YAC7C,IAAI,CAAC,GAAG,CAAC,OAAO,SAAS,CAAC,GAAG,IAAI,WAAW,EAAE,CAAC,CAAC;SACjD;aAAM;YACL,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;SACvB;IACH,CAAC;IAED;;;;OAIG;IACH,aAAa,CAAC,OAAe;QAC3B,IAAI,CAAC,GAAG,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,eAAe,CAAC,aAAqB;QACnC,IAAI,CAAC,aAAa,CAChB,eAAe,2BAAc,CAC3B,CAAC,EACD,CAAC,CACF,CAAC,aAAa,GAAG,IAAI,CAAC,2BAA2B,IAAI,IAAI,CACxD,aAAa,CACd,KAAK,CACP,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,YAAY;QACV,IAAI,CAAC,GAAG,CACN,qFAAqF,CACtF,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,sBAAsB;QACpB,IAAI,CAAC,aAAa,CAChB,gCAAgC,GAAG,4BAA4B,GAAG,GAAG,CACtE,CAAC;IACJ,CAAC;CACF;AAED,kBAAe,kBAAkB,CAAC"}

View file

@ -0,0 +1 @@
export {};

View file

@ -0,0 +1,60 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const HistogramLogWriter_1 = require("./HistogramLogWriter");
const Int32Histogram_1 = require("./Int32Histogram");
describe("Histogram Log Writer", () => {
let buffer;
let writer;
let histogram;
beforeEach(() => {
buffer = "";
writer = new HistogramLogWriter_1.default((content) => {
buffer += content;
});
histogram = new Int32Histogram_1.default(1, Number.MAX_SAFE_INTEGER, 3);
});
it("should write a line with start time, duration, max value, and a base64 encoded histogram", () => {
// given
histogram.recordValue(123000);
// when
writer.outputIntervalHistogram(histogram, 1000, 1042);
// then
expect(buffer).toMatch(/^1000.000,42.000,123.000,HISTFAA/);
});
it("should write start time, duration and max value using 3 digits", () => {
// given
histogram.recordValue(123001);
// when
writer.outputIntervalHistogram(histogram, 1000.0120001, 1042.013001);
// then
expect(buffer).toMatch(/^1000.012,42.001,123.001,HISTFAA/);
});
it("should write a line starting with histogram tag", () => {
// given
histogram.tag = "TAG";
histogram.recordValue(123000);
// when
writer.outputIntervalHistogram(histogram, 1000, 1042);
// then
expect(buffer).toContain("Tag=TAG,1000.000,42.000,123.000,HISTFAA");
});
it("should write a histogram's start time in sec using basetime", () => {
// given
histogram.startTimeStampMsec = 1234001;
histogram.endTimeStampMsec = 1235001;
writer.baseTime = 1000000;
histogram.recordValue(1);
// when
writer.outputIntervalHistogram(histogram);
// then
expect(buffer).toContain("234.001");
});
it("should write start time in seconds", () => {
// given
// when
writer.outputStartTime(1234560);
// then
expect(buffer).toContain("1234.560");
});
});
//# sourceMappingURL=HistogramLogWriter.spec.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"HistogramLogWriter.spec.js","sourceRoot":"","sources":["../src/HistogramLogWriter.spec.ts"],"names":[],"mappings":";;AAAA,6DAAsD;AACtD,qDAA8C;AAE9C,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,IAAI,MAAc,CAAC;IACnB,IAAI,MAA0B,CAAC;IAC/B,IAAI,SAAyB,CAAC;IAC9B,UAAU,CAAC,GAAG,EAAE;QACd,MAAM,GAAG,EAAE,CAAC;QACZ,MAAM,GAAG,IAAI,4BAAkB,CAAC,CAAC,OAAO,EAAE,EAAE;YAC1C,MAAM,IAAI,OAAO,CAAC;QACpB,CAAC,CAAC,CAAC;QACH,SAAS,GAAG,IAAI,wBAAc,CAAC,CAAC,EAAE,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0FAA0F,EAAE,GAAG,EAAE;QAClG,QAAQ;QACR,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC9B,OAAO;QACP,MAAM,CAAC,uBAAuB,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACtD,OAAO;QACP,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,QAAQ;QACR,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC9B,OAAO;QACP,MAAM,CAAC,uBAAuB,CAAC,SAAS,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;QACrE,OAAO;QACP,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,QAAQ;QACR,SAAS,CAAC,GAAG,GAAG,KAAK,CAAC;QACtB,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC9B,OAAO;QACP,MAAM,CAAC,uBAAuB,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACtD,OAAO;QACP,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,yCAAyC,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,QAAQ;QACR,SAAS,CAAC,kBAAkB,GAAG,OAAO,CAAC;QACvC,SAAS,CAAC,gBAAgB,GAAG,OAAO,CAAC;QACrC,MAAM,CAAC,QAAQ,GAAG,OAAO,CAAC;QAC1B,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QACzB,OAAO;QACP,MAAM,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC;QAC1C,OAAO;QACP,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,QAAQ;QACR,OAAO;QACP,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAChC,OAAO;QACP,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}

View file

@ -0,0 +1,5 @@
import TypedArrayHistogram from "./TypedArrayHistogram";
declare class Int16Histogram extends TypedArrayHistogram {
constructor(lowestDiscernibleValue: number, highestTrackableValue: number, numberOfSignificantValueDigits: number);
}
export default Int16Histogram;

17
my-app/node_modules/hdr-histogram-js/dist/Int16Histogram.js generated vendored Executable file
View file

@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*
* 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/
*/
const TypedArrayHistogram_1 = require("./TypedArrayHistogram");
class Int16Histogram extends TypedArrayHistogram_1.default {
constructor(lowestDiscernibleValue, highestTrackableValue, numberOfSignificantValueDigits) {
super(Uint16Array, lowestDiscernibleValue, highestTrackableValue, numberOfSignificantValueDigits);
}
}
exports.default = Int16Histogram;
//# sourceMappingURL=Int16Histogram.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"Int16Histogram.js","sourceRoot":"","sources":["../src/Int16Histogram.ts"],"names":[],"mappings":";;AAAA;;;;;;GAMG;AACH,+DAAwD;AAExD,MAAM,cAAe,SAAQ,6BAAmB;IAC9C,YACE,sBAA8B,EAC9B,qBAA6B,EAC7B,8BAAsC;QAEtC,KAAK,CACH,WAAW,EACX,sBAAsB,EACtB,qBAAqB,EACrB,8BAA8B,CAC/B,CAAC;IACJ,CAAC;CACF;AAED,kBAAe,cAAc,CAAC"}

View file

@ -0,0 +1,5 @@
import TypedArrayHistogram from "./TypedArrayHistogram";
declare class Int32Histogram extends TypedArrayHistogram {
constructor(lowestDiscernibleValue: number, highestTrackableValue: number, numberOfSignificantValueDigits: number);
}
export default Int32Histogram;

17
my-app/node_modules/hdr-histogram-js/dist/Int32Histogram.js generated vendored Executable file
View file

@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*
* 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/
*/
const TypedArrayHistogram_1 = require("./TypedArrayHistogram");
class Int32Histogram extends TypedArrayHistogram_1.default {
constructor(lowestDiscernibleValue, highestTrackableValue, numberOfSignificantValueDigits) {
super(Uint32Array, lowestDiscernibleValue, highestTrackableValue, numberOfSignificantValueDigits);
}
}
exports.default = Int32Histogram;
//# sourceMappingURL=Int32Histogram.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"Int32Histogram.js","sourceRoot":"","sources":["../src/Int32Histogram.ts"],"names":[],"mappings":";;AAAA;;;;;;GAMG;AACH,+DAAwD;AAExD,MAAM,cAAe,SAAQ,6BAAmB;IAC9C,YACE,sBAA8B,EAC9B,qBAA6B,EAC7B,8BAAsC;QAEtC,KAAK,CACH,WAAW,EACX,sBAAsB,EACtB,qBAAqB,EACrB,8BAA8B,CAC/B,CAAC;IACJ,CAAC;CACF;AAED,kBAAe,cAAc,CAAC"}

View file

@ -0,0 +1,5 @@
import TypedArrayHistogram from "./TypedArrayHistogram";
declare class Int8Histogram extends TypedArrayHistogram {
constructor(lowestDiscernibleValue: number, highestTrackableValue: number, numberOfSignificantValueDigits: number);
}
export default Int8Histogram;

17
my-app/node_modules/hdr-histogram-js/dist/Int8Histogram.js generated vendored Executable file
View file

@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*
* 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/
*/
const TypedArrayHistogram_1 = require("./TypedArrayHistogram");
class Int8Histogram extends TypedArrayHistogram_1.default {
constructor(lowestDiscernibleValue, highestTrackableValue, numberOfSignificantValueDigits) {
super(Uint8Array, lowestDiscernibleValue, highestTrackableValue, numberOfSignificantValueDigits);
}
}
exports.default = Int8Histogram;
//# sourceMappingURL=Int8Histogram.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"Int8Histogram.js","sourceRoot":"","sources":["../src/Int8Histogram.ts"],"names":[],"mappings":";;AAAA;;;;;;GAMG;AACH,+DAAwD;AAExD,MAAM,aAAc,SAAQ,6BAAmB;IAC7C,YACE,sBAA8B,EAC9B,qBAA6B,EAC7B,8BAAsC;QAEtC,KAAK,CACH,UAAU,EACV,sBAAsB,EACtB,qBAAqB,EACrB,8BAA8B,CAC/B,CAAC;IACJ,CAAC;CACF;AAED,kBAAe,aAAa,CAAC"}

320
my-app/node_modules/hdr-histogram-js/dist/JsHistogram.d.ts generated vendored Executable file
View file

@ -0,0 +1,320 @@
import RecordedValuesIterator from "./RecordedValuesIterator";
import PercentileIterator from "./PercentileIterator";
import Histogram, { HistogramSummary } from "./Histogram";
export declare abstract class JsHistogram implements Histogram {
static identityBuilder: number;
identity: number;
autoResize: boolean;
highestTrackableValue: number;
lowestDiscernibleValue: number;
numberOfSignificantValueDigits: number;
bucketCount: number;
/**
* Power-of-two length of linearly scaled array slots in the counts array. Long enough to hold the first sequence of
* entries that must be distinguished by a single unit (determined by configured precision).
*/
subBucketCount: number;
countsArrayLength: number;
wordSizeInBytes: number;
startTimeStampMsec: number;
endTimeStampMsec: number;
tag: string;
percentileIterator: PercentileIterator;
recordedValuesIterator: RecordedValuesIterator;
/**
* Number of leading zeros in the largest value that can fit in bucket 0.
*/
leadingZeroCountBase: number;
subBucketHalfCountMagnitude: number;
/**
* Largest k such that 2^k &lt;= lowestDiscernibleValue
*/
unitMagnitude: number;
subBucketHalfCount: number;
lowestDiscernibleValueRounded: number;
/**
* Biggest value that can fit in bucket 0
*/
subBucketMask: number;
/**
* Lowest unitMagnitude bits are set
*/
unitMagnitudeMask: number;
maxValue: number;
minNonZeroValue: number;
_totalCount: number;
incrementTotalCount(): void;
addToTotalCount(value: number): void;
setTotalCount(value: number): void;
/**
* Get the total count of all recorded values in the histogram
* @return the total count of all recorded values in the histogram
*/
get totalCount(): number;
abstract getCountAtIndex(index: number): number;
abstract incrementCountAtIndex(index: number): void;
abstract addToCountAtIndex(index: number, value: number): void;
abstract setCountAtIndex(index: number, value: number): void;
abstract clearCounts(): void;
protected abstract _getEstimatedFootprintInBytes(): number;
abstract resize(newHighestTrackableValue: number): void;
private updatedMaxValue;
private updateMinNonZeroValue;
constructor(lowestDiscernibleValue: number, highestTrackableValue: number, numberOfSignificantValueDigits: number);
init(lowestDiscernibleValue: number, highestTrackableValue: number, numberOfSignificantValueDigits: number): void;
/**
* The buckets (each of which has subBucketCount sub-buckets, here assumed to be 2048 as an example) overlap:
*
* <pre>
* The 0'th bucket covers from 0...2047 in multiples of 1, using all 2048 sub-buckets
* The 1'th bucket covers from 2048..4097 in multiples of 2, using only the top 1024 sub-buckets
* The 2'th bucket covers from 4096..8191 in multiple of 4, using only the top 1024 sub-buckets
* ...
* </pre>
*
* Bucket 0 is "special" here. It is the only one that has 2048 entries. All the rest have 1024 entries (because
* their bottom half overlaps with and is already covered by the all of the previous buckets put together). In other
* words, the k'th bucket could represent 0 * 2^k to 2048 * 2^k in 2048 buckets with 2^k precision, but the midpoint
* of 1024 * 2^k = 2048 * 2^(k-1) = the k-1'th bucket's end, so we would use the previous bucket for those lower
* values as it has better precision.
*/
establishSize(newHighestTrackableValue: number): void;
determineArrayLengthNeeded(highestTrackableValue: number): number;
/**
* If we have N such that subBucketCount * 2^N > max value, we need storage for N+1 buckets, each with enough
* slots to hold the top half of the subBucketCount (the lower half is covered by previous buckets), and the +1
* being used for the lower half of the 0'th bucket. Or, equivalently, we need 1 more bucket to capture the max
* value if we consider the sub-bucket length to be halved.
*/
getLengthForNumberOfBuckets(numberOfBuckets: number): number;
getBucketsNeededToCoverValue(value: number): number;
/**
* Record a value in the histogram
*
* @param value The value to be recorded
* @throws may throw Error if value is exceeds highestTrackableValue
*/
recordValue(value: number): void;
recordSingleValue(value: number): void;
handleRecordException(count: number, value: number): void;
countsArrayIndex(value: number): number;
private computeCountsArrayIndex;
/**
* @return the lowest (and therefore highest precision) bucket index that can represent the value
*/
getBucketIndex(value: number): number;
getSubBucketIndex(value: number, bucketIndex: number): number;
updateMinAndMax(value: number): void;
/**
* Get the value at a given percentile.
* When the given percentile is &gt; 0.0, the value returned is the value that the given
* percentage of the overall recorded value entries in the histogram are either smaller than
* or equivalent to. When the given percentile is 0.0, the value returned is the value that all value
* entries in the histogram are either larger than or equivalent to.
* <p>
* Note that two values are "equivalent" in this statement if
* {@link org.HdrHistogram.JsHistogram#valuesAreEquivalent} would return true.
*
* @param percentile The percentile for which to return the associated value
* @return The value that the given percentage of the overall recorded value entries in the
* histogram are either smaller than or equivalent to. When the percentile is 0.0, returns the
* value that all value entries in the histogram are either larger than or equivalent to.
*/
getValueAtPercentile(percentile: number): number;
valueFromIndexes(bucketIndex: number, subBucketIndex: number): number;
valueFromIndex(index: number): number;
/**
* Get the lowest value that is equivalent to the given value within the histogram's resolution.
* Where "equivalent" means that value samples recorded for any two
* equivalent values are counted in a common total count.
*
* @param value The given value
* @return The lowest value that is equivalent to the given value within the histogram's resolution.
*/
lowestEquivalentValue(value: number): number;
/**
* Get the highest value that is equivalent to the given value within the histogram's resolution.
* Where "equivalent" means that value samples recorded for any two
* equivalent values are counted in a common total count.
*
* @param value The given value
* @return The highest value that is equivalent to the given value within the histogram's resolution.
*/
highestEquivalentValue(value: number): number;
/**
* Get the next value that is not equivalent to the given value within the histogram's resolution.
* Where "equivalent" means that value samples recorded for any two
* equivalent values are counted in a common total count.
*
* @param value The given value
* @return The next value that is not equivalent to the given value within the histogram's resolution.
*/
nextNonEquivalentValue(value: number): number;
/**
* Get the size (in value units) of the range of values that are equivalent to the given value within the
* histogram's resolution. Where "equivalent" means that value samples recorded for any two
* equivalent values are counted in a common total count.
*
* @param value The given value
* @return The size of the range of values equivalent to the given value.
*/
sizeOfEquivalentValueRange(value: number): number;
/**
* Get a value that lies in the middle (rounded up) of the range of values equivalent the given value.
* Where "equivalent" means that value samples recorded for any two
* equivalent values are counted in a common total count.
*
* @param value The given value
* @return The value lies in the middle (rounded up) of the range of values equivalent the given value.
*/
medianEquivalentValue(value: number): number;
/**
* Get the computed mean value of all recorded values in the histogram
*
* @return the mean value (in value units) of the histogram data
*/
get mean(): number;
private getStdDeviation;
/**
* Get the computed standard deviation of all recorded values in the histogram
*
* @return the standard deviation (in value units) of the histogram data
*/
get stdDeviation(): number;
/**
* Produce textual representation of the value distribution of histogram data by percentile. The distribution is
* output with exponentially increasing resolution, with each exponentially decreasing half-distance containing
* <i>dumpTicksPerHalf</i> percentile reporting tick points.
*
* @param printStream Stream into which the distribution will be output
* <p>
* @param percentileTicksPerHalfDistance The number of reporting points per exponentially decreasing half-distance
* <p>
* @param outputValueUnitScalingRatio The scaling factor by which to divide histogram recorded values units in
* output
* @param useCsvFormat Output in CSV format if true. Otherwise use plain text form.
*/
outputPercentileDistribution(percentileTicksPerHalfDistance?: number, outputValueUnitScalingRatio?: number, useCsvFormat?: boolean): string;
get summary(): HistogramSummary;
toJSON(): HistogramSummary;
inspect(): string;
/**
* Provide a (conservatively high) estimate of the Histogram's total footprint in bytes
*
* @return a (conservatively high) estimate of the Histogram's total footprint in bytes
*/
get estimatedFootprintInBytes(): number;
recordSingleValueWithExpectedInterval(value: number, expectedIntervalBetweenValueSamples: number): void;
private recordCountAtValue;
/**
* Record a value in the histogram (adding to the value's current count)
*
* @param value The value to be recorded
* @param count The number of occurrences of this value to record
* @throws ArrayIndexOutOfBoundsException (may throw) if value is exceeds highestTrackableValue
*/
recordValueWithCount(value: number, count: number): void;
/**
* Record a value in the histogram.
* <p>
* To compensate for the loss of sampled values when a recorded value is larger than the expected
* interval between value samples, Histogram will auto-generate an additional series of decreasingly-smaller
* (down to the expectedIntervalBetweenValueSamples) value records.
* <p>
* Note: This is a at-recording correction method, as opposed to the post-recording correction method provided
* by {@link #copyCorrectedForCoordinatedOmission(long)}.
* The two methods are mutually exclusive, and only one of the two should be be used on a given data set to correct
* for the same coordinated omission issue.
* <p>
* See notes in the description of the Histogram calls for an illustration of why this corrective behavior is
* important.
*
* @param value The value to record
* @param expectedIntervalBetweenValueSamples If expectedIntervalBetweenValueSamples is larger than 0, add
* auto-generated value records as appropriate if value is larger
* than expectedIntervalBetweenValueSamples
* @throws ArrayIndexOutOfBoundsException (may throw) if value is exceeds highestTrackableValue
*/
recordValueWithExpectedInterval(value: number, expectedIntervalBetweenValueSamples: number): void;
private recordValueWithCountAndExpectedInterval;
/**
* Add the contents of another histogram to this one, while correcting the incoming data for coordinated omission.
* <p>
* To compensate for the loss of sampled values when a recorded value is larger than the expected
* interval between value samples, the values added will include an auto-generated additional series of
* decreasingly-smaller (down to the expectedIntervalBetweenValueSamples) value records for each count found
* in the current histogram that is larger than the expectedIntervalBetweenValueSamples.
*
* Note: This is a post-recording correction method, as opposed to the at-recording correction method provided
* by {@link #recordValueWithExpectedInterval(long, long) recordValueWithExpectedInterval}. The two
* methods are mutually exclusive, and only one of the two should be be used on a given data set to correct
* for the same coordinated omission issue.
* by
* <p>
* See notes in the description of the Histogram calls for an illustration of why this corrective behavior is
* important.
*
* @param otherHistogram The other histogram. highestTrackableValue and largestValueWithSingleUnitResolution must match.
* @param expectedIntervalBetweenValueSamples If expectedIntervalBetweenValueSamples is larger than 0, add
* auto-generated value records as appropriate if value is larger
* than expectedIntervalBetweenValueSamples
* @throws ArrayIndexOutOfBoundsException (may throw) if values exceed highestTrackableValue
*/
addWhileCorrectingForCoordinatedOmission(otherHistogram: JsHistogram, expectedIntervalBetweenValueSamples: number): void;
/**
* Get a copy of this histogram, corrected for coordinated omission.
* <p>
* To compensate for the loss of sampled values when a recorded value is larger than the expected
* interval between value samples, the new histogram will include an auto-generated additional series of
* decreasingly-smaller (down to the expectedIntervalBetweenValueSamples) value records for each count found
* in the current histogram that is larger than the expectedIntervalBetweenValueSamples.
*
* Note: This is a post-correction method, as opposed to the at-recording correction method provided
* by {@link #recordValueWithExpectedInterval(long, long) recordValueWithExpectedInterval}. The two
* methods are mutually exclusive, and only one of the two should be be used on a given data set to correct
* for the same coordinated omission issue.
* by
* <p>
* See notes in the description of the Histogram calls for an illustration of why this corrective behavior is
* important.
*
* @param expectedIntervalBetweenValueSamples If expectedIntervalBetweenValueSamples is larger than 0, add
* auto-generated value records as appropriate if value is larger
* than expectedIntervalBetweenValueSamples
* @return a copy of this histogram, corrected for coordinated omission.
*/
abstract copyCorrectedForCoordinatedOmission(expectedIntervalBetweenValueSamples: number): JsHistogram;
/**
* Add the contents of another histogram to this one.
* <p>
* As part of adding the contents, the start/end timestamp range of this histogram will be
* extended to include the start/end timestamp range of the other histogram.
*
* @param otherHistogram The other histogram.
* @throws (may throw) if values in fromHistogram's are
* higher than highestTrackableValue.
*/
add(otherHistogram: JsHistogram): void;
/**
* Get the count of recorded values at a specific value (to within the histogram resolution at the value level).
*
* @param value The value for which to provide the recorded count
* @return The total count of values recorded in the histogram within the value range that is
* {@literal >=} lowestEquivalentValue(<i>value</i>) and {@literal <=} highestEquivalentValue(<i>value</i>)
*/
private getCountAtValue;
/**
* Subtract the contents of another histogram from this one.
* <p>
* The start/end timestamps of this histogram will remain unchanged.
*
* @param otherHistogram The other histogram.
* @throws ArrayIndexOutOfBoundsException (may throw) if values in otherHistogram's are higher than highestTrackableValue.
*
*/
subtract(otherHistogram: JsHistogram): void;
establishInternalTackingValues(lengthToCover?: number): void;
reset(): void;
destroy(): void;
}
export { JsHistogram as default };

View file

@ -0,0 +1,18 @@
import { JsHistogram } from "./JsHistogram";
import { BitBucketSize } from "./Histogram";
export declare const deflate: any;
export declare const inflate: any;
export declare function decompress(data: Uint8Array): Uint8Array;
export declare function doDecode(data: Uint8Array, bitBucketSize?: BitBucketSize, minBarForHighestTrackableValue?: number): JsHistogram;
declare function doEncodeIntoCompressedBase64(compressionLevel?: number): string;
declare module "./JsHistogram" {
namespace JsHistogram {
let decode: typeof doDecode;
}
}
declare module "./JsHistogram" {
interface JsHistogram {
encodeIntoCompressedBase64: typeof doEncodeIntoCompressedBase64;
}
}
export {};

View file

@ -0,0 +1,194 @@
"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

File diff suppressed because one or more lines are too long

799
my-app/node_modules/hdr-histogram-js/dist/JsHistogram.js generated vendored Executable file
View file

@ -0,0 +1,799 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = exports.JsHistogram = 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/
*/
const RecordedValuesIterator_1 = require("./RecordedValuesIterator");
const PercentileIterator_1 = require("./PercentileIterator");
const formatters_1 = require("./formatters");
const ulp_1 = require("./ulp");
const Histogram_1 = require("./Histogram");
const { pow, floor, ceil, log2, max, min } = Math;
class JsHistogram {
constructor(lowestDiscernibleValue, highestTrackableValue, numberOfSignificantValueDigits) {
this.autoResize = false;
this.startTimeStampMsec = Number.MAX_SAFE_INTEGER;
this.endTimeStampMsec = 0;
this.tag = Histogram_1.NO_TAG;
this.maxValue = 0;
this.minNonZeroValue = Number.MAX_SAFE_INTEGER;
this.identity = 0;
this.highestTrackableValue = 0;
this.lowestDiscernibleValue = 0;
this.numberOfSignificantValueDigits = 0;
this.bucketCount = 0;
this.subBucketCount = 0;
this.countsArrayLength = 0;
this.wordSizeInBytes = 0;
// Verify argument validity
if (lowestDiscernibleValue < 1) {
throw new Error("lowestDiscernibleValue must be >= 1");
}
if (highestTrackableValue < 2 * lowestDiscernibleValue) {
throw new Error(`highestTrackableValue must be >= 2 * lowestDiscernibleValue ( 2 * ${lowestDiscernibleValue} )`);
}
if (numberOfSignificantValueDigits < 0 ||
numberOfSignificantValueDigits > 5) {
throw new Error("numberOfSignificantValueDigits must be between 0 and 5");
}
this.identity = JsHistogram.identityBuilder++;
this.init(lowestDiscernibleValue, highestTrackableValue, numberOfSignificantValueDigits);
}
incrementTotalCount() {
this._totalCount++;
}
addToTotalCount(value) {
this._totalCount += value;
}
setTotalCount(value) {
this._totalCount = value;
}
/**
* Get the total count of all recorded values in the histogram
* @return the total count of all recorded values in the histogram
*/
get totalCount() {
return this._totalCount;
}
updatedMaxValue(value) {
const internalValue = value + this.unitMagnitudeMask;
this.maxValue = internalValue;
}
updateMinNonZeroValue(value) {
if (value <= this.unitMagnitudeMask) {
return;
}
const internalValue = floor(value / this.lowestDiscernibleValueRounded) *
this.lowestDiscernibleValueRounded;
this.minNonZeroValue = internalValue;
}
init(lowestDiscernibleValue, highestTrackableValue, numberOfSignificantValueDigits) {
this.lowestDiscernibleValue = lowestDiscernibleValue;
this.highestTrackableValue = highestTrackableValue;
this.numberOfSignificantValueDigits = numberOfSignificantValueDigits;
/*
* Given a 3 decimal point accuracy, the expectation is obviously for "+/- 1 unit at 1000". It also means that
* it's "ok to be +/- 2 units at 2000". The "tricky" thing is that it is NOT ok to be +/- 2 units at 1999. Only
* starting at 2000. So internally, we need to maintain single unit resolution to 2x 10^decimalPoints.
*/
const largestValueWithSingleUnitResolution = 2 * floor(pow(10, numberOfSignificantValueDigits));
this.unitMagnitude = floor(log2(lowestDiscernibleValue));
this.lowestDiscernibleValueRounded = pow(2, this.unitMagnitude);
this.unitMagnitudeMask = this.lowestDiscernibleValueRounded - 1;
// We need to maintain power-of-two subBucketCount (for clean direct indexing) that is large enough to
// provide unit resolution to at least largestValueWithSingleUnitResolution. So figure out
// largestValueWithSingleUnitResolution's nearest power-of-two (rounded up), and use that:
const subBucketCountMagnitude = ceil(log2(largestValueWithSingleUnitResolution));
this.subBucketHalfCountMagnitude =
(subBucketCountMagnitude > 1 ? subBucketCountMagnitude : 1) - 1;
this.subBucketCount = pow(2, this.subBucketHalfCountMagnitude + 1);
this.subBucketHalfCount = this.subBucketCount / 2;
this.subBucketMask =
(floor(this.subBucketCount) - 1) * pow(2, this.unitMagnitude);
this.establishSize(highestTrackableValue);
this.leadingZeroCountBase =
53 - this.unitMagnitude - this.subBucketHalfCountMagnitude - 1;
this.percentileIterator = new PercentileIterator_1.default(this, 1);
this.recordedValuesIterator = new RecordedValuesIterator_1.default(this);
}
/**
* The buckets (each of which has subBucketCount sub-buckets, here assumed to be 2048 as an example) overlap:
*
* <pre>
* The 0'th bucket covers from 0...2047 in multiples of 1, using all 2048 sub-buckets
* The 1'th bucket covers from 2048..4097 in multiples of 2, using only the top 1024 sub-buckets
* The 2'th bucket covers from 4096..8191 in multiple of 4, using only the top 1024 sub-buckets
* ...
* </pre>
*
* Bucket 0 is "special" here. It is the only one that has 2048 entries. All the rest have 1024 entries (because
* their bottom half overlaps with and is already covered by the all of the previous buckets put together). In other
* words, the k'th bucket could represent 0 * 2^k to 2048 * 2^k in 2048 buckets with 2^k precision, but the midpoint
* of 1024 * 2^k = 2048 * 2^(k-1) = the k-1'th bucket's end, so we would use the previous bucket for those lower
* values as it has better precision.
*/
establishSize(newHighestTrackableValue) {
// establish counts array length:
this.countsArrayLength = this.determineArrayLengthNeeded(newHighestTrackableValue);
// establish exponent range needed to support the trackable value with no overflow:
this.bucketCount = this.getBucketsNeededToCoverValue(newHighestTrackableValue);
// establish the new highest trackable value:
this.highestTrackableValue = newHighestTrackableValue;
}
determineArrayLengthNeeded(highestTrackableValue) {
if (highestTrackableValue < 2 * this.lowestDiscernibleValue) {
throw new Error("highestTrackableValue (" +
highestTrackableValue +
") cannot be < (2 * lowestDiscernibleValue)");
}
//determine counts array length needed:
const countsArrayLength = this.getLengthForNumberOfBuckets(this.getBucketsNeededToCoverValue(highestTrackableValue));
return countsArrayLength;
}
/**
* If we have N such that subBucketCount * 2^N > max value, we need storage for N+1 buckets, each with enough
* slots to hold the top half of the subBucketCount (the lower half is covered by previous buckets), and the +1
* being used for the lower half of the 0'th bucket. Or, equivalently, we need 1 more bucket to capture the max
* value if we consider the sub-bucket length to be halved.
*/
getLengthForNumberOfBuckets(numberOfBuckets) {
const lengthNeeded = (numberOfBuckets + 1) * (this.subBucketCount / 2);
return lengthNeeded;
}
getBucketsNeededToCoverValue(value) {
// the k'th bucket can express from 0 * 2^k to subBucketCount * 2^k in units of 2^k
let smallestUntrackableValue = this.subBucketCount * pow(2, this.unitMagnitude);
// always have at least 1 bucket
let bucketsNeeded = 1;
while (smallestUntrackableValue <= value) {
if (smallestUntrackableValue > Number.MAX_SAFE_INTEGER / 2) {
// TODO check array max size in JavaScript
// next shift will overflow, meaning that bucket could represent values up to ones greater than
// Number.MAX_SAFE_INTEGER, so it's the last bucket
return bucketsNeeded + 1;
}
smallestUntrackableValue = smallestUntrackableValue * 2;
bucketsNeeded++;
}
return bucketsNeeded;
}
/**
* Record a value in the histogram
*
* @param value The value to be recorded
* @throws may throw Error if value is exceeds highestTrackableValue
*/
recordValue(value) {
this.recordSingleValue(value);
}
recordSingleValue(value) {
const countsIndex = this.countsArrayIndex(value);
if (countsIndex >= this.countsArrayLength) {
this.handleRecordException(1, value);
}
else {
this.incrementCountAtIndex(countsIndex);
}
this.updateMinAndMax(value);
this.incrementTotalCount();
}
handleRecordException(count, value) {
if (!this.autoResize) {
throw new Error("Value " + value + " is outside of histogram covered range");
}
this.resize(value);
var countsIndex = this.countsArrayIndex(value);
this.addToCountAtIndex(countsIndex, count);
this.highestTrackableValue = this.highestEquivalentValue(this.valueFromIndex(this.countsArrayLength - 1));
}
countsArrayIndex(value) {
if (value < 0) {
throw new Error("Histogram recorded value cannot be negative.");
}
const bucketIndex = this.getBucketIndex(value);
const subBucketIndex = this.getSubBucketIndex(value, bucketIndex);
return this.computeCountsArrayIndex(bucketIndex, subBucketIndex);
}
computeCountsArrayIndex(bucketIndex, subBucketIndex) {
// TODO
//assert(subBucketIndex < subBucketCount);
//assert(bucketIndex == 0 || (subBucketIndex >= subBucketHalfCount));
// Calculate the index for the first entry that will be used in the bucket (halfway through subBucketCount).
// For bucketIndex 0, all subBucketCount entries may be used, but bucketBaseIndex is still set in the middle.
const bucketBaseIndex = (bucketIndex + 1) * pow(2, this.subBucketHalfCountMagnitude);
// Calculate the offset in the bucket. This subtraction will result in a positive value in all buckets except
// the 0th bucket (since a value in that bucket may be less than half the bucket's 0 to subBucketCount range).
// However, this works out since we give bucket 0 twice as much space.
const offsetInBucket = subBucketIndex - this.subBucketHalfCount;
// The following is the equivalent of ((subBucketIndex - subBucketHalfCount) + bucketBaseIndex;
return bucketBaseIndex + offsetInBucket;
}
/**
* @return the lowest (and therefore highest precision) bucket index that can represent the value
*/
getBucketIndex(value) {
// Calculates the number of powers of two by which the value is greater than the biggest value that fits in
// bucket 0. This is the bucket index since each successive bucket can hold a value 2x greater.
// The mask maps small values to bucket 0.
// return this.leadingZeroCountBase - Long.numberOfLeadingZeros(value | subBucketMask);
return max(floor(log2(value)) -
this.subBucketHalfCountMagnitude -
this.unitMagnitude, 0);
}
getSubBucketIndex(value, bucketIndex) {
// For bucketIndex 0, this is just value, so it may be anywhere in 0 to subBucketCount.
// For other bucketIndex, this will always end up in the top half of subBucketCount: assume that for some bucket
// k > 0, this calculation will yield a value in the bottom half of 0 to subBucketCount. Then, because of how
// buckets overlap, it would have also been in the top half of bucket k-1, and therefore would have
// returned k-1 in getBucketIndex(). Since we would then shift it one fewer bits here, it would be twice as big,
// and therefore in the top half of subBucketCount.
return floor(value / pow(2, bucketIndex + this.unitMagnitude));
}
updateMinAndMax(value) {
if (value > this.maxValue) {
this.updatedMaxValue(value);
}
if (value < this.minNonZeroValue && value !== 0) {
this.updateMinNonZeroValue(value);
}
}
/**
* Get the value at a given percentile.
* When the given percentile is &gt; 0.0, the value returned is the value that the given
* percentage of the overall recorded value entries in the histogram are either smaller than
* or equivalent to. When the given percentile is 0.0, the value returned is the value that all value
* entries in the histogram are either larger than or equivalent to.
* <p>
* Note that two values are "equivalent" in this statement if
* {@link org.HdrHistogram.JsHistogram#valuesAreEquivalent} would return true.
*
* @param percentile The percentile for which to return the associated value
* @return The value that the given percentage of the overall recorded value entries in the
* histogram are either smaller than or equivalent to. When the percentile is 0.0, returns the
* value that all value entries in the histogram are either larger than or equivalent to.
*/
getValueAtPercentile(percentile) {
const requestedPercentile = min(percentile, 100); // Truncate down to 100%
// round count up to nearest integer, to ensure that the largest value that the requested percentile
// of overall recorded values is actually included. However, this must be done with care:
//
// First, Compute fp value for count at the requested percentile. Note that fp result end up
// being 1 ulp larger than the correct integer count for this percentile:
const fpCountAtPercentile = (requestedPercentile / 100.0) * this.totalCount;
// Next, round up, but make sure to prevent <= 1 ulp inaccurancies in the above fp math from
// making us skip a count:
const countAtPercentile = max(ceil(fpCountAtPercentile - ulp_1.default(fpCountAtPercentile)), // round up
1 // Make sure we at least reach the first recorded entry
);
let totalToCurrentIndex = 0;
for (let i = 0; i < this.countsArrayLength; i++) {
totalToCurrentIndex += this.getCountAtIndex(i);
if (totalToCurrentIndex >= countAtPercentile) {
var valueAtIndex = this.valueFromIndex(i);
return percentile === 0.0
? this.lowestEquivalentValue(valueAtIndex)
: this.highestEquivalentValue(valueAtIndex);
}
}
return 0;
}
valueFromIndexes(bucketIndex, subBucketIndex) {
return subBucketIndex * pow(2, bucketIndex + this.unitMagnitude);
}
valueFromIndex(index) {
let bucketIndex = floor(index / this.subBucketHalfCount) - 1;
let subBucketIndex = (index % this.subBucketHalfCount) + this.subBucketHalfCount;
if (bucketIndex < 0) {
subBucketIndex -= this.subBucketHalfCount;
bucketIndex = 0;
}
return this.valueFromIndexes(bucketIndex, subBucketIndex);
}
/**
* Get the lowest value that is equivalent to the given value within the histogram's resolution.
* Where "equivalent" means that value samples recorded for any two
* equivalent values are counted in a common total count.
*
* @param value The given value
* @return The lowest value that is equivalent to the given value within the histogram's resolution.
*/
lowestEquivalentValue(value) {
const bucketIndex = this.getBucketIndex(value);
const subBucketIndex = this.getSubBucketIndex(value, bucketIndex);
const thisValueBaseLevel = this.valueFromIndexes(bucketIndex, subBucketIndex);
return thisValueBaseLevel;
}
/**
* Get the highest value that is equivalent to the given value within the histogram's resolution.
* Where "equivalent" means that value samples recorded for any two
* equivalent values are counted in a common total count.
*
* @param value The given value
* @return The highest value that is equivalent to the given value within the histogram's resolution.
*/
highestEquivalentValue(value) {
return this.nextNonEquivalentValue(value) - 1;
}
/**
* Get the next value that is not equivalent to the given value within the histogram's resolution.
* Where "equivalent" means that value samples recorded for any two
* equivalent values are counted in a common total count.
*
* @param value The given value
* @return The next value that is not equivalent to the given value within the histogram's resolution.
*/
nextNonEquivalentValue(value) {
return (this.lowestEquivalentValue(value) + this.sizeOfEquivalentValueRange(value));
}
/**
* Get the size (in value units) of the range of values that are equivalent to the given value within the
* histogram's resolution. Where "equivalent" means that value samples recorded for any two
* equivalent values are counted in a common total count.
*
* @param value The given value
* @return The size of the range of values equivalent to the given value.
*/
sizeOfEquivalentValueRange(value) {
const bucketIndex = this.getBucketIndex(value);
const subBucketIndex = this.getSubBucketIndex(value, bucketIndex);
const distanceToNextValue = pow(2, this.unitMagnitude +
(subBucketIndex >= this.subBucketCount ? bucketIndex + 1 : bucketIndex));
return distanceToNextValue;
}
/**
* Get a value that lies in the middle (rounded up) of the range of values equivalent the given value.
* Where "equivalent" means that value samples recorded for any two
* equivalent values are counted in a common total count.
*
* @param value The given value
* @return The value lies in the middle (rounded up) of the range of values equivalent the given value.
*/
medianEquivalentValue(value) {
return (this.lowestEquivalentValue(value) +
floor(this.sizeOfEquivalentValueRange(value) / 2));
}
/**
* Get the computed mean value of all recorded values in the histogram
*
* @return the mean value (in value units) of the histogram data
*/
get mean() {
if (this.totalCount === 0) {
return 0;
}
this.recordedValuesIterator.reset();
let totalValue = 0;
while (this.recordedValuesIterator.hasNext()) {
const iterationValue = this.recordedValuesIterator.next();
totalValue +=
this.medianEquivalentValue(iterationValue.valueIteratedTo) *
iterationValue.countAtValueIteratedTo;
}
return totalValue / this.totalCount;
}
getStdDeviation(mean = this.mean) {
if (this.totalCount === 0) {
return 0;
}
let geometric_deviation_total = 0.0;
this.recordedValuesIterator.reset();
while (this.recordedValuesIterator.hasNext()) {
const iterationValue = this.recordedValuesIterator.next();
const deviation = this.medianEquivalentValue(iterationValue.valueIteratedTo) - mean;
geometric_deviation_total +=
deviation * deviation * iterationValue.countAddedInThisIterationStep;
}
const std_deviation = Math.sqrt(geometric_deviation_total / this.totalCount);
return std_deviation;
}
/**
* Get the computed standard deviation of all recorded values in the histogram
*
* @return the standard deviation (in value units) of the histogram data
*/
get stdDeviation() {
if (this.totalCount === 0) {
return 0;
}
const mean = this.mean;
let geometric_deviation_total = 0.0;
this.recordedValuesIterator.reset();
while (this.recordedValuesIterator.hasNext()) {
const iterationValue = this.recordedValuesIterator.next();
const deviation = this.medianEquivalentValue(iterationValue.valueIteratedTo) - mean;
geometric_deviation_total +=
deviation * deviation * iterationValue.countAddedInThisIterationStep;
}
const std_deviation = Math.sqrt(geometric_deviation_total / this.totalCount);
return std_deviation;
}
/**
* Produce textual representation of the value distribution of histogram data by percentile. The distribution is
* output with exponentially increasing resolution, with each exponentially decreasing half-distance containing
* <i>dumpTicksPerHalf</i> percentile reporting tick points.
*
* @param printStream Stream into which the distribution will be output
* <p>
* @param percentileTicksPerHalfDistance The number of reporting points per exponentially decreasing half-distance
* <p>
* @param outputValueUnitScalingRatio The scaling factor by which to divide histogram recorded values units in
* output
* @param useCsvFormat Output in CSV format if true. Otherwise use plain text form.
*/
outputPercentileDistribution(percentileTicksPerHalfDistance = 5, outputValueUnitScalingRatio = 1, useCsvFormat = false) {
let result = "";
if (useCsvFormat) {
result += '"Value","Percentile","TotalCount","1/(1-Percentile)"\n';
}
else {
result += " Value Percentile TotalCount 1/(1-Percentile)\n\n";
}
const iterator = this.percentileIterator;
iterator.reset(percentileTicksPerHalfDistance);
let lineFormatter;
let lastLineFormatter;
if (useCsvFormat) {
const valueFormatter = formatters_1.floatFormatter(0, this.numberOfSignificantValueDigits);
const percentileFormatter = formatters_1.floatFormatter(0, 12);
const lastFormatter = formatters_1.floatFormatter(0, 2);
lineFormatter = (iterationValue) => valueFormatter(iterationValue.valueIteratedTo / outputValueUnitScalingRatio) +
"," +
percentileFormatter(iterationValue.percentileLevelIteratedTo / 100) +
"," +
iterationValue.totalCountToThisValue +
"," +
lastFormatter(1 / (1 - iterationValue.percentileLevelIteratedTo / 100)) +
"\n";
lastLineFormatter = (iterationValue) => valueFormatter(iterationValue.valueIteratedTo / outputValueUnitScalingRatio) +
"," +
percentileFormatter(iterationValue.percentileLevelIteratedTo / 100) +
"," +
iterationValue.totalCountToThisValue +
",Infinity\n";
}
else {
const valueFormatter = formatters_1.floatFormatter(12, this.numberOfSignificantValueDigits);
const percentileFormatter = formatters_1.floatFormatter(2, 12);
const totalCountFormatter = formatters_1.integerFormatter(10);
const lastFormatter = formatters_1.floatFormatter(14, 2);
lineFormatter = (iterationValue) => valueFormatter(iterationValue.valueIteratedTo / outputValueUnitScalingRatio) +
" " +
percentileFormatter(iterationValue.percentileLevelIteratedTo / 100) +
" " +
totalCountFormatter(iterationValue.totalCountToThisValue) +
" " +
lastFormatter(1 / (1 - iterationValue.percentileLevelIteratedTo / 100)) +
"\n";
lastLineFormatter = (iterationValue) => valueFormatter(iterationValue.valueIteratedTo / outputValueUnitScalingRatio) +
" " +
percentileFormatter(iterationValue.percentileLevelIteratedTo / 100) +
" " +
totalCountFormatter(iterationValue.totalCountToThisValue) +
"\n";
}
while (iterator.hasNext()) {
const iterationValue = iterator.next();
if (iterationValue.percentileLevelIteratedTo < 100) {
result += lineFormatter(iterationValue);
}
else {
result += lastLineFormatter(iterationValue);
}
}
if (!useCsvFormat) {
// Calculate and output mean and std. deviation.
// Note: mean/std. deviation numbers are very often completely irrelevant when
// data is extremely non-normal in distribution (e.g. in cases of strong multi-modal
// response time distribution associated with GC pauses). However, reporting these numbers
// can be very useful for contrasting with the detailed percentile distribution
// reported by outputPercentileDistribution(). It is not at all surprising to find
// percentile distributions where results fall many tens or even hundreds of standard
// deviations away from the mean - such results simply indicate that the data sampled
// exhibits a very non-normal distribution, highlighting situations for which the std.
// deviation metric is a useless indicator.
//
const formatter = formatters_1.floatFormatter(12, this.numberOfSignificantValueDigits);
const _mean = this.mean;
const mean = formatter(_mean / outputValueUnitScalingRatio);
const std_deviation = formatter(this.getStdDeviation(_mean) / outputValueUnitScalingRatio);
const max = formatter(this.maxValue / outputValueUnitScalingRatio);
const intFormatter = formatters_1.integerFormatter(12);
const totalCount = intFormatter(this.totalCount);
const bucketCount = intFormatter(this.bucketCount);
const subBucketCount = intFormatter(this.subBucketCount);
result += `#[Mean = ${mean}, StdDeviation = ${std_deviation}]
#[Max = ${max}, Total count = ${totalCount}]
#[Buckets = ${bucketCount}, SubBuckets = ${subBucketCount}]
`;
}
return result;
}
get summary() {
return Histogram_1.toSummary(this);
}
toJSON() {
return this.summary;
}
inspect() {
return this.toString();
}
[Symbol.for("nodejs.util.inspect.custom")]() {
return this.toString();
}
/**
* Provide a (conservatively high) estimate of the Histogram's total footprint in bytes
*
* @return a (conservatively high) estimate of the Histogram's total footprint in bytes
*/
get estimatedFootprintInBytes() {
return this._getEstimatedFootprintInBytes();
}
recordSingleValueWithExpectedInterval(value, expectedIntervalBetweenValueSamples) {
this.recordSingleValue(value);
if (expectedIntervalBetweenValueSamples <= 0) {
return;
}
for (let missingValue = value - expectedIntervalBetweenValueSamples; missingValue >= expectedIntervalBetweenValueSamples; missingValue -= expectedIntervalBetweenValueSamples) {
this.recordSingleValue(missingValue);
}
}
recordCountAtValue(count, value) {
const countsIndex = this.countsArrayIndex(value);
if (countsIndex >= this.countsArrayLength) {
this.handleRecordException(count, value);
}
else {
this.addToCountAtIndex(countsIndex, count);
}
this.updateMinAndMax(value);
this.addToTotalCount(count);
}
/**
* Record a value in the histogram (adding to the value's current count)
*
* @param value The value to be recorded
* @param count The number of occurrences of this value to record
* @throws ArrayIndexOutOfBoundsException (may throw) if value is exceeds highestTrackableValue
*/
recordValueWithCount(value, count) {
this.recordCountAtValue(count, value);
}
/**
* Record a value in the histogram.
* <p>
* To compensate for the loss of sampled values when a recorded value is larger than the expected
* interval between value samples, Histogram will auto-generate an additional series of decreasingly-smaller
* (down to the expectedIntervalBetweenValueSamples) value records.
* <p>
* Note: This is a at-recording correction method, as opposed to the post-recording correction method provided
* by {@link #copyCorrectedForCoordinatedOmission(long)}.
* The two methods are mutually exclusive, and only one of the two should be be used on a given data set to correct
* for the same coordinated omission issue.
* <p>
* See notes in the description of the Histogram calls for an illustration of why this corrective behavior is
* important.
*
* @param value The value to record
* @param expectedIntervalBetweenValueSamples If expectedIntervalBetweenValueSamples is larger than 0, add
* auto-generated value records as appropriate if value is larger
* than expectedIntervalBetweenValueSamples
* @throws ArrayIndexOutOfBoundsException (may throw) if value is exceeds highestTrackableValue
*/
recordValueWithExpectedInterval(value, expectedIntervalBetweenValueSamples) {
this.recordSingleValueWithExpectedInterval(value, expectedIntervalBetweenValueSamples);
}
recordValueWithCountAndExpectedInterval(value, count, expectedIntervalBetweenValueSamples) {
this.recordCountAtValue(count, value);
if (expectedIntervalBetweenValueSamples <= 0) {
return;
}
for (let missingValue = value - expectedIntervalBetweenValueSamples; missingValue >= expectedIntervalBetweenValueSamples; missingValue -= expectedIntervalBetweenValueSamples) {
this.recordCountAtValue(count, missingValue);
}
}
/**
* Add the contents of another histogram to this one, while correcting the incoming data for coordinated omission.
* <p>
* To compensate for the loss of sampled values when a recorded value is larger than the expected
* interval between value samples, the values added will include an auto-generated additional series of
* decreasingly-smaller (down to the expectedIntervalBetweenValueSamples) value records for each count found
* in the current histogram that is larger than the expectedIntervalBetweenValueSamples.
*
* Note: This is a post-recording correction method, as opposed to the at-recording correction method provided
* by {@link #recordValueWithExpectedInterval(long, long) recordValueWithExpectedInterval}. The two
* methods are mutually exclusive, and only one of the two should be be used on a given data set to correct
* for the same coordinated omission issue.
* by
* <p>
* See notes in the description of the Histogram calls for an illustration of why this corrective behavior is
* important.
*
* @param otherHistogram The other histogram. highestTrackableValue and largestValueWithSingleUnitResolution must match.
* @param expectedIntervalBetweenValueSamples If expectedIntervalBetweenValueSamples is larger than 0, add
* auto-generated value records as appropriate if value is larger
* than expectedIntervalBetweenValueSamples
* @throws ArrayIndexOutOfBoundsException (may throw) if values exceed highestTrackableValue
*/
addWhileCorrectingForCoordinatedOmission(otherHistogram, expectedIntervalBetweenValueSamples) {
const toHistogram = this;
const otherValues = new RecordedValuesIterator_1.default(otherHistogram);
while (otherValues.hasNext()) {
const v = otherValues.next();
toHistogram.recordValueWithCountAndExpectedInterval(v.valueIteratedTo, v.countAtValueIteratedTo, expectedIntervalBetweenValueSamples);
}
}
/**
* Add the contents of another histogram to this one.
* <p>
* As part of adding the contents, the start/end timestamp range of this histogram will be
* extended to include the start/end timestamp range of the other histogram.
*
* @param otherHistogram The other histogram.
* @throws (may throw) if values in fromHistogram's are
* higher than highestTrackableValue.
*/
add(otherHistogram) {
if (!(otherHistogram instanceof JsHistogram)) {
// should be impossible to be in this situation but actually
// TypeScript has some flaws...
throw new Error("Cannot add a WASM histogram to a regular JS histogram");
}
const highestRecordableValue = this.highestEquivalentValue(this.valueFromIndex(this.countsArrayLength - 1));
if (highestRecordableValue < otherHistogram.maxValue) {
if (!this.autoResize) {
throw new Error("The other histogram includes values that do not fit in this histogram's range.");
}
this.resize(otherHistogram.maxValue);
}
if (this.bucketCount === otherHistogram.bucketCount &&
this.subBucketCount === otherHistogram.subBucketCount &&
this.unitMagnitude === otherHistogram.unitMagnitude) {
// Counts arrays are of the same length and meaning, so we can just iterate and add directly:
let observedOtherTotalCount = 0;
for (let i = 0; i < otherHistogram.countsArrayLength; i++) {
const otherCount = otherHistogram.getCountAtIndex(i);
if (otherCount > 0) {
this.addToCountAtIndex(i, otherCount);
observedOtherTotalCount += otherCount;
}
}
this.setTotalCount(this.totalCount + observedOtherTotalCount);
this.updatedMaxValue(max(this.maxValue, otherHistogram.maxValue));
this.updateMinNonZeroValue(min(this.minNonZeroValue, otherHistogram.minNonZeroValue));
}
else {
// Arrays are not a direct match (or the other could change on the fly in some valid way),
// so we can't just stream through and add them. Instead, go through the array and add each
// non-zero value found at it's proper value:
// Do max value first, to avoid max value updates on each iteration:
const otherMaxIndex = otherHistogram.countsArrayIndex(otherHistogram.maxValue);
let otherCount = otherHistogram.getCountAtIndex(otherMaxIndex);
this.recordCountAtValue(otherCount, otherHistogram.valueFromIndex(otherMaxIndex));
// Record the remaining values, up to but not including the max value:
for (let i = 0; i < otherMaxIndex; i++) {
otherCount = otherHistogram.getCountAtIndex(i);
if (otherCount > 0) {
this.recordCountAtValue(otherCount, otherHistogram.valueFromIndex(i));
}
}
}
this.startTimeStampMsec = min(this.startTimeStampMsec, otherHistogram.startTimeStampMsec);
this.endTimeStampMsec = max(this.endTimeStampMsec, otherHistogram.endTimeStampMsec);
}
/**
* Get the count of recorded values at a specific value (to within the histogram resolution at the value level).
*
* @param value The value for which to provide the recorded count
* @return The total count of values recorded in the histogram within the value range that is
* {@literal >=} lowestEquivalentValue(<i>value</i>) and {@literal <=} highestEquivalentValue(<i>value</i>)
*/
getCountAtValue(value) {
const index = min(max(0, this.countsArrayIndex(value)), this.countsArrayLength - 1);
return this.getCountAtIndex(index);
}
/**
* Subtract the contents of another histogram from this one.
* <p>
* The start/end timestamps of this histogram will remain unchanged.
*
* @param otherHistogram The other histogram.
* @throws ArrayIndexOutOfBoundsException (may throw) if values in otherHistogram's are higher than highestTrackableValue.
*
*/
subtract(otherHistogram) {
const highestRecordableValue = this.valueFromIndex(this.countsArrayLength - 1);
if (!(otherHistogram instanceof JsHistogram)) {
// should be impossible to be in this situation but actually
// TypeScript has some flaws...
throw new Error("Cannot subtract a WASM histogram to a regular JS histogram");
}
if (highestRecordableValue < otherHistogram.maxValue) {
if (!this.autoResize) {
throw new Error("The other histogram includes values that do not fit in this histogram's range.");
}
this.resize(otherHistogram.maxValue);
}
if (this.bucketCount === otherHistogram.bucketCount &&
this.subBucketCount === otherHistogram.subBucketCount &&
this.unitMagnitude === otherHistogram.unitMagnitude) {
// optim
// Counts arrays are of the same length and meaning, so we can just iterate and add directly:
let observedOtherTotalCount = 0;
for (let i = 0; i < otherHistogram.countsArrayLength; i++) {
const otherCount = otherHistogram.getCountAtIndex(i);
if (otherCount > 0) {
this.addToCountAtIndex(i, -otherCount);
observedOtherTotalCount += otherCount;
}
}
this.setTotalCount(this.totalCount - observedOtherTotalCount);
}
else {
for (let i = 0; i < otherHistogram.countsArrayLength; i++) {
const otherCount = otherHistogram.getCountAtIndex(i);
if (otherCount > 0) {
const otherValue = otherHistogram.valueFromIndex(i);
if (this.getCountAtValue(otherValue) < otherCount) {
throw new Error("otherHistogram count (" +
otherCount +
") at value " +
otherValue +
" is larger than this one's (" +
this.getCountAtValue(otherValue) +
")");
}
this.recordCountAtValue(-otherCount, otherValue);
}
}
}
// With subtraction, the max and minNonZero values could have changed:
if (this.getCountAtValue(this.maxValue) <= 0 ||
this.getCountAtValue(this.minNonZeroValue) <= 0) {
this.establishInternalTackingValues();
}
}
establishInternalTackingValues(lengthToCover = this.countsArrayLength) {
this.maxValue = 0;
this.minNonZeroValue = Number.MAX_VALUE;
let maxIndex = -1;
let minNonZeroIndex = -1;
let observedTotalCount = 0;
for (let index = 0; index < lengthToCover; index++) {
const countAtIndex = this.getCountAtIndex(index);
if (countAtIndex > 0) {
observedTotalCount += countAtIndex;
maxIndex = index;
if (minNonZeroIndex == -1 && index != 0) {
minNonZeroIndex = index;
}
}
}
if (maxIndex >= 0) {
this.updatedMaxValue(this.highestEquivalentValue(this.valueFromIndex(maxIndex)));
}
if (minNonZeroIndex >= 0) {
this.updateMinNonZeroValue(this.valueFromIndex(minNonZeroIndex));
}
this.setTotalCount(observedTotalCount);
}
reset() {
this.clearCounts();
this.setTotalCount(0);
this.startTimeStampMsec = 0;
this.endTimeStampMsec = 0;
this.tag = Histogram_1.NO_TAG;
this.maxValue = 0;
this.minNonZeroValue = Number.MAX_SAFE_INTEGER;
}
destroy() {
// no op - not needed here
}
}
exports.JsHistogram = JsHistogram;
exports.default = JsHistogram;
//# sourceMappingURL=JsHistogram.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,6 @@
import { BitBucketSize } from "./Histogram";
import JsHistogram from "./JsHistogram";
export interface JsHistogramConstructor {
new (lowestDiscernibleValue: number, highestTrackableValue: number, numberOfSignificantValueDigits: number): JsHistogram;
}
export declare function constructorFromBucketSize(bitBucketSize: BitBucketSize): JsHistogramConstructor;

View file

@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.constructorFromBucketSize = void 0;
const PackedHistogram_1 = require("./PackedHistogram");
const Int8Histogram_1 = require("./Int8Histogram");
const Int16Histogram_1 = require("./Int16Histogram");
const Int32Histogram_1 = require("./Int32Histogram");
const Float64Histogram_1 = require("./Float64Histogram");
function constructorFromBucketSize(bitBucketSize) {
switch (bitBucketSize) {
case "packed":
return PackedHistogram_1.default;
case 8:
return Int8Histogram_1.default;
case 16:
return Int16Histogram_1.default;
case 32:
return Int32Histogram_1.default;
case 64:
return Float64Histogram_1.default;
default:
throw new Error("Incorrect parameter bitBucketSize");
}
}
exports.constructorFromBucketSize = constructorFromBucketSize;
//# sourceMappingURL=JsHistogramFactory.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"JsHistogramFactory.js","sourceRoot":"","sources":["../src/JsHistogramFactory.ts"],"names":[],"mappings":";;;AACA,uDAAgD;AAChD,mDAA4C;AAC5C,qDAA8C;AAC9C,qDAA8C;AAC9C,yDAAkD;AAWlD,SAAgB,yBAAyB,CACvC,aAA4B;IAE5B,QAAQ,aAAa,EAAE;QACrB,KAAK,QAAQ;YACX,OAAO,yBAAe,CAAC;QACzB,KAAK,CAAC;YACJ,OAAO,uBAAa,CAAC;QACvB,KAAK,EAAE;YACL,OAAO,wBAAc,CAAC;QACxB,KAAK,EAAE;YACL,OAAO,wBAAc,CAAC;QACxB,KAAK,EAAE;YACL,OAAO,0BAAgB,CAAC;QAC1B;YACE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;KACxD;AACH,CAAC;AAjBD,8DAiBC"}

View file

@ -0,0 +1,45 @@
import JsHistogram from "./JsHistogram";
import HistogramIterationValue from "./HistogramIterationValue";
/**
* Used for iterating through histogram values.
*/
declare abstract class JsHistogramIterator {
histogram: JsHistogram;
savedHistogramTotalRawCount: number;
currentIndex: number;
currentValueAtIndex: number;
nextValueAtIndex: number;
prevValueIteratedTo: number;
totalCountToPrevIndex: number;
totalCountToCurrentIndex: number;
totalValueToCurrentIndex: number;
arrayTotalCount: number;
countAtThisValue: number;
private freshSubBucket;
currentIterationValue: HistogramIterationValue;
resetIterator(histogram: JsHistogram): void;
/**
* Returns true if the iteration has more elements. (In other words, returns true if next would return an
* element rather than throwing an exception.)
*
* @return true if the iterator has more elements.
*/
hasNext(): boolean;
/**
* Returns the next element in the iteration.
*
* @return the {@link HistogramIterationValue} associated with the next element in the iteration.
*/
next(): HistogramIterationValue;
abstract incrementIterationLevel(): void;
/**
* @return true if the current position's data should be emitted by the iterator
*/
abstract reachedIterationLevel(): boolean;
getPercentileIteratedTo(): number;
getPercentileIteratedFrom(): number;
getValueIteratedTo(): number;
private exhaustedSubBuckets;
incrementSubBucket(): void;
}
export default JsHistogramIterator;

View file

@ -0,0 +1,99 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const HistogramIterationValue_1 = require("./HistogramIterationValue");
/**
* Used for iterating through histogram values.
*/
class JsHistogramIterator /* implements Iterator<HistogramIterationValue> */ {
constructor() {
this.currentIterationValue = new HistogramIterationValue_1.default();
}
resetIterator(histogram) {
this.histogram = histogram;
this.savedHistogramTotalRawCount = histogram.totalCount;
this.arrayTotalCount = histogram.totalCount;
this.currentIndex = 0;
this.currentValueAtIndex = 0;
this.nextValueAtIndex = Math.pow(2, histogram.unitMagnitude);
this.prevValueIteratedTo = 0;
this.totalCountToPrevIndex = 0;
this.totalCountToCurrentIndex = 0;
this.totalValueToCurrentIndex = 0;
this.countAtThisValue = 0;
this.freshSubBucket = true;
this.currentIterationValue.reset();
}
/**
* Returns true if the iteration has more elements. (In other words, returns true if next would return an
* element rather than throwing an exception.)
*
* @return true if the iterator has more elements.
*/
hasNext() {
if (this.histogram.totalCount !== this.savedHistogramTotalRawCount) {
throw "Concurrent Modification Exception";
}
return this.totalCountToCurrentIndex < this.arrayTotalCount;
}
/**
* Returns the next element in the iteration.
*
* @return the {@link HistogramIterationValue} associated with the next element in the iteration.
*/
next() {
// Move through the sub buckets and buckets until we hit the next reporting level:
while (!this.exhaustedSubBuckets()) {
this.countAtThisValue = this.histogram.getCountAtIndex(this.currentIndex);
if (this.freshSubBucket) {
// Don't add unless we've incremented since last bucket...
this.totalCountToCurrentIndex += this.countAtThisValue;
this.totalValueToCurrentIndex +=
this.countAtThisValue *
this.histogram.highestEquivalentValue(this.currentValueAtIndex);
this.freshSubBucket = false;
}
if (this.reachedIterationLevel()) {
const valueIteratedTo = this.getValueIteratedTo();
Object.assign(this.currentIterationValue, {
valueIteratedTo,
valueIteratedFrom: this.prevValueIteratedTo,
countAtValueIteratedTo: this.countAtThisValue,
countAddedInThisIterationStep: this.totalCountToCurrentIndex - this.totalCountToPrevIndex,
totalCountToThisValue: this.totalCountToCurrentIndex,
totalValueToThisValue: this.totalValueToCurrentIndex,
percentile: (100 * this.totalCountToCurrentIndex) / this.arrayTotalCount,
percentileLevelIteratedTo: this.getPercentileIteratedTo(),
});
this.prevValueIteratedTo = valueIteratedTo;
this.totalCountToPrevIndex = this.totalCountToCurrentIndex;
this.incrementIterationLevel();
if (this.histogram.totalCount !== this.savedHistogramTotalRawCount) {
throw new Error("Concurrent Modification Exception");
}
return this.currentIterationValue;
}
this.incrementSubBucket();
}
throw new Error("Index Out Of Bounds Exception");
}
getPercentileIteratedTo() {
return (100 * this.totalCountToCurrentIndex) / this.arrayTotalCount;
}
getPercentileIteratedFrom() {
return (100 * this.totalCountToPrevIndex) / this.arrayTotalCount;
}
getValueIteratedTo() {
return this.histogram.highestEquivalentValue(this.currentValueAtIndex);
}
exhaustedSubBuckets() {
return this.currentIndex >= this.histogram.countsArrayLength;
}
incrementSubBucket() {
this.freshSubBucket = true;
this.currentIndex++;
this.currentValueAtIndex = this.histogram.valueFromIndex(this.currentIndex);
this.nextValueAtIndex = this.histogram.valueFromIndex(this.currentIndex + 1);
}
}
exports.default = JsHistogramIterator;
//# sourceMappingURL=JsHistogramIterator.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"JsHistogramIterator.js","sourceRoot":"","sources":["../src/JsHistogramIterator.ts"],"names":[],"mappings":";;AAQA,uEAAgE;AAEhE;;GAEG;AACH,MAAe,mBAAmB,CAAC,kDAAkD;IAArF;QAeE,0BAAqB,GAA4B,IAAI,iCAAuB,EAAE,CAAC;IA4GjF,CAAC;IA1GC,aAAa,CAAC,SAAsB;QAClC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,2BAA2B,GAAG,SAAS,CAAC,UAAU,CAAC;QACxD,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC,UAAU,CAAC;QAC5C,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;QAC7D,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,qBAAqB,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,wBAAwB,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,wBAAwB,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,CAAC;IACrC,CAAC;IAED;;;;;OAKG;IACI,OAAO;QACZ,IAAI,IAAI,CAAC,SAAS,CAAC,UAAU,KAAK,IAAI,CAAC,2BAA2B,EAAE;YAClE,MAAM,mCAAmC,CAAC;SAC3C;QACD,OAAO,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC,eAAe,CAAC;IAC9D,CAAC;IAED;;;;OAIG;IACI,IAAI;QACT,kFAAkF;QAClF,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE,EAAE;YAClC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC1E,IAAI,IAAI,CAAC,cAAc,EAAE;gBACvB,0DAA0D;gBAC1D,IAAI,CAAC,wBAAwB,IAAI,IAAI,CAAC,gBAAgB,CAAC;gBACvD,IAAI,CAAC,wBAAwB;oBAC3B,IAAI,CAAC,gBAAgB;wBACrB,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;gBAClE,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;aAC7B;YACD,IAAI,IAAI,CAAC,qBAAqB,EAAE,EAAE;gBAChC,MAAM,eAAe,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAElD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE;oBACxC,eAAe;oBACf,iBAAiB,EAAE,IAAI,CAAC,mBAAmB;oBAC3C,sBAAsB,EAAE,IAAI,CAAC,gBAAgB;oBAC7C,6BAA6B,EAC3B,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC,qBAAqB;oBAC5D,qBAAqB,EAAE,IAAI,CAAC,wBAAwB;oBACpD,qBAAqB,EAAE,IAAI,CAAC,wBAAwB;oBACpD,UAAU,EACR,CAAC,GAAG,GAAG,IAAI,CAAC,wBAAwB,CAAC,GAAG,IAAI,CAAC,eAAe;oBAC9D,yBAAyB,EAAE,IAAI,CAAC,uBAAuB,EAAE;iBAC1D,CAAC,CAAC;gBAEH,IAAI,CAAC,mBAAmB,GAAG,eAAe,CAAC;gBAC3C,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,wBAAwB,CAAC;gBAC3D,IAAI,CAAC,uBAAuB,EAAE,CAAC;gBAC/B,IAAI,IAAI,CAAC,SAAS,CAAC,UAAU,KAAK,IAAI,CAAC,2BAA2B,EAAE;oBAClE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;iBACtD;gBACD,OAAO,IAAI,CAAC,qBAAqB,CAAC;aACnC;YACD,IAAI,CAAC,kBAAkB,EAAE,CAAC;SAC3B;QACD,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IASD,uBAAuB;QACrB,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,wBAAwB,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC;IACtE,CAAC;IAED,yBAAyB;QACvB,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,qBAAqB,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC;IACnE,CAAC;IAED,kBAAkB;QAChB,OAAO,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACzE,CAAC;IAEO,mBAAmB;QACzB,OAAO,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC;IAC/D,CAAC;IAED,kBAAkB;QAChB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC5E,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,CACnD,IAAI,CAAC,YAAY,GAAG,CAAC,CACtB,CAAC;IACJ,CAAC;CACF;AAED,kBAAe,mBAAmB,CAAC"}

View file

@ -0,0 +1,44 @@
import JsHistogram from "./JsHistogram";
import { PackedArray } from "./packedarray/PackedArray";
/**
* <h3>A High Dynamic Range (HDR) Histogram that uses a packed internal representation</h3>
* <p>
* {@link PackedHistogram} supports the recording and analyzing sampled data value counts across a configurable
* integer value range with configurable value precision within the range. Value precision is expressed as the
* number of significant digits in the value recording, and provides control over value quantization behavior
* across the value range and the subsequent value resolution at any given level.
* <p>
* {@link PackedHistogram} tracks value counts in a packed internal representation optimized
* for typical histogram recoded values are sparse in the value range and tend to be incremented in small unit counts.
* This packed representation tends to require significantly smaller amounts of stoarge when compared to unpacked
* representations, but can incur additional recording cost due to resizing and repacking operations that may
* occur as previously unrecorded values are encountered.
* <p>
* For example, a {@link PackedHistogram} could be configured to track the counts of observed integer values between 0 and
* 3,600,000,000,000 while maintaining a value precision of 3 significant digits across that range. Value quantization
* within the range will thus be no larger than 1/1,000th (or 0.1%) of any value. This example Histogram could
* be used to track and analyze the counts of observed response times ranging between 1 nanosecond and 1 hour
* in magnitude, while maintaining a value resolution of 1 microsecond up to 1 millisecond, a resolution of
* 1 millisecond (or better) up to one second, and a resolution of 1 second (or better) up to 1,000 seconds. At its
* maximum tracked value (1 hour), it would still maintain a resolution of 3.6 seconds (or better).
* <p>
* Auto-resizing: When constructed with no specified value range range (or when auto-resize is turned on with {@link
* Histogram#setAutoResize}) a {@link PackedHistogram} will auto-resize its dynamic range to include recorded values as
* they are encountered. Note that recording calls that cause auto-resizing may take longer to execute, as resizing
* incurs allocation and copying of internal data structures.
* <p>
*/
declare class PackedHistogram extends JsHistogram {
packedCounts: PackedArray;
constructor(lowestDiscernibleValue: number, highestTrackableValue: number, numberOfSignificantValueDigits: number);
clearCounts(): void;
incrementCountAtIndex(index: number): void;
addToCountAtIndex(index: number, value: number): void;
setCountAtIndex(index: number, value: number): void;
resize(newHighestTrackableValue: number): void;
getCountAtIndex(index: number): number;
protected _getEstimatedFootprintInBytes(): number;
copyCorrectedForCoordinatedOmission(expectedIntervalBetweenValueSamples: number): PackedHistogram;
toString(): string;
}
export default PackedHistogram;

78
my-app/node_modules/hdr-histogram-js/dist/PackedHistogram.js generated vendored Executable file
View file

@ -0,0 +1,78 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*
* 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/
*/
const JsHistogram_1 = require("./JsHistogram");
const PackedArray_1 = require("./packedarray/PackedArray");
/**
* <h3>A High Dynamic Range (HDR) Histogram that uses a packed internal representation</h3>
* <p>
* {@link PackedHistogram} supports the recording and analyzing sampled data value counts across a configurable
* integer value range with configurable value precision within the range. Value precision is expressed as the
* number of significant digits in the value recording, and provides control over value quantization behavior
* across the value range and the subsequent value resolution at any given level.
* <p>
* {@link PackedHistogram} tracks value counts in a packed internal representation optimized
* for typical histogram recoded values are sparse in the value range and tend to be incremented in small unit counts.
* This packed representation tends to require significantly smaller amounts of stoarge when compared to unpacked
* representations, but can incur additional recording cost due to resizing and repacking operations that may
* occur as previously unrecorded values are encountered.
* <p>
* For example, a {@link PackedHistogram} could be configured to track the counts of observed integer values between 0 and
* 3,600,000,000,000 while maintaining a value precision of 3 significant digits across that range. Value quantization
* within the range will thus be no larger than 1/1,000th (or 0.1%) of any value. This example Histogram could
* be used to track and analyze the counts of observed response times ranging between 1 nanosecond and 1 hour
* in magnitude, while maintaining a value resolution of 1 microsecond up to 1 millisecond, a resolution of
* 1 millisecond (or better) up to one second, and a resolution of 1 second (or better) up to 1,000 seconds. At its
* maximum tracked value (1 hour), it would still maintain a resolution of 3.6 seconds (or better).
* <p>
* Auto-resizing: When constructed with no specified value range range (or when auto-resize is turned on with {@link
* Histogram#setAutoResize}) a {@link PackedHistogram} will auto-resize its dynamic range to include recorded values as
* they are encountered. Note that recording calls that cause auto-resizing may take longer to execute, as resizing
* incurs allocation and copying of internal data structures.
* <p>
*/
class PackedHistogram extends JsHistogram_1.default {
constructor(lowestDiscernibleValue, highestTrackableValue, numberOfSignificantValueDigits) {
super(lowestDiscernibleValue, highestTrackableValue, numberOfSignificantValueDigits);
this._totalCount = 0;
this.packedCounts = new PackedArray_1.PackedArray(this.countsArrayLength);
}
clearCounts() {
this.packedCounts.clear();
}
incrementCountAtIndex(index) {
this.packedCounts.increment(index);
}
addToCountAtIndex(index, value) {
this.packedCounts.add(index, value);
}
setCountAtIndex(index, value) {
this.packedCounts.set(index, value);
}
resize(newHighestTrackableValue) {
this.establishSize(newHighestTrackableValue);
this.packedCounts.setVirtualLength(this.countsArrayLength);
}
getCountAtIndex(index) {
return this.packedCounts.get(index);
}
_getEstimatedFootprintInBytes() {
return 192 + 8 * this.packedCounts.getPhysicalLength();
}
copyCorrectedForCoordinatedOmission(expectedIntervalBetweenValueSamples) {
const copy = new PackedHistogram(this.lowestDiscernibleValue, this.highestTrackableValue, this.numberOfSignificantValueDigits);
copy.addWhileCorrectingForCoordinatedOmission(this, expectedIntervalBetweenValueSamples);
return copy;
}
toString() {
return `PackedHistogram ${JSON.stringify(this, null, 2)}`;
}
}
exports.default = PackedHistogram;
//# sourceMappingURL=PackedHistogram.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"PackedHistogram.js","sourceRoot":"","sources":["../src/PackedHistogram.ts"],"names":[],"mappings":";;AAAA;;;;;;GAMG;AACH,+CAAwC;AACxC,2DAAwD;AACxD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,eAAgB,SAAQ,qBAAW;IAGvC,YACE,sBAA8B,EAC9B,qBAA6B,EAC7B,8BAAsC;QAEtC,KAAK,CACH,sBAAsB,EACtB,qBAAqB,EACrB,8BAA8B,CAC/B,CAAC;QACF,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,IAAI,yBAAW,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC9D,CAAC;IAED,WAAW;QACT,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED,qBAAqB,CAAC,KAAa;QACjC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;IAED,iBAAiB,CAAC,KAAa,EAAE,KAAa;QAC5C,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,eAAe,CAAC,KAAa,EAAE,KAAa;QAC1C,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,MAAM,CAAC,wBAAgC;QACrC,IAAI,CAAC,aAAa,CAAC,wBAAwB,CAAC,CAAC;QAC7C,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC7D,CAAC;IAED,eAAe,CAAC,KAAa;QAC3B,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAES,6BAA6B;QACrC,OAAO,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,iBAAiB,EAAE,CAAC;IACzD,CAAC;IAED,mCAAmC,CACjC,mCAA2C;QAE3C,MAAM,IAAI,GAAG,IAAI,eAAe,CAC9B,IAAI,CAAC,sBAAsB,EAC3B,IAAI,CAAC,qBAAqB,EAC1B,IAAI,CAAC,8BAA8B,CACpC,CAAC;QACF,IAAI,CAAC,wCAAwC,CAC3C,IAAI,EACJ,mCAAmC,CACpC,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,QAAQ;QACN,OAAO,mBAAmB,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;IAC5D,CAAC;CACF;AAED,kBAAe,eAAe,CAAC"}

View file

@ -0,0 +1 @@
export {};

View file

@ -0,0 +1,76 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const PackedHistogram_1 = require("./PackedHistogram");
describe("Packed histogram", () => {
it("should compute median value in first bucket", () => {
// given
const histogram = new PackedHistogram_1.default(1, Number.MAX_SAFE_INTEGER, 3);
histogram.recordValue(123456);
histogram.recordValue(127);
histogram.recordValue(42);
// when
const medianValue = histogram.getValueAtPercentile(50);
// then
expect(medianValue).toBe(127);
});
it("should compute same values when new or reseted", () => {
// given
const histogram = new PackedHistogram_1.default(1, 2, 3);
const histogram2 = new PackedHistogram_1.default(1, 2, 3);
histogram.autoResize = true;
histogram2.autoResize = true;
[1, 49026].forEach((v) => histogram.recordValue(v));
// when
histogram.reset();
[7, 67, 42357, 805017].forEach((v) => {
histogram.recordValue(v);
histogram2.recordValue(v);
});
// then
expect(histogram.getValueAtPercentile(5)).toBe(histogram2.getValueAtPercentile(5));
});
it("should compute value outside first bucket with an error less than 1000", () => {
// given
const histogram = new PackedHistogram_1.default(1, 123456, 2);
histogram.recordValue(5234);
histogram.recordValue(127);
histogram.recordValue(42);
// when
const percentileValue = histogram.getValueAtPercentile(90);
// then
expect(Math.abs(percentileValue - 5234)).toBeLessThan(100);
});
it("should resize underlying packed array when recording an out of bound value", () => {
// given
const histogram = new PackedHistogram_1.default(1, 2, 3);
histogram.autoResize = true;
// when
histogram.recordValue(123456);
// then
expect(histogram.totalCount).toBe(1);
});
});
describe("Histogram clearing support", () => {
it("should reset data in order to reuse histogram", () => {
// given
const histogram = new PackedHistogram_1.default(1, Number.MAX_SAFE_INTEGER, 2);
const histogram2 = new PackedHistogram_1.default(1, Number.MAX_SAFE_INTEGER, 2);
histogram.startTimeStampMsec = 42;
histogram.endTimeStampMsec = 56;
histogram.tag = "blabla";
histogram.recordValue(10);
histogram.recordValue(1000);
histogram.recordValue(10000000);
// when
histogram.reset();
// then
expect(histogram.totalCount).toBe(0);
expect(histogram.startTimeStampMsec).toBe(0);
expect(histogram.endTimeStampMsec).toBe(0);
//expect(histogram.tag).toBe(NO_TAG);
expect(histogram.maxValue).toBe(0);
expect(histogram.minNonZeroValue).toBe(Number.MAX_SAFE_INTEGER);
expect(histogram.getValueAtPercentile(99.999)).toBe(0);
});
});
//# sourceMappingURL=PackedHistogram.spec.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"PackedHistogram.spec.js","sourceRoot":"","sources":["../src/PackedHistogram.spec.ts"],"names":[],"mappings":"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"}

View file

@ -0,0 +1,32 @@
import JsHistogram from "./JsHistogram";
import JsHistogramIterator from "./JsHistogramIterator";
/**
* Used for iterating through histogram values according to percentile levels. The iteration is
* performed in steps that start at 0% and reduce their distance to 100% according to the
* <i>percentileTicksPerHalfDistance</i> parameter, ultimately reaching 100% when all recorded histogram
* values are exhausted.
*/
declare class PercentileIterator extends JsHistogramIterator {
percentileTicksPerHalfDistance: number;
percentileLevelToIterateTo: number;
percentileLevelToIterateFrom: number;
reachedLastRecordedValue: boolean;
/**
* @param histogram The histogram this iterator will operate on
* @param percentileTicksPerHalfDistance The number of equal-sized iteration steps per half-distance to 100%.
*/
constructor(histogram: JsHistogram, percentileTicksPerHalfDistance: number);
/**
* Reset iterator for re-use in a fresh iteration over the same histogram data set.
*
* @param percentileTicksPerHalfDistance The number of iteration steps per half-distance to 100%.
*/
reset(percentileTicksPerHalfDistance: number): void;
private doReset;
hasNext(): boolean;
incrementIterationLevel(): void;
reachedIterationLevel(): boolean;
getPercentileIteratedTo(): number;
getPercentileIteratedFrom(): number;
}
export default PercentileIterator;

View file

@ -0,0 +1,83 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const JsHistogramIterator_1 = require("./JsHistogramIterator");
const { pow, floor, log2 } = Math;
/**
* Used for iterating through histogram values according to percentile levels. The iteration is
* performed in steps that start at 0% and reduce their distance to 100% according to the
* <i>percentileTicksPerHalfDistance</i> parameter, ultimately reaching 100% when all recorded histogram
* values are exhausted.
*/
class PercentileIterator extends JsHistogramIterator_1.default {
/**
* @param histogram The histogram this iterator will operate on
* @param percentileTicksPerHalfDistance The number of equal-sized iteration steps per half-distance to 100%.
*/
constructor(histogram, percentileTicksPerHalfDistance) {
super();
this.percentileTicksPerHalfDistance = 0;
this.percentileLevelToIterateTo = 0;
this.percentileLevelToIterateFrom = 0;
this.reachedLastRecordedValue = false;
this.doReset(histogram, percentileTicksPerHalfDistance);
}
/**
* Reset iterator for re-use in a fresh iteration over the same histogram data set.
*
* @param percentileTicksPerHalfDistance The number of iteration steps per half-distance to 100%.
*/
reset(percentileTicksPerHalfDistance) {
this.doReset(this.histogram, percentileTicksPerHalfDistance);
}
doReset(histogram, percentileTicksPerHalfDistance) {
super.resetIterator(histogram);
this.percentileTicksPerHalfDistance = percentileTicksPerHalfDistance;
this.percentileLevelToIterateTo = 0;
this.percentileLevelToIterateFrom = 0;
this.reachedLastRecordedValue = false;
}
hasNext() {
if (super.hasNext())
return true;
if (!this.reachedLastRecordedValue && this.arrayTotalCount > 0) {
this.percentileLevelToIterateTo = 100;
this.reachedLastRecordedValue = true;
return true;
}
return false;
}
incrementIterationLevel() {
this.percentileLevelToIterateFrom = this.percentileLevelToIterateTo;
// The choice to maintain fixed-sized "ticks" in each half-distance to 100% [starting
// from 0%], as opposed to a "tick" size that varies with each interval, was made to
// make the steps easily comprehensible and readable to humans. The resulting percentile
// steps are much easier to browse through in a percentile distribution output, for example.
//
// We calculate the number of equal-sized "ticks" that the 0-100 range will be divided
// by at the current scale. The scale is detemined by the percentile level we are
// iterating to. The following math determines the tick size for the current scale,
// and maintain a fixed tick size for the remaining "half the distance to 100%"
// [from either 0% or from the previous half-distance]. When that half-distance is
// crossed, the scale changes and the tick size is effectively cut in half.
// percentileTicksPerHalfDistance = 5
// percentileReportingTicks = 10,
const percentileReportingTicks = this.percentileTicksPerHalfDistance *
pow(2, floor(log2(100 / (100 - this.percentileLevelToIterateTo))) + 1);
this.percentileLevelToIterateTo += 100 / percentileReportingTicks;
}
reachedIterationLevel() {
if (this.countAtThisValue === 0) {
return false;
}
const currentPercentile = (100 * this.totalCountToCurrentIndex) / this.arrayTotalCount;
return currentPercentile >= this.percentileLevelToIterateTo;
}
getPercentileIteratedTo() {
return this.percentileLevelToIterateTo;
}
getPercentileIteratedFrom() {
return this.percentileLevelToIterateFrom;
}
}
exports.default = PercentileIterator;
//# sourceMappingURL=PercentileIterator.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"PercentileIterator.js","sourceRoot":"","sources":["../src/PercentileIterator.ts"],"names":[],"mappings":";;AACA,+DAAwD;AAExD,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;AAElC;;;;;GAKG;AACH,MAAM,kBAAmB,SAAQ,6BAAmB;IAMlD;;;OAGG;IACH,YACE,SAAsB,EACtB,8BAAsC;QAEtC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,8BAA8B,GAAG,CAAC,CAAC;QACxC,IAAI,CAAC,0BAA0B,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,4BAA4B,GAAG,CAAC,CAAC;QACtC,IAAI,CAAC,wBAAwB,GAAG,KAAK,CAAC;QACtC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,8BAA8B,CAAC,CAAC;IAC1D,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,8BAAsC;QAC1C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,8BAA8B,CAAC,CAAC;IAC/D,CAAC;IAEO,OAAO,CACb,SAAsB,EACtB,8BAAsC;QAEtC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAC/B,IAAI,CAAC,8BAA8B,GAAG,8BAA8B,CAAC;QACrE,IAAI,CAAC,0BAA0B,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,4BAA4B,GAAG,CAAC,CAAC;QACtC,IAAI,CAAC,wBAAwB,GAAG,KAAK,CAAC;IACxC,CAAC;IAEM,OAAO;QACZ,IAAI,KAAK,CAAC,OAAO,EAAE;YAAE,OAAO,IAAI,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC,wBAAwB,IAAI,IAAI,CAAC,eAAe,GAAG,CAAC,EAAE;YAC9D,IAAI,CAAC,0BAA0B,GAAG,GAAG,CAAC;YACtC,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC;YACrC,OAAO,IAAI,CAAC;SACb;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,uBAAuB;QACrB,IAAI,CAAC,4BAA4B,GAAG,IAAI,CAAC,0BAA0B,CAAC;QAEpE,qFAAqF;QACrF,oFAAoF;QACpF,wFAAwF;QACxF,4FAA4F;QAC5F,EAAE;QACF,sFAAsF;QACtF,iFAAiF;QACjF,mFAAmF;QACnF,+EAA+E;QAC/E,kFAAkF;QAClF,2EAA2E;QAE3E,qCAAqC;QACrC,iCAAiC;QAEjC,MAAM,wBAAwB,GAC5B,IAAI,CAAC,8BAA8B;YACnC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAEzE,IAAI,CAAC,0BAA0B,IAAI,GAAG,GAAG,wBAAwB,CAAC;IACpE,CAAC;IAED,qBAAqB;QACnB,IAAI,IAAI,CAAC,gBAAgB,KAAK,CAAC,EAAE;YAC/B,OAAO,KAAK,CAAC;SACd;QACD,MAAM,iBAAiB,GACrB,CAAC,GAAG,GAAG,IAAI,CAAC,wBAAwB,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC;QAC/D,OAAO,iBAAiB,IAAI,IAAI,CAAC,0BAA0B,CAAC;IAC9D,CAAC;IAED,uBAAuB;QACrB,OAAO,IAAI,CAAC,0BAA0B,CAAC;IACzC,CAAC;IAED,yBAAyB;QACvB,OAAO,IAAI,CAAC,4BAA4B,CAAC;IAC3C,CAAC;CACF;AAED,kBAAe,kBAAkB,CAAC"}

View file

@ -0,0 +1,22 @@
import JsHistogram from "./JsHistogram";
import JsHistogramIterator from "./JsHistogramIterator";
/**
* Used for iterating through all recorded histogram values using the finest granularity steps supported by the
* underlying representation. The iteration steps through all non-zero recorded value counts, and terminates when
* all recorded histogram values are exhausted.
*/
declare class RecordedValuesIterator extends JsHistogramIterator {
visitedIndex: number;
/**
* @param histogram The histogram this iterator will operate on
*/
constructor(histogram: JsHistogram);
/**
* Reset iterator for re-use in a fresh iteration over the same histogram data set.
*/
reset(): void;
private doReset;
incrementIterationLevel(): void;
reachedIterationLevel(): boolean;
}
export default RecordedValuesIterator;

View file

@ -0,0 +1,43 @@
"use strict";
/*
* 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/
*/
Object.defineProperty(exports, "__esModule", { value: true });
const JsHistogramIterator_1 = require("./JsHistogramIterator");
/**
* Used for iterating through all recorded histogram values using the finest granularity steps supported by the
* underlying representation. The iteration steps through all non-zero recorded value counts, and terminates when
* all recorded histogram values are exhausted.
*/
class RecordedValuesIterator extends JsHistogramIterator_1.default {
/**
* @param histogram The histogram this iterator will operate on
*/
constructor(histogram) {
super();
this.doReset(histogram);
}
/**
* Reset iterator for re-use in a fresh iteration over the same histogram data set.
*/
reset() {
this.doReset(this.histogram);
}
doReset(histogram) {
super.resetIterator(histogram);
this.visitedIndex = -1;
}
incrementIterationLevel() {
this.visitedIndex = this.currentIndex;
}
reachedIterationLevel() {
const currentCount = this.histogram.getCountAtIndex(this.currentIndex);
return currentCount != 0 && this.visitedIndex !== this.currentIndex;
}
}
exports.default = RecordedValuesIterator;
//# sourceMappingURL=RecordedValuesIterator.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"RecordedValuesIterator.js","sourceRoot":"","sources":["../src/RecordedValuesIterator.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAGH,+DAAwD;AAExD;;;;GAIG;AACH,MAAM,sBAAuB,SAAQ,6BAAmB;IAGtD;;OAEG;IACH,YAAY,SAAsB;QAChC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC1B,CAAC;IAED;;OAEG;IACI,KAAK;QACV,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;IAEO,OAAO,CAAC,SAAsB;QACpC,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAC/B,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;IACzB,CAAC;IAED,uBAAuB;QACrB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;IACxC,CAAC;IAED,qBAAqB;QACnB,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACvE,OAAO,YAAY,IAAI,CAAC,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,YAAY,CAAC;IACtE,CAAC;CACF;AAED,kBAAe,sBAAsB,CAAC"}

View file

@ -0,0 +1 @@
export {};

View file

@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const RecordedValuesIterator_1 = require("./RecordedValuesIterator");
const Int32Histogram_1 = require("./Int32Histogram");
describe("Recorded Values Iterator", () => {
it("should iterate to recorded value", () => {
// given
const histogram = new Int32Histogram_1.default(1, Number.MAX_SAFE_INTEGER, 2);
histogram.recordValue(123);
const iterator = new RecordedValuesIterator_1.default(histogram);
// when
const iterationValue = iterator.next();
// then
expect(iterator.hasNext()).toBe(false);
expect(iterationValue.totalCountToThisValue).toBe(1);
expect(iterationValue.totalValueToThisValue).toBe(123);
});
it("should iterate to all recorded values", () => {
// given
const histogram = new Int32Histogram_1.default(1, Number.MAX_SAFE_INTEGER, 2);
histogram.recordValue(1);
histogram.recordValue(300);
histogram.recordValue(3000);
const iterator = new RecordedValuesIterator_1.default(histogram);
// when
const values = [];
while (iterator.hasNext()) {
values.push(iterator.next().valueIteratedTo);
}
// then
expect(values).toHaveLength(3);
expect(values[0]).toBe(1);
expect(values[1]).toBeGreaterThan(300);
expect(values[2]).toBeGreaterThan(3000);
});
});
//# sourceMappingURL=RecordedValuesIterator.spec.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"RecordedValuesIterator.spec.js","sourceRoot":"","sources":["../src/RecordedValuesIterator.spec.ts"],"names":[],"mappings":";;AAAA,qEAA8D;AAC9D,qDAAyC;AAEzC,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,QAAQ;QACR,MAAM,SAAS,GAAG,IAAI,wBAAS,CAAC,CAAC,EAAE,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;QAC/D,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAC3B,MAAM,QAAQ,GAAG,IAAI,gCAAsB,CAAC,SAAS,CAAC,CAAC;QACvD,OAAO;QACP,MAAM,cAAc,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;QACvC,OAAO;QACP,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,CAAC,cAAc,CAAC,qBAAqB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,CAAC,cAAc,CAAC,qBAAqB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,QAAQ;QACR,MAAM,SAAS,GAAG,IAAI,wBAAS,CAAC,CAAC,EAAE,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;QAC/D,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QACzB,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAC3B,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,gCAAsB,CAAC,SAAS,CAAC,CAAC;QACvD,OAAO;QACP,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,OAAO,QAAQ,CAAC,OAAO,EAAE,EAAE;YACzB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,eAAe,CAAC,CAAC;SAC9C;QACD,OAAO;QACP,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}

112
my-app/node_modules/hdr-histogram-js/dist/Recorder.d.ts generated vendored Executable file
View file

@ -0,0 +1,112 @@
import Histogram from "./Histogram";
import { BuildRequest } from "./HistogramBuilder";
/**
* Records integer values, and provides stable interval {@link Histogram} samples from
* live recorded data without interrupting or stalling active recording of values. Each interval
* histogram provided contains all value counts accumulated since the previous interval histogram
* was taken.
* <p>
* This pattern is commonly used in logging interval histogram information while recording is ongoing.
* <p>
* {@link Recorder} supports concurrent
* {@link Recorder#recordValue} or
* {@link Recorder#recordValueWithExpectedInterval} calls.
*
*/
declare class Recorder {
private histogramBuildRequest;
private clock;
static idGenerator: number;
private activeHistogram;
private inactiveHistogram;
/**
* Construct an auto-resizing {@link Recorder} with a lowest discernible value of
* 1 and an auto-adjusting highestTrackableValue. Can auto-resize up to track values up to Number.MAX_SAFE_INTEGER.
*
* @param histogramBuildRequest parameters used to build histograms while using this recorder.
* @param clock (for testing purpose) an action that give current time in ms since 1970
*/
constructor(histogramBuildRequest?: BuildRequest, clock?: () => number);
/**
* Record a value in the histogram
*
* @param value The value to be recorded
* @throws may throw Error if value is exceeds highestTrackableValue
*/
recordValue(value: number): void;
/**
* Record a value in the histogram (adding to the value's current count)
*
* @param value The value to be recorded
* @param count The number of occurrences of this value to record
* @throws ArrayIndexOutOfBoundsException (may throw) if value is exceeds highestTrackableValue
*/
recordValueWithCount(value: number, count: number): void;
/**
* Record a value
* <p>
* To compensate for the loss of sampled values when a recorded value is larger than the expected
* interval between value samples, Histogram will auto-generate an additional series of decreasingly-smaller
* (down to the expectedIntervalBetweenValueSamples) value records.
* <p>
* See related notes {@link Histogram#recordValueWithExpectedInterval(long, long)}
* for more explanations about coordinated omission and expected interval correction.
* *
* @param value The value to record
* @param expectedIntervalBetweenValueSamples If expectedIntervalBetweenValueSamples is larger than 0, add
* auto-generated value records as appropriate if value is larger
* than expectedIntervalBetweenValueSamples
* @throws ArrayIndexOutOfBoundsException (may throw) if value is exceeds highestTrackableValue
*/
recordValueWithExpectedInterval(value: number, expectedIntervalBetweenValueSamples: number): void;
/**
* Get an interval histogram, which will include a stable, consistent view of all value counts
* accumulated since the last interval histogram was taken.
* <p>
* {@link Recorder#getIntervalHistogram(Histogram histogramToRecycle)
* getIntervalHistogram(histogramToRecycle)}
* accepts a previously returned interval histogram that can be recycled internally to avoid allocation
* and content copying operations, and is therefore significantly more efficient for repeated use than
* {@link Recorder#getIntervalHistogram()} and
* {@link Recorder#getIntervalHistogramInto getIntervalHistogramInto()}. The provided
* {@code histogramToRecycle} must
* be either be null or an interval histogram returned by a previous call to
* {@link Recorder#getIntervalHistogram(Histogram histogramToRecycle)
* getIntervalHistogram(histogramToRecycle)} or
* {@link Recorder#getIntervalHistogram()}.
* <p>
* NOTE: The caller is responsible for not recycling the same returned interval histogram more than once. If
* the same interval histogram instance is recycled more than once, behavior is undefined.
* <p>
* Calling {@link Recorder#getIntervalHistogram(Histogram histogramToRecycle)
* getIntervalHistogram(histogramToRecycle)} will reset the value counts, and start accumulating value
* counts for the next interval
*
* @param histogramToRecycle a previously returned interval histogram that may be recycled to avoid allocation and
* copy operations.
* @return a histogram containing the value counts accumulated since the last interval histogram was taken.
*/
getIntervalHistogram(histogramToRecycle?: Histogram): Histogram;
/**
* Place a copy of the value counts accumulated since accumulated (since the last interval histogram
* was taken) into {@code targetHistogram}.
*
* Calling {@link Recorder#getIntervalHistogramInto getIntervalHistogramInto()} will reset
* the value counts, and start accumulating value counts for the next interval.
*
* @param targetHistogram the histogram into which the interval histogram's data should be copied
*/
getIntervalHistogramInto(targetHistogram: Histogram): void;
/**
* Reset any value counts accumulated thus far.
*/
reset(): void;
private performIntervalSample;
/**
* Release memory associated to this recorder by destroying
* histograms used under the cover.
* Useful when webassembly histograms are used.
*/
destroy(): void;
}
export default Recorder;

169
my-app/node_modules/hdr-histogram-js/dist/Recorder.js generated vendored Executable file
View file

@ -0,0 +1,169 @@
"use strict";
/*
* 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/
*/
Object.defineProperty(exports, "__esModule", { value: true });
const HistogramBuilder_1 = require("./HistogramBuilder");
/**
* Records integer values, and provides stable interval {@link Histogram} samples from
* live recorded data without interrupting or stalling active recording of values. Each interval
* histogram provided contains all value counts accumulated since the previous interval histogram
* was taken.
* <p>
* This pattern is commonly used in logging interval histogram information while recording is ongoing.
* <p>
* {@link Recorder} supports concurrent
* {@link Recorder#recordValue} or
* {@link Recorder#recordValueWithExpectedInterval} calls.
*
*/
class Recorder {
/**
* Construct an auto-resizing {@link Recorder} with a lowest discernible value of
* 1 and an auto-adjusting highestTrackableValue. Can auto-resize up to track values up to Number.MAX_SAFE_INTEGER.
*
* @param histogramBuildRequest parameters used to build histograms while using this recorder.
* @param clock (for testing purpose) an action that give current time in ms since 1970
*/
constructor(histogramBuildRequest = HistogramBuilder_1.defaultRequest, clock = () => new Date().getTime()) {
this.histogramBuildRequest = histogramBuildRequest;
this.clock = clock;
this.activeHistogram = HistogramBuilder_1.build(this.histogramBuildRequest);
Recorder.idGenerator++;
this.activeHistogram.containingInstanceId = Recorder.idGenerator;
this.activeHistogram.startTimeStampMsec = clock();
}
/**
* Record a value in the histogram
*
* @param value The value to be recorded
* @throws may throw Error if value is exceeds highestTrackableValue
*/
recordValue(value) {
this.activeHistogram.recordValue(value);
}
/**
* Record a value in the histogram (adding to the value's current count)
*
* @param value The value to be recorded
* @param count The number of occurrences of this value to record
* @throws ArrayIndexOutOfBoundsException (may throw) if value is exceeds highestTrackableValue
*/
recordValueWithCount(value, count) {
this.activeHistogram.recordValueWithCount(value, count);
}
/**
* Record a value
* <p>
* To compensate for the loss of sampled values when a recorded value is larger than the expected
* interval between value samples, Histogram will auto-generate an additional series of decreasingly-smaller
* (down to the expectedIntervalBetweenValueSamples) value records.
* <p>
* See related notes {@link Histogram#recordValueWithExpectedInterval(long, long)}
* for more explanations about coordinated omission and expected interval correction.
* *
* @param value The value to record
* @param expectedIntervalBetweenValueSamples If expectedIntervalBetweenValueSamples is larger than 0, add
* auto-generated value records as appropriate if value is larger
* than expectedIntervalBetweenValueSamples
* @throws ArrayIndexOutOfBoundsException (may throw) if value is exceeds highestTrackableValue
*/
recordValueWithExpectedInterval(value, expectedIntervalBetweenValueSamples) {
this.activeHistogram.recordValueWithExpectedInterval(value, expectedIntervalBetweenValueSamples);
}
/**
* Get an interval histogram, which will include a stable, consistent view of all value counts
* accumulated since the last interval histogram was taken.
* <p>
* {@link Recorder#getIntervalHistogram(Histogram histogramToRecycle)
* getIntervalHistogram(histogramToRecycle)}
* accepts a previously returned interval histogram that can be recycled internally to avoid allocation
* and content copying operations, and is therefore significantly more efficient for repeated use than
* {@link Recorder#getIntervalHistogram()} and
* {@link Recorder#getIntervalHistogramInto getIntervalHistogramInto()}. The provided
* {@code histogramToRecycle} must
* be either be null or an interval histogram returned by a previous call to
* {@link Recorder#getIntervalHistogram(Histogram histogramToRecycle)
* getIntervalHistogram(histogramToRecycle)} or
* {@link Recorder#getIntervalHistogram()}.
* <p>
* NOTE: The caller is responsible for not recycling the same returned interval histogram more than once. If
* the same interval histogram instance is recycled more than once, behavior is undefined.
* <p>
* Calling {@link Recorder#getIntervalHistogram(Histogram histogramToRecycle)
* getIntervalHistogram(histogramToRecycle)} will reset the value counts, and start accumulating value
* counts for the next interval
*
* @param histogramToRecycle a previously returned interval histogram that may be recycled to avoid allocation and
* copy operations.
* @return a histogram containing the value counts accumulated since the last interval histogram was taken.
*/
getIntervalHistogram(histogramToRecycle) {
if (histogramToRecycle) {
const histogramToRecycleWithId = histogramToRecycle;
if (histogramToRecycleWithId.containingInstanceId !==
this.activeHistogram.containingInstanceId) {
throw "replacement histogram must have been obtained via a previous getIntervalHistogram() call from this Recorder";
}
}
this.inactiveHistogram = histogramToRecycle;
this.performIntervalSample();
const sampledHistogram = this.inactiveHistogram;
this.inactiveHistogram = null; // Once we expose the sample, we can't reuse it internally until it is recycled
return sampledHistogram;
}
/**
* Place a copy of the value counts accumulated since accumulated (since the last interval histogram
* was taken) into {@code targetHistogram}.
*
* Calling {@link Recorder#getIntervalHistogramInto getIntervalHistogramInto()} will reset
* the value counts, and start accumulating value counts for the next interval.
*
* @param targetHistogram the histogram into which the interval histogram's data should be copied
*/
getIntervalHistogramInto(targetHistogram) {
this.performIntervalSample();
if (this.inactiveHistogram) {
targetHistogram.add(this.inactiveHistogram);
targetHistogram.startTimeStampMsec = this.inactiveHistogram.startTimeStampMsec;
targetHistogram.endTimeStampMsec = this.inactiveHistogram.endTimeStampMsec;
}
}
/**
* Reset any value counts accumulated thus far.
*/
reset() {
this.activeHistogram.reset();
this.activeHistogram.startTimeStampMsec = this.clock();
}
performIntervalSample() {
if (!this.inactiveHistogram) {
this.inactiveHistogram = HistogramBuilder_1.build(this.histogramBuildRequest);
this.inactiveHistogram.containingInstanceId = this.activeHistogram.containingInstanceId;
}
this.inactiveHistogram.reset();
const tempHistogram = this.activeHistogram;
this.activeHistogram = this.inactiveHistogram;
this.inactiveHistogram = tempHistogram;
const currentTimeInMs = this.clock();
this.inactiveHistogram.endTimeStampMsec = currentTimeInMs;
this.activeHistogram.startTimeStampMsec = currentTimeInMs;
}
/**
* Release memory associated to this recorder by destroying
* histograms used under the cover.
* Useful when webassembly histograms are used.
*/
destroy() {
var _a;
this.activeHistogram.destroy();
(_a = this.inactiveHistogram) === null || _a === void 0 ? void 0 : _a.destroy();
}
}
Recorder.idGenerator = 0;
exports.default = Recorder;
//# sourceMappingURL=Recorder.js.map

1
my-app/node_modules/hdr-histogram-js/dist/Recorder.js.map generated vendored Executable file
View file

@ -0,0 +1 @@
{"version":3,"file":"Recorder.js","sourceRoot":"","sources":["../src/Recorder.ts"],"names":[],"mappings":"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"}

View file

@ -0,0 +1 @@
export {};

189
my-app/node_modules/hdr-histogram-js/dist/Recorder.spec.js generated vendored Executable file
View file

@ -0,0 +1,189 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Recorder_1 = require("./Recorder");
const Int32Histogram_1 = require("./Int32Histogram");
const PackedHistogram_1 = require("./PackedHistogram");
const wasm_1 = require("./wasm");
describe("Recorder", () => {
beforeAll(wasm_1.initWebAssembly);
it("should record value", () => {
// given
const recorder = new Recorder_1.default();
// when
recorder.recordValue(123);
// then
const histogram = recorder.getIntervalHistogram();
expect(histogram.totalCount).toBe(1);
});
it("should record value in a packed histogram", () => {
// given
const recorder = new Recorder_1.default({
numberOfSignificantValueDigits: 5,
bitBucketSize: "packed",
});
// when
recorder.recordValue(123);
// then
expect(recorder.getIntervalHistogram() instanceof PackedHistogram_1.default).toBe(true);
expect(recorder.getIntervalHistogram() instanceof PackedHistogram_1.default).toBe(true);
});
it("should record value in a WASM histogram", () => {
// given
const recorder = new Recorder_1.default({
numberOfSignificantValueDigits: 5,
bitBucketSize: "packed",
useWebAssembly: true,
});
try {
// when
recorder.recordValue(123);
// then
expect(recorder.getIntervalHistogram() instanceof wasm_1.WasmHistogram).toBe(true);
}
finally {
recorder.destroy();
}
});
it("should record value with count", () => {
// given
const recorder = new Recorder_1.default();
// when
recorder.recordValueWithCount(123, 3);
// then
const histogram = recorder.getIntervalHistogram();
expect(histogram.totalCount).toBe(3);
});
it("should record value with expected interval", () => {
// given
const recorder = new Recorder_1.default();
// when
recorder.recordValueWithExpectedInterval(223, 100);
// then
const histogram = recorder.getIntervalHistogram();
expect(histogram.totalCount).toBe(2);
});
it("should record value in a packed histogram", () => {
// given
const recorder = new Recorder_1.default({ bitBucketSize: "packed" });
recorder.recordValue(42);
// when
const histogram = recorder.getIntervalHistogram();
// then
expect(histogram instanceof PackedHistogram_1.default).toBe(true);
});
it("should record value only on one interval histogram", () => {
// given
const recorder = new Recorder_1.default();
// when
recorder.recordValue(123);
const firstHistogram = recorder.getIntervalHistogram();
// then
const secondHistogram = recorder.getIntervalHistogram();
expect(secondHistogram.totalCount).toBe(0);
});
it("should not record value on returned interval histogram", () => {
// given
const recorder = new Recorder_1.default();
const firstHistogram = recorder.getIntervalHistogram();
const secondHistogram = recorder.getIntervalHistogram();
// when
firstHistogram.recordValue(42); // should have 0 impact on recorder
const thirdHistogram = recorder.getIntervalHistogram();
// then
expect(thirdHistogram.totalCount).toBe(0);
});
it("should return interval histograms with expected significant digits", () => {
// given
const recorder = new Recorder_1.default({ numberOfSignificantValueDigits: 4 });
const firstHistogram = recorder.getIntervalHistogram();
const secondHistogram = recorder.getIntervalHistogram();
// when
const thirdHistogram = recorder.getIntervalHistogram();
// then
expect(thirdHistogram.numberOfSignificantValueDigits).toBe(4);
});
it("should return recycled histograms when asking for interval histogram", () => {
// given
const recorder = new Recorder_1.default();
const firstHistogram = recorder.getIntervalHistogram();
// when
const secondHistogram = recorder.getIntervalHistogram(firstHistogram);
const thirdHistogram = recorder.getIntervalHistogram();
// then
expect(thirdHistogram === firstHistogram).toBe(true);
});
it("should throw an error when trying to recycle an histogram not created by the recorder", () => {
// given
const recorder = new Recorder_1.default();
const somehistogram = new Int32Histogram_1.default(1, 2, 3);
// when & then
expect(() => recorder.getIntervalHistogram(somehistogram)).toThrowError();
});
it("should reset histogram when recycling", () => {
// given
const recorder = new Recorder_1.default();
recorder.recordValue(42);
const firstHistogram = recorder.getIntervalHistogram();
// when
const secondHistogram = recorder.getIntervalHistogram(firstHistogram);
const thirdHistogram = recorder.getIntervalHistogram();
// then
expect(thirdHistogram.totalCount).toBe(0);
});
it("should set timestamps on first interval histogram", () => {
// given
let currentTime = 42;
let clock = () => currentTime;
const recorder = new Recorder_1.default({}, clock);
// when
currentTime = 123;
const histogram = recorder.getIntervalHistogram();
// then
expect(histogram.startTimeStampMsec).toBe(42);
expect(histogram.endTimeStampMsec).toBe(123);
});
it("should set timestamps on any interval histogram", () => {
// given
let currentTime = 42;
let clock = () => currentTime;
const recorder = new Recorder_1.default({}, clock);
currentTime = 51;
const firstHistogram = recorder.getIntervalHistogram();
// when
currentTime = 56;
const secondHistogram = recorder.getIntervalHistogram();
// then
expect(secondHistogram.startTimeStampMsec).toBe(51);
expect(secondHistogram.endTimeStampMsec).toBe(56);
});
it("should copy interval histogram", () => {
// given
let currentTime = 42;
let clock = () => currentTime;
const recorder = new Recorder_1.default({ numberOfSignificantValueDigits: 4 }, clock);
recorder.recordValue(123);
// when
const histogram = new Int32Histogram_1.default(1, Number.MAX_SAFE_INTEGER, 3);
currentTime = 51;
recorder.getIntervalHistogramInto(histogram);
// then
expect(histogram.totalCount).toBe(1);
expect(histogram.startTimeStampMsec).toBe(42);
expect(histogram.endTimeStampMsec).toBe(51);
});
it("should reset values and timestamp", () => {
// given
let currentTime = 42;
let clock = () => currentTime;
const recorder = new Recorder_1.default({ numberOfSignificantValueDigits: 4 }, clock);
recorder.recordValue(123);
// when
currentTime = 55;
recorder.reset();
const histogram = recorder.getIntervalHistogram();
// then
expect(histogram.totalCount).toBe(0);
expect(histogram.startTimeStampMsec).toBe(55);
});
});
//# sourceMappingURL=Recorder.spec.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,23 @@
import JsHistogram from "./JsHistogram";
declare type TypedArray = ArrayLike<number> & {
readonly BYTES_PER_ELEMENT: number;
[key: number]: number;
fill(v: number): void;
set(other: TypedArray): void;
};
declare class TypedArrayHistogram extends JsHistogram {
private arrayCtr;
_counts: TypedArray;
_totalCount: number;
constructor(arrayCtr: new (size: number) => TypedArray, lowestDiscernibleValue: number, highestTrackableValue: number, numberOfSignificantValueDigits: number);
clearCounts(): void;
incrementCountAtIndex(index: number): void;
addToCountAtIndex(index: number, value: number): void;
setCountAtIndex(index: number, value: number): void;
resize(newHighestTrackableValue: number): void;
getCountAtIndex(index: number): number;
protected _getEstimatedFootprintInBytes(): number;
copyCorrectedForCoordinatedOmission(expectedIntervalBetweenValueSamples: number): TypedArrayHistogram;
toString(): string;
}
export default TypedArrayHistogram;

View file

@ -0,0 +1,66 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*
* 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/
*/
const JsHistogram_1 = require("./JsHistogram");
class TypedArrayHistogram extends JsHistogram_1.default {
constructor(arrayCtr, lowestDiscernibleValue, highestTrackableValue, numberOfSignificantValueDigits) {
super(lowestDiscernibleValue, highestTrackableValue, numberOfSignificantValueDigits);
this.arrayCtr = arrayCtr;
this._totalCount = 0;
this._counts = new arrayCtr(this.countsArrayLength);
}
clearCounts() {
this._counts.fill(0);
}
incrementCountAtIndex(index) {
const currentCount = this._counts[index];
const newCount = currentCount + 1;
if (newCount < 0) {
throw newCount + " would overflow short integer count";
}
this._counts[index] = newCount;
}
addToCountAtIndex(index, value) {
const currentCount = this._counts[index];
const newCount = currentCount + value;
if (newCount < Number.MIN_SAFE_INTEGER ||
newCount > Number.MAX_SAFE_INTEGER) {
throw newCount + " would overflow integer count";
}
this._counts[index] = newCount;
}
setCountAtIndex(index, value) {
if (value < Number.MIN_SAFE_INTEGER || value > Number.MAX_SAFE_INTEGER) {
throw value + " would overflow integer count";
}
this._counts[index] = value;
}
resize(newHighestTrackableValue) {
this.establishSize(newHighestTrackableValue);
const newCounts = new this.arrayCtr(this.countsArrayLength);
newCounts.set(this._counts);
this._counts = newCounts;
}
getCountAtIndex(index) {
return this._counts[index];
}
_getEstimatedFootprintInBytes() {
return 1024 + this._counts.BYTES_PER_ELEMENT * this._counts.length;
}
copyCorrectedForCoordinatedOmission(expectedIntervalBetweenValueSamples) {
const copy = new TypedArrayHistogram(this.arrayCtr, this.lowestDiscernibleValue, this.highestTrackableValue, this.numberOfSignificantValueDigits);
copy.addWhileCorrectingForCoordinatedOmission(this, expectedIntervalBetweenValueSamples);
return copy;
}
toString() {
return `Histogram ${this._counts.BYTES_PER_ELEMENT * 8}b ${JSON.stringify(this, null, 2)}`;
}
}
exports.default = TypedArrayHistogram;
//# sourceMappingURL=TypedArrayHistogram.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"TypedArrayHistogram.js","sourceRoot":"","sources":["../src/TypedArrayHistogram.ts"],"names":[],"mappings":";;AAAA;;;;;;GAMG;AACH,+CAAwC;AASxC,MAAM,mBAAoB,SAAQ,qBAAW;IAI3C,YACU,QAA0C,EAClD,sBAA8B,EAC9B,qBAA6B,EAC7B,8BAAsC;QAEtC,KAAK,CACH,sBAAsB,EACtB,qBAAqB,EACrB,8BAA8B,CAC/B,CAAC;QATM,aAAQ,GAAR,QAAQ,CAAkC;QAUlD,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACtD,CAAC;IAED,WAAW;QACT,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAED,qBAAqB,CAAC,KAAa;QACjC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,YAAY,GAAG,CAAC,CAAC;QAClC,IAAI,QAAQ,GAAG,CAAC,EAAE;YAChB,MAAM,QAAQ,GAAG,qCAAqC,CAAC;SACxD;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;IACjC,CAAC;IAED,iBAAiB,CAAC,KAAa,EAAE,KAAa;QAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,YAAY,GAAG,KAAK,CAAC;QACtC,IACE,QAAQ,GAAG,MAAM,CAAC,gBAAgB;YAClC,QAAQ,GAAG,MAAM,CAAC,gBAAgB,EAClC;YACA,MAAM,QAAQ,GAAG,+BAA+B,CAAC;SAClD;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;IACjC,CAAC;IAED,eAAe,CAAC,KAAa,EAAE,KAAa;QAC1C,IAAI,KAAK,GAAG,MAAM,CAAC,gBAAgB,IAAI,KAAK,GAAG,MAAM,CAAC,gBAAgB,EAAE;YACtE,MAAM,KAAK,GAAG,+BAA+B,CAAC;SAC/C;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;IAC9B,CAAC;IAED,MAAM,CAAC,wBAAgC;QACrC,IAAI,CAAC,aAAa,CAAC,wBAAwB,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC5D,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5B,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;IAC3B,CAAC;IAED,eAAe,CAAC,KAAa;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAES,6BAA6B;QACrC,OAAO,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IACrE,CAAC;IAED,mCAAmC,CACjC,mCAA2C;QAE3C,MAAM,IAAI,GAAG,IAAI,mBAAmB,CAClC,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,sBAAsB,EAC3B,IAAI,CAAC,qBAAqB,EAC1B,IAAI,CAAC,8BAA8B,CACpC,CAAC;QACF,IAAI,CAAC,wCAAwC,CAC3C,IAAI,EACJ,mCAAmC,CACpC,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,QAAQ;QACN,OAAO,aAAa,IAAI,CAAC,OAAO,CAAC,iBAAiB,GAAG,CAAC,KAAK,IAAI,CAAC,SAAS,CACvE,IAAI,EACJ,IAAI,EACJ,CAAC,CACF,EAAE,CAAC;IACN,CAAC;CACF;AAED,kBAAe,mBAAmB,CAAC"}

View file

@ -0,0 +1 @@
export {};

View file

@ -0,0 +1,65 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Int8Histogram_1 = require("./Int8Histogram");
const Int16Histogram_1 = require("./Int16Histogram");
const Int32Histogram_1 = require("./Int32Histogram");
const Float64Histogram_1 = require("./Float64Histogram");
[Int8Histogram_1.default, Int16Histogram_1.default, Int32Histogram_1.default, Float64Histogram_1.default].forEach((Histogram) => {
describe(`${Histogram} histogram`, () => {
it("should record a value", () => {
// given
const histogram = new Histogram(1, Number.MAX_SAFE_INTEGER, 3);
// when
histogram.recordValue(123456);
// then
expect(histogram.getCountAtIndex(8073)).toBe(1);
});
it("should compute median value in first bucket", () => {
// given
const histogram = new Histogram(1, Number.MAX_SAFE_INTEGER, 3);
histogram.recordValue(123456);
histogram.recordValue(127);
histogram.recordValue(42);
// when
const medianValue = histogram.getValueAtPercentile(50);
// then
expect(medianValue).toBe(127);
});
it("should compute value outside first bucket with an error less than 1000", () => {
// given
const histogram = new Histogram(1, Number.MAX_SAFE_INTEGER, 3);
histogram.recordValue(123456);
histogram.recordValue(122777);
histogram.recordValue(127);
histogram.recordValue(42);
// when
const percentileValue = histogram.getValueAtPercentile(99.9);
// then
expect(Math.abs(percentileValue - 123456)).toBeLessThan(1000);
// TODO the value is 123519 > max, ask Gil if it is a bug
});
it("should resize recording values above max", () => {
// given
const histogram = new Histogram(1, 2, 3);
histogram.autoResize = true;
// when
histogram.recordValue(123456);
histogram.recordValue(127000);
histogram.recordValue(420000);
// then
const medianValue = histogram.getValueAtPercentile(50);
expect(Math.abs(medianValue - 127000)).toBeLessThan(1000);
});
it("should compute proper value at percentile even with rounding issues", () => {
// given
const histogram = new Histogram(1, Number.MAX_SAFE_INTEGER, 3);
histogram.recordValue(1);
histogram.recordValue(2);
// when & then
expect(histogram.getValueAtPercentile(50.0)).toBe(1);
expect(histogram.getValueAtPercentile(50.00000000000001)).toBe(1);
expect(histogram.getValueAtPercentile(50.0000000000001)).toBe(2);
});
});
});
//# sourceMappingURL=TypedArrayHistogram.spec.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"TypedArrayHistogram.spec.js","sourceRoot":"","sources":["../src/TypedArrayHistogram.spec.ts"],"names":[],"mappings":"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"}

View file

@ -0,0 +1,34 @@
import ByteBuffer from "./ByteBuffer";
/**
* This class provides encoding and decoding methods for writing and reading
* ZigZag-encoded LEB128-64b9B-variant (Little Endian Base 128) values to/from a
* {@link ByteBuffer}. LEB128's variable length encoding provides for using a
* smaller nuber of bytes for smaller values, and the use of ZigZag encoding
* allows small (closer to zero) negative values to use fewer bytes. Details
* on both LEB128 and ZigZag can be readily found elsewhere.
*
* The LEB128-64b9B-variant encoding used here diverges from the "original"
* LEB128 as it extends to 64 bit values: In the original LEB128, a 64 bit
* value can take up to 10 bytes in the stream, where this variant's encoding
* of a 64 bit values will max out at 9 bytes.
*
* As such, this encoder/decoder should NOT be used for encoding or decoding
* "standard" LEB128 formats (e.g. Google Protocol Buffers).
*/
declare class ZigZagEncoding {
/**
* Writes a long value to the given buffer in LEB128 ZigZag encoded format
* (negative numbers not supported)
* @param buffer the buffer to write to
* @param value the value to write to the buffer
*/
static encode(buffer: ByteBuffer, value: number): void;
/**
* Read an LEB128-64b9B ZigZag encoded long value from the given buffer
* (negative numbers not supported)
* @param buffer the buffer to read from
* @return the value read from the buffer
*/
static decode(buffer: ByteBuffer): number;
}
export default ZigZagEncoding;

View file

@ -0,0 +1 @@
export {};

View file

@ -0,0 +1,22 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const fc = require("fast-check");
const ByteBuffer_1 = require("./ByteBuffer");
const ZigZagEncoding_1 = require("./ZigZagEncoding");
const runFromStryker = __dirname.includes("stryker");
const runnerOptions = {
numRuns: runFromStryker ? 10 : 1000,
};
describe("Zig Zag Encoding", () => {
it("should get the same number after an encoding & decoding", () => {
const buffer = ByteBuffer_1.default.allocate(8);
fc.assert(fc.property(fc.nat(Number.MAX_SAFE_INTEGER), (number) => {
buffer.resetPosition();
ZigZagEncoding_1.default.encode(buffer, number);
buffer.resetPosition();
const result = ZigZagEncoding_1.default.decode(buffer);
return number === result;
}), runnerOptions);
});
});
//# sourceMappingURL=ZigZagEncoding.fc.spec.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"ZigZagEncoding.fc.spec.js","sourceRoot":"","sources":["../src/ZigZagEncoding.fc.spec.ts"],"names":[],"mappings":";;AAAA,iCAAiC;AACjC,6CAAsC;AACtC,qDAA8C;AAE9C,MAAM,cAAc,GAAG,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AAErD,MAAM,aAAa,GAAG;IACpB,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI;CACpC,CAAC;AAEF,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,MAAM,GAAG,oBAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACtC,EAAE,CAAC,MAAM,CACP,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE;YACtD,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,wBAAc,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACtC,MAAM,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,MAAM,GAAG,wBAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC7C,OAAO,MAAM,KAAK,MAAM,CAAC;QAC3B,CAAC,CAAC,EACF,aAAa,CACd,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}

144
my-app/node_modules/hdr-histogram-js/dist/ZigZagEncoding.js generated vendored Executable file
View file

@ -0,0 +1,144 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const { pow, floor } = Math;
const TWO_POW_7 = pow(2, 7);
const TWO_POW_14 = pow(2, 14);
const TWO_POW_21 = pow(2, 21);
const TWO_POW_28 = pow(2, 28);
const TWO_POW_35 = pow(2, 35);
const TWO_POW_42 = pow(2, 42);
const TWO_POW_49 = pow(2, 49);
const TWO_POW_56 = pow(2, 56);
/**
* This class provides encoding and decoding methods for writing and reading
* ZigZag-encoded LEB128-64b9B-variant (Little Endian Base 128) values to/from a
* {@link ByteBuffer}. LEB128's variable length encoding provides for using a
* smaller nuber of bytes for smaller values, and the use of ZigZag encoding
* allows small (closer to zero) negative values to use fewer bytes. Details
* on both LEB128 and ZigZag can be readily found elsewhere.
*
* The LEB128-64b9B-variant encoding used here diverges from the "original"
* LEB128 as it extends to 64 bit values: In the original LEB128, a 64 bit
* value can take up to 10 bytes in the stream, where this variant's encoding
* of a 64 bit values will max out at 9 bytes.
*
* As such, this encoder/decoder should NOT be used for encoding or decoding
* "standard" LEB128 formats (e.g. Google Protocol Buffers).
*/
class ZigZagEncoding {
/**
* Writes a long value to the given buffer in LEB128 ZigZag encoded format
* (negative numbers not supported)
* @param buffer the buffer to write to
* @param value the value to write to the buffer
*/
static encode(buffer, value) {
if (value >= 0) {
value = value * 2;
}
else {
value = -value * 2 - 1;
}
if (value < TWO_POW_7) {
buffer.put(value);
}
else {
buffer.put(value | 0x80);
if (value < TWO_POW_14) {
buffer.put(floor(value / TWO_POW_7));
}
else {
buffer.put(floor(value / TWO_POW_7) | 0x80);
if (value < TWO_POW_21) {
buffer.put(floor(value / TWO_POW_14));
}
else {
buffer.put(floor(value / TWO_POW_14) | 0x80);
if (value < TWO_POW_28) {
buffer.put(floor(value / TWO_POW_21));
}
else {
buffer.put(floor(value / TWO_POW_21) | 0x80);
if (value < TWO_POW_35) {
buffer.put(floor(value / TWO_POW_28));
}
else {
buffer.put(floor(value / TWO_POW_28) | 0x80);
if (value < TWO_POW_42) {
buffer.put(floor(value / TWO_POW_35));
}
else {
buffer.put(floor(value / TWO_POW_35) | 0x80);
if (value < TWO_POW_49) {
buffer.put(floor(value / TWO_POW_42));
}
else {
buffer.put(floor(value / TWO_POW_42) | 0x80);
if (value < TWO_POW_56) {
buffer.put(floor(value / TWO_POW_49));
}
else {
// should not happen
buffer.put(floor(value / TWO_POW_49) + 0x80);
buffer.put(floor(value / TWO_POW_56));
}
}
}
}
}
}
}
}
}
/**
* Read an LEB128-64b9B ZigZag encoded long value from the given buffer
* (negative numbers not supported)
* @param buffer the buffer to read from
* @return the value read from the buffer
*/
static decode(buffer) {
let v = buffer.get();
let value = v & 0x7f;
if ((v & 0x80) != 0) {
v = buffer.get();
value += (v & 0x7f) * TWO_POW_7;
if ((v & 0x80) != 0) {
v = buffer.get();
value += (v & 0x7f) * TWO_POW_14;
if ((v & 0x80) != 0) {
v = buffer.get();
value += (v & 0x7f) * TWO_POW_21;
if ((v & 0x80) != 0) {
v = buffer.get();
value += (v & 0x7f) * TWO_POW_28;
if ((v & 0x80) != 0) {
v = buffer.get();
value += (v & 0x7f) * TWO_POW_35;
if ((v & 0x80) != 0) {
v = buffer.get();
value += (v & 0x7f) * TWO_POW_42;
if ((v & 0x80) != 0) {
v = buffer.get();
value += (v & 0x7f) * TWO_POW_49;
if ((v & 0x80) != 0) {
v = buffer.get();
value += (v & 0x7f) * TWO_POW_56;
}
}
}
}
}
}
}
}
if (value % 2 === 0) {
value = value / 2;
}
else {
value = -(value + 1) / 2;
}
return value;
}
}
exports.default = ZigZagEncoding;
//# sourceMappingURL=ZigZagEncoding.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"ZigZagEncoding.js","sourceRoot":"","sources":["../src/ZigZagEncoding.ts"],"names":[],"mappings":"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"}

View file

@ -0,0 +1 @@
export {};

View file

@ -0,0 +1,95 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const ByteBuffer_1 = require("./ByteBuffer");
const ZigZagEncoding_1 = require("./ZigZagEncoding");
describe("Zig Zag Encoding", () => {
it("should encode int using one byte when value is less than 64", () => {
// given
const buffer = ByteBuffer_1.default.allocate(4);
// when
ZigZagEncoding_1.default.encode(buffer, 56);
// then
expect(buffer.data).toHaveLength(4);
expect(buffer.data[0]).toBe(112);
});
it("should encode int using several bytes when value is more than 64", () => {
// given
const buffer = ByteBuffer_1.default.allocate(4);
// when
ZigZagEncoding_1.default.encode(buffer, 456);
// then
expect(buffer.data).toHaveLength(4);
expect(Array.from(buffer.data)).toEqual([144, 7, 0, 0]);
});
it("should encode negative int using several bytes when value is more than 64", () => {
// given
const buffer = ByteBuffer_1.default.allocate(4);
// when
ZigZagEncoding_1.default.encode(buffer, -456);
// then
expect(buffer.data).toHaveLength(4);
expect(Array.from(buffer.data)).toEqual([143, 7, 0, 0]);
});
it("should encode large safe int greater than 2^32", () => {
// given
const buffer = ByteBuffer_1.default.allocate(4);
// when
ZigZagEncoding_1.default.encode(buffer, Math.pow(2, 50));
// then
expect(buffer.data).toHaveLength(8);
expect(Array.from(buffer.data)).toEqual([
128,
128,
128,
128,
128,
128,
128,
4,
]);
});
it("should decode int using one byte", () => {
// given
const buffer = ByteBuffer_1.default.allocate(8);
ZigZagEncoding_1.default.encode(buffer, 56);
buffer.resetPosition();
// when
const value = ZigZagEncoding_1.default.decode(buffer);
// then
expect(value).toBe(56);
});
it("should decode int using multiple bytes", () => {
// given
const buffer = ByteBuffer_1.default.allocate(8);
ZigZagEncoding_1.default.encode(buffer, 70000);
ZigZagEncoding_1.default.encode(buffer, 56);
buffer.resetPosition();
// when
const value = ZigZagEncoding_1.default.decode(buffer);
// then
expect(value).toBe(70000);
});
it("should decode negative int using multiple bytes", () => {
// given
const buffer = ByteBuffer_1.default.allocate(8);
ZigZagEncoding_1.default.encode(buffer, -1515);
ZigZagEncoding_1.default.encode(buffer, 56);
buffer.resetPosition();
// when
const value = ZigZagEncoding_1.default.decode(buffer);
// then
expect(value).toBe(-1515);
});
it("should decode large safe int greater than 2^32", () => {
// given
const buffer = ByteBuffer_1.default.allocate(4);
ZigZagEncoding_1.default.encode(buffer, Math.pow(2, 50) + 1234);
ZigZagEncoding_1.default.encode(buffer, 56);
buffer.resetPosition();
// when
const value = ZigZagEncoding_1.default.decode(buffer);
// then
expect(value).toBe(Math.pow(2, 50) + 1234);
});
});
//# sourceMappingURL=ZigZagEncoding.spec.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"ZigZagEncoding.spec.js","sourceRoot":"","sources":["../src/ZigZagEncoding.spec.ts"],"names":[],"mappings":"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"}

View file

@ -0,0 +1 @@
export {};

View file

@ -0,0 +1,57 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const benny_1 = require("benny");
const index_1 = require("../index");
const wasm_1 = require("../wasm");
wasm_1.initWebAssembly().then(() => {
const randomInteger = (max = Number.MAX_SAFE_INTEGER) => Math.floor(Math.random() * max);
const options = { initCount: 1000 };
benny_1.default.suite("Histogram add", benny_1.default.add("Int32Histogram", () => {
const histogram = index_1.build();
const histogram2 = index_1.build();
for (let index = 0; index < 1024; index++) {
histogram.recordValueWithCount(randomInteger(), randomInteger(100));
histogram2.recordValueWithCount(randomInteger(), randomInteger(100));
}
return () => {
histogram.add(histogram2);
};
}, options), benny_1.default.add("WASM 32B Histogram", () => {
const histogram = index_1.build({ useWebAssembly: true });
const histogram2 = index_1.build({ useWebAssembly: true });
for (let index = 0; index < 1024; index++) {
histogram.recordValueWithCount(randomInteger(), randomInteger(100));
histogram2.recordValueWithCount(randomInteger(), randomInteger(100));
}
return () => {
histogram.add(histogram2);
};
}, options), benny_1.default.add("Packed Histogram", () => {
const histogram = index_1.build({ bitBucketSize: "packed" });
const histogram2 = index_1.build({ bitBucketSize: "packed" });
for (let index = 0; index < 1024; index++) {
histogram.recordValueWithCount(randomInteger(), randomInteger(100));
histogram2.recordValueWithCount(randomInteger(), randomInteger(100));
}
return () => {
histogram.add(histogram2);
};
}, options), benny_1.default.add("WASM Packed Histogram", () => {
const histogram = index_1.build({
bitBucketSize: "packed",
useWebAssembly: true
});
const histogram2 = index_1.build({
bitBucketSize: "packed",
useWebAssembly: true
});
for (let index = 0; index < 1024; index++) {
histogram.recordValueWithCount(randomInteger(), randomInteger(100));
histogram2.recordValueWithCount(randomInteger(), randomInteger(100));
}
return () => {
histogram.add(histogram2);
};
}, options), benny_1.default.complete(), benny_1.default.save({ file: "add", format: "chart.html" }));
});
//# sourceMappingURL=histogram-add.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"histogram-add.js","sourceRoot":"","sources":["../../src/bench/histogram-add.ts"],"names":[],"mappings":"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"}

View file

@ -0,0 +1 @@
export {};

Some files were not shown because too many files have changed in this diff Show more