index.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. "use strict";
  2. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  3. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  4. return new (P || (P = Promise))(function (resolve, reject) {
  5. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  6. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  7. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  8. step((generator = generator.apply(thisArg, _arguments || [])).next());
  9. });
  10. };
  11. Object.defineProperty(exports, "__esModule", { value: true });
  12. exports.WasmHistogram = exports.webAssemblyReady = exports.initWebAssemblySync = exports.initWebAssembly = exports.webAssemblyAvailable = void 0;
  13. const generated_wasm_1 = require("./generated-wasm");
  14. const Histogram_1 = require("../Histogram");
  15. // @ts-ignore
  16. const base64 = require("base64-js");
  17. // @ts-ignore
  18. const pako = require("pako");
  19. // @ts-ignore
  20. const loader = require("@assemblyscript/loader");
  21. const isNode = typeof process !== "undefined" && process.version;
  22. // @ts-ignore
  23. const isWorker = typeof importScripts === "function";
  24. exports.webAssemblyAvailable = (() => {
  25. let available = false;
  26. if (isNode) {
  27. // nodejs
  28. available = "WebAssembly" in global;
  29. }
  30. else {
  31. // browser
  32. // @ts-ignore
  33. available = isWorker || "WebAssembly" in window;
  34. }
  35. return available;
  36. })();
  37. let wasm = undefined;
  38. exports.initWebAssembly = () => __awaiter(void 0, void 0, void 0, function* () {
  39. if (!exports.webAssemblyAvailable) {
  40. throw new Error("WebAssembly not available here!");
  41. }
  42. if (!!wasm) {
  43. return;
  44. }
  45. return loader
  46. .instantiate(pako.inflate(base64.toByteArray(generated_wasm_1.BINARY)))
  47. .then((w) => (wasm = w.exports || w));
  48. });
  49. exports.initWebAssemblySync = () => {
  50. if (!!wasm) {
  51. return;
  52. }
  53. const w = loader.instantiateSync(pako.inflate(base64.toByteArray(generated_wasm_1.BINARY)));
  54. wasm = w.exports || w;
  55. };
  56. exports.webAssemblyReady = () => !!wasm;
  57. const defaultRequest = {
  58. bitBucketSize: 32,
  59. autoResize: true,
  60. lowestDiscernibleValue: 1,
  61. highestTrackableValue: 2,
  62. numberOfSignificantValueDigits: 3
  63. };
  64. const remoteHistogramClassFor = (size) => size === "packed" ? "PackedHistogram" : `Histogram${size}`;
  65. const destroyedWasmHistogram = new Proxy({}, {
  66. get: function (obj, prop) {
  67. throw new Error("Cannot use a destroyed histogram");
  68. }
  69. });
  70. class WasmHistogram {
  71. constructor(_wasmHistogram, _remoteHistogramClass) {
  72. this._wasmHistogram = _wasmHistogram;
  73. this._remoteHistogramClass = _remoteHistogramClass;
  74. this.tag = Histogram_1.NO_TAG;
  75. }
  76. static build(request = defaultRequest) {
  77. if (!exports.webAssemblyReady()) {
  78. throw new Error("WebAssembly is not ready yet!");
  79. }
  80. const parameters = Object.assign({}, defaultRequest, request);
  81. const remoteHistogramClass = remoteHistogramClassFor(parameters.bitBucketSize);
  82. return new WasmHistogram(new wasm[remoteHistogramClass](parameters.lowestDiscernibleValue, parameters.highestTrackableValue, parameters.numberOfSignificantValueDigits, parameters.autoResize), remoteHistogramClass);
  83. }
  84. static decode(data, bitBucketSize = 32, minBarForHighestTrackableValue = 0) {
  85. if (!exports.webAssemblyReady()) {
  86. throw new Error("WebAssembly is not ready yet!");
  87. }
  88. const remoteHistogramClass = remoteHistogramClassFor(bitBucketSize);
  89. const decodeFunc = `decode${remoteHistogramClass}`;
  90. const ptrArr = wasm.__retain(wasm.__allocArray(wasm.UINT8ARRAY_ID, data));
  91. const wasmHistogram = new WasmHistogram(wasm[remoteHistogramClass].wrap(wasm[decodeFunc](ptrArr, minBarForHighestTrackableValue)), remoteHistogramClass);
  92. wasm.__release(ptrArr);
  93. return wasmHistogram;
  94. }
  95. get numberOfSignificantValueDigits() {
  96. return this._wasmHistogram.numberOfSignificantValueDigits;
  97. }
  98. get autoResize() {
  99. return !!this._wasmHistogram.autoResize;
  100. }
  101. set autoResize(resize) {
  102. this._wasmHistogram.autoResize = resize;
  103. }
  104. get highestTrackableValue() {
  105. return this._wasmHistogram.highestTrackableValue;
  106. }
  107. set highestTrackableValue(value) {
  108. this._wasmHistogram.highestTrackableValue = value;
  109. }
  110. get startTimeStampMsec() {
  111. return this._wasmHistogram.startTimeStampMsec;
  112. }
  113. set startTimeStampMsec(value) {
  114. this._wasmHistogram.startTimeStampMsec = value;
  115. }
  116. get endTimeStampMsec() {
  117. return this._wasmHistogram.endTimeStampMsec;
  118. }
  119. set endTimeStampMsec(value) {
  120. this._wasmHistogram.endTimeStampMsec = value;
  121. }
  122. get totalCount() {
  123. return this._wasmHistogram.totalCount;
  124. }
  125. get stdDeviation() {
  126. return this._wasmHistogram.stdDeviation;
  127. }
  128. get mean() {
  129. return this._wasmHistogram.mean;
  130. }
  131. get estimatedFootprintInBytes() {
  132. return 192 + this._wasmHistogram.estimatedFootprintInBytes;
  133. }
  134. get minNonZeroValue() {
  135. return this._wasmHistogram.minNonZeroValue;
  136. }
  137. get maxValue() {
  138. return this._wasmHistogram.maxValue;
  139. }
  140. recordValue(value) {
  141. this._wasmHistogram.recordValue(value);
  142. }
  143. recordValueWithCount(value, count) {
  144. this._wasmHistogram.recordValueWithCount(value, count);
  145. }
  146. recordValueWithExpectedInterval(value, expectedIntervalBetweenValueSamples) {
  147. this._wasmHistogram.recordValueWithExpectedInterval(value, expectedIntervalBetweenValueSamples);
  148. }
  149. getValueAtPercentile(percentile) {
  150. return this._wasmHistogram.getValueAtPercentile(percentile);
  151. }
  152. outputPercentileDistribution(percentileTicksPerHalfDistance = 5, outputValueUnitScalingRatio = 1, useCsvFormat = false) {
  153. // TODO csv
  154. if (useCsvFormat) {
  155. throw new Error("CSV output not supported by wasm histograms");
  156. }
  157. return wasm.__getString(this._wasmHistogram.outputPercentileDistribution(percentileTicksPerHalfDistance, outputValueUnitScalingRatio));
  158. }
  159. isDestroyed() {
  160. return this._wasmHistogram === destroyedWasmHistogram;
  161. }
  162. get summary() {
  163. return Histogram_1.toSummary(this);
  164. }
  165. toJSON() {
  166. return this.summary;
  167. }
  168. toString() {
  169. if (this.isDestroyed()) {
  170. return "Destroyed WASM histogram";
  171. }
  172. return `WASM ${this._remoteHistogramClass} ${JSON.stringify(this, null, 2)}`;
  173. }
  174. inspect() {
  175. return this.toString();
  176. }
  177. [Symbol.for("nodejs.util.inspect.custom")]() {
  178. return this.toString();
  179. }
  180. addWhileCorrectingForCoordinatedOmission(otherHistogram, expectedIntervalBetweenValueSamples) {
  181. this._wasmHistogram.addWhileCorrectingForCoordinatedOmission(otherHistogram, expectedIntervalBetweenValueSamples);
  182. }
  183. copyCorrectedForCoordinatedOmission(expectedIntervalBetweenValueSamples) {
  184. return new WasmHistogram(wasm[this._remoteHistogramClass].wrap(this._wasmHistogram.copyCorrectedForCoordinatedOmission(expectedIntervalBetweenValueSamples)), this._remoteHistogramClass);
  185. }
  186. add(otherHistogram) {
  187. if (!(otherHistogram instanceof WasmHistogram)) {
  188. // should be impossible to be in this situation but actually
  189. // TypeScript has some flaws...
  190. throw new Error("Cannot add a regular JS histogram to a WASM histogram");
  191. }
  192. this._wasmHistogram[`add${otherHistogram._remoteHistogramClass}`](otherHistogram._wasmHistogram);
  193. }
  194. subtract(otherHistogram) {
  195. if (!(otherHistogram instanceof WasmHistogram)) {
  196. // should be impossible to be in this situation but actually
  197. // TypeScript has some flaws...
  198. throw new Error("Cannot subtract a regular JS histogram to a WASM histogram");
  199. }
  200. this._wasmHistogram[`subtract${otherHistogram._remoteHistogramClass}`](otherHistogram._wasmHistogram);
  201. }
  202. encode() {
  203. const ptrArray = this._wasmHistogram.encode();
  204. const array = wasm.__getUint8Array(ptrArray);
  205. wasm.__release(ptrArray);
  206. return array;
  207. }
  208. reset() {
  209. this.tag = Histogram_1.NO_TAG;
  210. this._wasmHistogram.reset();
  211. }
  212. destroy() {
  213. wasm.__release(this._wasmHistogram);
  214. this._wasmHistogram = destroyedWasmHistogram;
  215. }
  216. }
  217. exports.WasmHistogram = WasmHistogram;
  218. //# sourceMappingURL=index.js.map