UNPKG

@pm2/io

Version:
160 lines (159 loc) 4.69 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const EDS_1 = require("../EDS"); class Histogram { constructor(opts) { this._sample = new EDS_1.default(); this._count = 0; this._sum = 0; this._varianceM = 0; this._varianceS = 0; this._ema = 0; this.used = false; opts = opts || {}; this._measurement = opts.measurement; this._callFn = null; const methods = { min: this.getMin, max: this.getMax, sum: this.getSum, count: this.getCount, variance: this._calculateVariance, mean: this._calculateMean, ema: this.getEma() }; if (methods.hasOwnProperty(this._measurement)) { this._callFn = methods[this._measurement]; } else { this._callFn = function () { const percentiles = this.percentiles([0.5, 0.75, 0.95, 0.99, 0.999]); const medians = { median: percentiles[0.5], p75: percentiles[0.75], p95: percentiles[0.95], p99: percentiles[0.99], p999: percentiles[0.999] }; return medians[this._measurement]; }; } } update(value) { this.used = true; this._count++; this._sum += value; this._sample.update(value); this._updateMin(value); this._updateMax(value); this._updateVariance(value); this._updateEma(value); } percentiles(percentiles) { const values = this._sample .toArray() .sort(function (a, b) { return (a === b) ? 0 : a - b; }); const results = {}; for (let i = 0; i < percentiles.length; i++) { const percentile = percentiles[i]; if (!values.length) { results[percentile] = null; continue; } const pos = percentile * (values.length + 1); if (pos < 1) { results[percentile] = values[0]; } else if (pos >= values.length) { results[percentile] = values[values.length - 1]; } else { const lower = values[Math.floor(pos) - 1]; const upper = values[Math.ceil(pos) - 1]; results[percentile] = lower + (pos - Math.floor(pos)) * (upper - lower); } } return results; } val() { if (typeof (this._callFn) === 'function') { return this._callFn(); } else { return this._callFn; } } getMin() { return this._min; } getMax() { return this._max; } getSum() { return this._sum; } getCount() { return this._count; } getEma() { return this._ema; } fullResults() { const percentiles = this.percentiles([0.5, 0.75, 0.95, 0.99, 0.999]); return { min: this._min, max: this._max, sum: this._sum, variance: this._calculateVariance(), mean: this._calculateMean(), count: this._count, median: percentiles[0.5], p75: percentiles[0.75], p95: percentiles[0.95], p99: percentiles[0.99], p999: percentiles[0.999], ema: this._ema }; } _updateMin(value) { if (this._min === undefined || value < this._min) { this._min = value; } } _updateMax(value) { if (this._max === undefined || value > this._max) { this._max = value; } } _updateVariance(value) { if (this._count === 1) return this._varianceM = value; const oldM = this._varianceM; this._varianceM += ((value - oldM) / this._count); this._varianceS += ((value - oldM) * (value - this._varianceM)); } _updateEma(value) { if (this._count <= 1) return this._ema = this._calculateMean(); const alpha = 2 / (1 + this._count); this._ema = value * alpha + this._ema * (1 - alpha); } _calculateMean() { return (this._count === 0) ? 0 : this._sum / this._count; } _calculateVariance() { return (this._count <= 1) ? null : this._varianceS / (this._count - 1); } isUsed() { return this.used; } } exports.default = Histogram;