Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/third_party/closure/goog/stats/basicstat.js
2868 views
1
// Copyright 2011 The Closure Library Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS-IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
/**
16
* @fileoverview A basic statistics tracker.
17
*
18
*/
19
20
goog.provide('goog.stats.BasicStat');
21
22
goog.require('goog.asserts');
23
goog.require('goog.log');
24
goog.require('goog.string.format');
25
goog.require('goog.structs.CircularBuffer');
26
27
28
29
/**
30
* Tracks basic statistics over a specified time interval.
31
*
32
* Statistics are kept in a fixed number of slots, each representing
33
* an equal portion of the time interval.
34
*
35
* Most methods optionally allow passing in the current time, so that
36
* higher level stats can synchronize operations on multiple child
37
* objects. Under normal usage, the default of goog.now() should be
38
* sufficient.
39
*
40
* @param {number} interval The stat interval, in milliseconds.
41
* @constructor
42
* @final
43
*/
44
goog.stats.BasicStat = function(interval) {
45
goog.asserts.assert(interval > 50);
46
47
/**
48
* The time interval that this statistic aggregates over.
49
* @type {number}
50
* @private
51
*/
52
this.interval_ = interval;
53
54
/**
55
* The number of milliseconds in each slot.
56
* @type {number}
57
* @private
58
*/
59
this.slotInterval_ = Math.floor(interval / goog.stats.BasicStat.NUM_SLOTS_);
60
61
/**
62
* The array of slots.
63
* @type {goog.structs.CircularBuffer}
64
* @private
65
*/
66
this.slots_ =
67
new goog.structs.CircularBuffer(goog.stats.BasicStat.NUM_SLOTS_);
68
};
69
70
71
/**
72
* The number of slots. This value limits the accuracy of the get()
73
* method to (this.interval_ / NUM_SLOTS). A 1-minute statistic would
74
* be accurate to within 2 seconds.
75
* @type {number}
76
* @private
77
*/
78
goog.stats.BasicStat.NUM_SLOTS_ = 50;
79
80
81
/**
82
* @type {goog.log.Logger}
83
* @private
84
*/
85
goog.stats.BasicStat.prototype.logger_ =
86
goog.log.getLogger('goog.stats.BasicStat');
87
88
89
/**
90
* @return {number} The interval which over statistics are being
91
* accumulated, in milliseconds.
92
*/
93
goog.stats.BasicStat.prototype.getInterval = function() {
94
return this.interval_;
95
};
96
97
98
/**
99
* Increments the count of this statistic by the specified amount.
100
*
101
* @param {number} amt The amount to increase the count by.
102
* @param {number=} opt_now The time, in milliseconds, to be treated
103
* as the "current" time. The current time must always be greater
104
* than or equal to the last time recorded by this stat tracker.
105
*/
106
goog.stats.BasicStat.prototype.incBy = function(amt, opt_now) {
107
var now = opt_now ? opt_now : goog.now();
108
this.checkForTimeTravel_(now);
109
var slot = /** @type {goog.stats.BasicStat.Slot_} */ (this.slots_.getLast());
110
if (!slot || now >= slot.end) {
111
slot = new goog.stats.BasicStat.Slot_(this.getSlotBoundary_(now));
112
this.slots_.add(slot);
113
}
114
slot.count += amt;
115
slot.min = Math.min(amt, slot.min);
116
slot.max = Math.max(amt, slot.max);
117
};
118
119
120
/**
121
* Returns the count of the statistic over its configured time
122
* interval.
123
* @param {number=} opt_now The time, in milliseconds, to be treated
124
* as the "current" time. The current time must always be greater
125
* than or equal to the last time recorded by this stat tracker.
126
* @return {number} The total count over the tracked interval.
127
*/
128
goog.stats.BasicStat.prototype.get = function(opt_now) {
129
return this.reduceSlots_(
130
opt_now, function(sum, slot) { return sum + slot.count; }, 0);
131
};
132
133
134
/**
135
* Returns the magnitute of the largest atomic increment that occurred
136
* during the watched time interval.
137
* @param {number=} opt_now The time, in milliseconds, to be treated
138
* as the "current" time. The current time must always be greater
139
* than or equal to the last time recorded by this stat tracker.
140
* @return {number} The maximum count of this statistic.
141
*/
142
goog.stats.BasicStat.prototype.getMax = function(opt_now) {
143
return this.reduceSlots_(opt_now, function(max, slot) {
144
return Math.max(max, slot.max);
145
}, Number.MIN_VALUE);
146
};
147
148
149
/**
150
* Returns the magnitute of the smallest atomic increment that
151
* occurred during the watched time interval.
152
* @param {number=} opt_now The time, in milliseconds, to be treated
153
* as the "current" time. The current time must always be greater
154
* than or equal to the last time recorded by this stat tracker.
155
* @return {number} The minimum count of this statistic.
156
*/
157
goog.stats.BasicStat.prototype.getMin = function(opt_now) {
158
return this.reduceSlots_(opt_now, function(min, slot) {
159
return Math.min(min, slot.min);
160
}, Number.MAX_VALUE);
161
};
162
163
164
/**
165
* Passes each active slot into a function and accumulates the result.
166
*
167
* @param {number|undefined} now The current time, in milliseconds.
168
* @param {function(number, goog.stats.BasicStat.Slot_): number} func
169
* The function to call for every active slot. This function
170
* takes two arguments: the previous result and the new slot to
171
* include in the reduction.
172
* @param {number} val The initial value for the reduction.
173
* @return {number} The result of the reduction.
174
* @private
175
*/
176
goog.stats.BasicStat.prototype.reduceSlots_ = function(now, func, val) {
177
now = now || goog.now();
178
this.checkForTimeTravel_(now);
179
var rval = val;
180
var start = this.getSlotBoundary_(now) - this.interval_;
181
for (var i = this.slots_.getCount() - 1; i >= 0; --i) {
182
var slot = /** @type {goog.stats.BasicStat.Slot_} */ (this.slots_.get(i));
183
if (slot.end <= start) {
184
break;
185
}
186
rval = func(rval, slot);
187
}
188
return rval;
189
};
190
191
192
/**
193
* Computes the end time for the slot that should contain the count
194
* around the given time. This method ensures that every bucket is
195
* aligned on a "this.slotInterval_" millisecond boundary.
196
* @param {number} time The time to compute a boundary for.
197
* @return {number} The computed boundary.
198
* @private
199
*/
200
goog.stats.BasicStat.prototype.getSlotBoundary_ = function(time) {
201
return this.slotInterval_ * (Math.floor(time / this.slotInterval_) + 1);
202
};
203
204
205
/**
206
* Checks that time never goes backwards. If it does (for example,
207
* the user changes their system clock), the object state is cleared.
208
* @param {number} now The current time, in milliseconds.
209
* @private
210
*/
211
goog.stats.BasicStat.prototype.checkForTimeTravel_ = function(now) {
212
var slot = /** @type {goog.stats.BasicStat.Slot_} */ (this.slots_.getLast());
213
if (slot) {
214
var slotStart = slot.end - this.slotInterval_;
215
if (now < slotStart) {
216
goog.log.warning(
217
this.logger_,
218
goog.string.format(
219
'Went backwards in time: now=%d, slotStart=%d. Resetting state.',
220
now, slotStart));
221
this.reset_();
222
}
223
}
224
};
225
226
227
/**
228
* Clears any statistics tracked by this object, as though it were
229
* freshly created.
230
* @private
231
*/
232
goog.stats.BasicStat.prototype.reset_ = function() {
233
this.slots_.clear();
234
};
235
236
237
238
/**
239
* A struct containing information for each sub-interval.
240
* @param {number} end The end time for this slot, in milliseconds.
241
* @constructor
242
* @private
243
*/
244
goog.stats.BasicStat.Slot_ = function(end) {
245
/**
246
* End time of this slot, exclusive.
247
* @type {number}
248
*/
249
this.end = end;
250
};
251
252
253
/**
254
* Aggregated count within this slot.
255
* @type {number}
256
*/
257
goog.stats.BasicStat.Slot_.prototype.count = 0;
258
259
260
/**
261
* The smallest atomic increment of the count within this slot.
262
* @type {number}
263
*/
264
goog.stats.BasicStat.Slot_.prototype.min = Number.MAX_VALUE;
265
266
267
/**
268
* The largest atomic increment of the count within this slot.
269
* @type {number}
270
*/
271
goog.stats.BasicStat.Slot_.prototype.max = Number.MIN_VALUE;
272
273