source: trip-planner-front/node_modules/hdr-histogram-js/src/Recorder.ts@ ceaed42

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

initial commit

  • Property mode set to 100644
File size: 7.9 KB
Line 
1/*
2 * This is a TypeScript 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 Histogram from "./Histogram";
10import { build, BuildRequest, defaultRequest } from "./HistogramBuilder";
11
12interface HistogramWithId extends Histogram {
13 containingInstanceId?: number;
14}
15
16/**
17 * Records integer values, and provides stable interval {@link Histogram} samples from
18 * live recorded data without interrupting or stalling active recording of values. Each interval
19 * histogram provided contains all value counts accumulated since the previous interval histogram
20 * was taken.
21 * <p>
22 * This pattern is commonly used in logging interval histogram information while recording is ongoing.
23 * <p>
24 * {@link Recorder} supports concurrent
25 * {@link Recorder#recordValue} or
26 * {@link Recorder#recordValueWithExpectedInterval} calls.
27 *
28 */
29class Recorder {
30 static idGenerator = 0;
31 private activeHistogram: HistogramWithId;
32 private inactiveHistogram: HistogramWithId | null | undefined;
33
34 /**
35 * Construct an auto-resizing {@link Recorder} with a lowest discernible value of
36 * 1 and an auto-adjusting highestTrackableValue. Can auto-resize up to track values up to Number.MAX_SAFE_INTEGER.
37 *
38 * @param histogramBuildRequest parameters used to build histograms while using this recorder.
39 * @param clock (for testing purpose) an action that give current time in ms since 1970
40 */
41 constructor(
42 private histogramBuildRequest: BuildRequest = defaultRequest,
43 private clock = () => new Date().getTime()
44 ) {
45 this.activeHistogram = build(this.histogramBuildRequest);
46
47 Recorder.idGenerator++;
48 this.activeHistogram.containingInstanceId = Recorder.idGenerator;
49 this.activeHistogram.startTimeStampMsec = clock();
50 }
51
52 /**
53 * Record a value in the histogram
54 *
55 * @param value The value to be recorded
56 * @throws may throw Error if value is exceeds highestTrackableValue
57 */
58 recordValue(value: number) {
59 this.activeHistogram.recordValue(value);
60 }
61
62 /**
63 * Record a value in the histogram (adding to the value's current count)
64 *
65 * @param value The value to be recorded
66 * @param count The number of occurrences of this value to record
67 * @throws ArrayIndexOutOfBoundsException (may throw) if value is exceeds highestTrackableValue
68 */
69 recordValueWithCount(value: number, count: number) {
70 this.activeHistogram.recordValueWithCount(value, count);
71 }
72
73 /**
74 * Record a value
75 * <p>
76 * To compensate for the loss of sampled values when a recorded value is larger than the expected
77 * interval between value samples, Histogram will auto-generate an additional series of decreasingly-smaller
78 * (down to the expectedIntervalBetweenValueSamples) value records.
79 * <p>
80 * See related notes {@link Histogram#recordValueWithExpectedInterval(long, long)}
81 * for more explanations about coordinated omission and expected interval correction.
82 * *
83 * @param value The value to record
84 * @param expectedIntervalBetweenValueSamples If expectedIntervalBetweenValueSamples is larger than 0, add
85 * auto-generated value records as appropriate if value is larger
86 * than expectedIntervalBetweenValueSamples
87 * @throws ArrayIndexOutOfBoundsException (may throw) if value is exceeds highestTrackableValue
88 */
89 recordValueWithExpectedInterval(
90 value: number,
91 expectedIntervalBetweenValueSamples: number
92 ) {
93 this.activeHistogram.recordValueWithExpectedInterval(
94 value,
95 expectedIntervalBetweenValueSamples
96 );
97 }
98
99 /**
100 * Get an interval histogram, which will include a stable, consistent view of all value counts
101 * accumulated since the last interval histogram was taken.
102 * <p>
103 * {@link Recorder#getIntervalHistogram(Histogram histogramToRecycle)
104 * getIntervalHistogram(histogramToRecycle)}
105 * accepts a previously returned interval histogram that can be recycled internally to avoid allocation
106 * and content copying operations, and is therefore significantly more efficient for repeated use than
107 * {@link Recorder#getIntervalHistogram()} and
108 * {@link Recorder#getIntervalHistogramInto getIntervalHistogramInto()}. The provided
109 * {@code histogramToRecycle} must
110 * be either be null or an interval histogram returned by a previous call to
111 * {@link Recorder#getIntervalHistogram(Histogram histogramToRecycle)
112 * getIntervalHistogram(histogramToRecycle)} or
113 * {@link Recorder#getIntervalHistogram()}.
114 * <p>
115 * NOTE: The caller is responsible for not recycling the same returned interval histogram more than once. If
116 * the same interval histogram instance is recycled more than once, behavior is undefined.
117 * <p>
118 * Calling {@link Recorder#getIntervalHistogram(Histogram histogramToRecycle)
119 * getIntervalHistogram(histogramToRecycle)} will reset the value counts, and start accumulating value
120 * counts for the next interval
121 *
122 * @param histogramToRecycle a previously returned interval histogram that may be recycled to avoid allocation and
123 * copy operations.
124 * @return a histogram containing the value counts accumulated since the last interval histogram was taken.
125 */
126 getIntervalHistogram(histogramToRecycle?: Histogram): Histogram {
127 if (histogramToRecycle) {
128 const histogramToRecycleWithId: HistogramWithId = histogramToRecycle;
129 if (
130 histogramToRecycleWithId.containingInstanceId !==
131 this.activeHistogram.containingInstanceId
132 ) {
133 throw "replacement histogram must have been obtained via a previous getIntervalHistogram() call from this Recorder";
134 }
135 }
136
137 this.inactiveHistogram = histogramToRecycle;
138 this.performIntervalSample();
139 const sampledHistogram = this.inactiveHistogram;
140 this.inactiveHistogram = null; // Once we expose the sample, we can't reuse it internally until it is recycled
141 return sampledHistogram as Histogram;
142 }
143
144 /**
145 * Place a copy of the value counts accumulated since accumulated (since the last interval histogram
146 * was taken) into {@code targetHistogram}.
147 *
148 * Calling {@link Recorder#getIntervalHistogramInto getIntervalHistogramInto()} will reset
149 * the value counts, and start accumulating value counts for the next interval.
150 *
151 * @param targetHistogram the histogram into which the interval histogram's data should be copied
152 */
153 getIntervalHistogramInto(targetHistogram: Histogram) {
154 this.performIntervalSample();
155 if (this.inactiveHistogram) {
156 targetHistogram.add(this.inactiveHistogram);
157 targetHistogram.startTimeStampMsec = this.inactiveHistogram.startTimeStampMsec;
158 targetHistogram.endTimeStampMsec = this.inactiveHistogram.endTimeStampMsec;
159 }
160 }
161
162 /**
163 * Reset any value counts accumulated thus far.
164 */
165 reset() {
166 this.activeHistogram.reset();
167 this.activeHistogram.startTimeStampMsec = this.clock();
168 }
169
170 private performIntervalSample() {
171 if (!this.inactiveHistogram) {
172 this.inactiveHistogram = build(this.histogramBuildRequest);
173 this.inactiveHistogram.containingInstanceId = this.activeHistogram.containingInstanceId;
174 }
175 this.inactiveHistogram.reset();
176 const tempHistogram = this.activeHistogram;
177 this.activeHistogram = this.inactiveHistogram;
178 this.inactiveHistogram = tempHistogram;
179
180 const currentTimeInMs = this.clock();
181 this.inactiveHistogram.endTimeStampMsec = currentTimeInMs;
182 this.activeHistogram.startTimeStampMsec = currentTimeInMs;
183 }
184
185 /**
186 * Release memory associated to this recorder by destroying
187 * histograms used under the cover.
188 * Useful when webassembly histograms are used.
189 */
190 destroy() {
191 this.activeHistogram.destroy();
192 this.inactiveHistogram?.destroy();
193 }
194}
195
196export default Recorder;
Note: See TracBrowser for help on using the repository browser.