source: trip-planner-front/node_modules/hdr-histogram-js/assembly/__tests__/Histogram.spec.ts

Last change on this file was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 11.2 KB
Line 
1/*
2 * This is a AssemblyScript port of the original Java version, which was written by
3 * Gil Tene as described in
4 * https://github.com/HdrHistogram/HdrHistogram
5 * and released to the public domain, as explained at
6 * http://creativecommons.org/publicdomain/zero/1.0/
7 */
8
9import {
10 Histogram8,
11 Histogram16,
12 Storage,
13 PackedHistogram,
14 Histogram64,
15} from "../Histogram";
16
17const buildHistogram = (): Histogram8 =>
18 new Histogram8(
19 1,
20 9007199254740991, // Number.MAX_SAFE_INTEGER
21 3
22 );
23
24describe("Histogram", () => {
25 it("should be instantiable", () => {
26 const h = buildHistogram();
27 h.autoResize;
28 expect<bool>(h.autoResize).toBe(false);
29 });
30});
31
32describe("Histogram initialization", () => {
33 it("should set sub bucket size", () => {
34 const histogram: Histogram8 = buildHistogram();
35 expect<u64>(histogram.subBucketCount).toBe(2048);
36 });
37
38 it("should set resize to false when max value specified", () => {
39 const histogram: Histogram8 = buildHistogram();
40 expect<bool>(histogram.autoResize).toBe(false);
41 });
42
43 it("should compute counts array length", () => {
44 const histogram: Histogram8 = buildHistogram();
45 expect<usize>(histogram.countsArrayLength).toBe(45056);
46 });
47 it("should compute bucket count", () => {
48 const histogram: Histogram8 = buildHistogram();
49 expect(histogram.bucketCount).toBe(43);
50 });
51
52 it("should set max value", () => {
53 const histogram: Histogram8 = buildHistogram();
54 expect(histogram.maxValue).toBe(0);
55 });
56});
57
58describe("Histogram internal indexes", () => {
59 it("should compute count index when value in first bucket", () => {
60 // given
61 const histogram: Histogram8 = buildHistogram();
62 // when
63 const index = histogram.countsArrayIndex(2000); // 2000 < 2048
64 expect(index).toBe(2000);
65 });
66
67 it("should compute count index when value outside first bucket", () => {
68 // given
69 const histogram: Histogram8 = buildHistogram();
70 // when
71 const index = histogram.countsArrayIndex(2050); // 2050 > 2048
72 // then
73 expect(index).toBe(2049);
74 });
75
76 it("should compute count index taking into account lowest discernible value", () => {
77 // given
78 const histogram = new Histogram8(
79 2000,
80 9007199254740991, // Number.MAX_SAFE_INTEGER
81 2
82 );
83 // when
84 const index = histogram.countsArrayIndex(16000);
85 // then
86 expect(index).toBe(15);
87 });
88});
89
90describe("Histogram computing statistics", () => {
91 it("should compute mean value", () => {
92 // given
93 const histogram = buildHistogram();
94 // when
95 histogram.recordValue(25);
96 histogram.recordValue(50);
97 histogram.recordValue(75);
98 // then
99 expect<f64>(histogram.getMean()).toBe(50);
100 });
101
102 it("should compute standard deviation", () => {
103 // given
104 const histogram = buildHistogram();
105 // when
106 histogram.recordValue(25);
107 histogram.recordValue(50);
108 histogram.recordValue(75);
109 // then
110 expect<f64>(histogram.getStdDeviation()).toBeGreaterThan(20.4124);
111 expect<f64>(histogram.getStdDeviation()).toBeLessThan(20.4125);
112 });
113
114 it("should compute percentiles", () => {
115 // given
116 const histogram = buildHistogram();
117 histogram.recordValue(123456);
118 histogram.recordValue(122777);
119 histogram.recordValue(127);
120 histogram.recordValue(42);
121 // when
122 const percentileValue = histogram.getValueAtPercentile(99.9);
123 // then
124 expect<u64>(percentileValue).toBeGreaterThan(123456 - 1000);
125 expect<u64>(percentileValue).toBeLessThan(123456 + 1000);
126 });
127
128 it("should compute max value", () => {
129 // given
130 const histogram = buildHistogram();
131 // when
132 histogram.recordValue(123);
133 // then
134 expect<u64>(histogram.maxValue).toBe(123);
135 });
136
137 it("should compute min non zero value", () => {
138 // given
139 const histogram = buildHistogram();
140 // when
141 histogram.recordValue(123);
142 // then
143 expect<u64>(histogram.minNonZeroValue).toBe(123);
144 });
145
146 it("should compute percentile distribution", () => {
147 // given
148 const histogram = buildHistogram();
149 // when
150 histogram.recordValue(25);
151 histogram.recordValue(50);
152 histogram.recordValue(75);
153 // then
154 const expectedResult = ` Value Percentile TotalCount 1/(1-Percentile)
155
156 25.000 0.000000000000 1 1.00
157 25.000 0.100000000000 1 1.11
158 25.000 0.200000000000 1 1.25
159 25.000 0.300000000000 1 1.43
160 50.000 0.400000000000 2 1.67
161 50.000 0.500000000000 2 2.00
162 50.000 0.550000000000 2 2.22
163 50.000 0.600000000000 2 2.50
164 50.000 0.650000000000 2 2.86
165 75.000 0.700000000000 3 3.33
166 75.000 1.000000000000 3
167#[Mean = 50.000, StdDeviation = 20.412]
168#[Max = 75.000, Total count = 3]
169#[Buckets = 43, SubBuckets = 2048]
170`;
171 expect<string>(histogram.outputPercentileDistribution()).toBe(
172 expectedResult
173 );
174 });
175});
176
177describe("Histogram resize", () => {
178 it("should not crash when autoresize on and value bigger than max", () => {
179 expect(() => {
180 // given
181 const histogram = new Histogram8(1, 4096, 3);
182 histogram.autoResize = true;
183 // when
184 histogram.recordValue(900000);
185 // then
186 expect<u64>(histogram.totalCount).toBe(1);
187 }).not.toThrow();
188 });
189
190 it("should compute percentiles after resize", () => {
191 // given
192 const histogram = new Histogram8(1, 4096, 3);
193 histogram.autoResize = true;
194 // when
195 histogram.recordValue(900000);
196 histogram.recordValue(9000000);
197 histogram.recordValue(9000000);
198 histogram.recordValue(90000000);
199 // then
200 const medianValue = histogram.getValueAtPercentile(50);
201 expect<f64>(Math.floor(<f64>medianValue / <f64>10000)).toBe(900);
202 });
203
204 it("should update highest trackable value when resizing", () => {
205 // given
206 const histogram = new Histogram8(1, 4096, 3);
207 histogram.autoResize = true;
208 // when
209 histogram.recordValue(9000);
210 // then
211 expect(histogram.highestTrackableValue).toBeGreaterThan(4096);
212 });
213});
214
215describe("Histogram clearing support", () => {
216 it("should reset data in order to reuse histogram", () => {
217 // given
218 const histogram = buildHistogram();
219 histogram.startTimeStampMsec = 42;
220 histogram.endTimeStampMsec = 56;
221 histogram.tag = "blabla";
222 histogram.recordValue(1000);
223 // when
224 histogram.reset();
225 // then
226 expect(histogram.totalCount).toBe(0);
227 expect(histogram.startTimeStampMsec).toBe(0);
228 expect(histogram.endTimeStampMsec).toBe(0);
229 //expect(histogram.tag).toBe(NO_TAG);
230 expect(histogram.maxValue).toBe(0);
231 expect(histogram.minNonZeroValue).toBe(U64.MAX_VALUE);
232 expect(histogram.getValueAtPercentile(99.999)).toBe(0);
233 });
234});
235
236describe("Histogram correcting coordinated omissions", () => {
237 it("should generate additional values when recording", () => {
238 // given
239 const histogram = buildHistogram();
240 // when
241 histogram.recordSingleValueWithExpectedInterval(200, 100);
242 // then
243 expect(histogram.totalCount).toBe(2);
244 expect(histogram.minNonZeroValue).toBe(100);
245 expect(histogram.maxValue).toBe(200);
246 });
247
248 it("should not generate additional values when recording without ommission", () => {
249 // given
250 const histogram = buildHistogram();
251 // when
252 histogram.recordSingleValueWithExpectedInterval(99, 100);
253 // then
254 expect(histogram.totalCount).toBe(1);
255 });
256
257 it("should generate additional values when correcting after recording", () => {
258 // given
259 const histogram = buildHistogram();
260 histogram.recordValue(207);
261 histogram.recordValue(207);
262 // when
263 const correctedHistogram = histogram.copyCorrectedForCoordinatedOmission(
264 100
265 );
266 // then
267 expect(correctedHistogram.totalCount).toBe(4);
268 expect(correctedHistogram.minNonZeroValue).toBe(107);
269 expect(correctedHistogram.maxValue).toBe(207);
270 });
271
272 it("should generate additional values when correcting after recording bis", () => {
273 // given
274 const histogram = buildHistogram();
275 histogram.recordValue(207);
276 histogram.recordValue(207);
277 // when
278 const correctedHistogram = histogram.copyCorrectedForCoordinatedOmission(
279 1000
280 );
281 // then
282 expect(correctedHistogram.totalCount).toBe(2);
283 expect(correctedHistogram.minNonZeroValue).toBe(207);
284 expect(correctedHistogram.maxValue).toBe(207);
285 });
286});
287
288describe("Histogram add & subtract", () => {
289 it("should add histograms of same size", () => {
290 // given
291 const histogram = buildHistogram();
292 const histogram2 = new Histogram16(1, 256, 3);
293 histogram.recordValue(42);
294 histogram2.recordValue(158);
295 // testwhen
296 histogram.add<Storage<Uint16Array, u16>, u16>(histogram2);
297 // then
298 expect(histogram.totalCount).toBe(2);
299 expect(histogram.getMean()).toBe(100);
300 });
301
302 it("should add histograms of different sizes & precisions", () => {
303 // given
304 const histogram = buildHistogram();
305 const histogram2 = new Histogram16(1, 1024, 3);
306 histogram2.autoResize = true;
307 histogram.recordValue(42000);
308 histogram2.recordValue(1000);
309 // when
310 histogram.add<Storage<Uint16Array, u16>, u16>(histogram2);
311 // then
312 expect(histogram.totalCount).toBe(2);
313 expect(Math.floor(histogram.getMean() / 100)).toBe(215);
314 });
315
316 it("should be equal when another histogram is added then subtracted with same characteristics", () => {
317 // given
318 const histogram = buildHistogram();
319 const histogram2 = buildHistogram();
320 histogram.recordCountAtValue(2, 100);
321 histogram2.recordCountAtValue(1, 100);
322 histogram.recordCountAtValue(2, 200);
323 histogram2.recordCountAtValue(1, 200);
324 histogram.recordCountAtValue(2, 300);
325 histogram2.recordCountAtValue(1, 300);
326 const outputBefore = histogram.outputPercentileDistribution();
327 // when
328 histogram.add<Storage<Uint8Array, u8>, u8>(histogram2);
329 histogram.subtract<Storage<Uint8Array, u8>, u8>(histogram2);
330 // then
331 expect(histogram.outputPercentileDistribution()).toBe(outputBefore);
332 });
333
334 it("should be equal when another histogram of lower precision is added then subtracted", () => {
335 // given
336 const histogram = new Histogram8(1, 1000000000, 5);
337 const histogram2 = new Histogram8(1, 1000000000, 3);
338 histogram.recordValue(10);
339 histogram2.recordValue(100000);
340 // when
341 const outputBefore = histogram.outputPercentileDistribution();
342 histogram.add<Storage<Uint8Array, u8>, u8>(histogram2);
343 histogram.subtract<Storage<Uint8Array, u8>, u8>(histogram2);
344 // then
345 expect(histogram.outputPercentileDistribution()).toBe(outputBefore);
346 });
347});
348
349describe("Packed Histogram", () => {
350 it("should compute percentiles as the non packed version", () => {
351 // given
352 const packedHistogram = new PackedHistogram(
353 1,
354 9007199254740991, // Number.MAX_SAFE_INTEGER
355 3
356 );
357 const histogram = new Histogram64(
358 1,
359 9007199254740991, // Number.MAX_SAFE_INTEGER
360 3
361 );
362
363 // when
364 histogram.recordValue(2199023255552);
365 packedHistogram.recordValue(2199023255552);
366
367 // then
368 expect<u64>(packedHistogram.getValueAtPercentile(90)).toBe(
369 histogram.getValueAtPercentile(90)
370 );
371 });
372});
Note: See TracBrowser for help on using the repository browser.