JSFiddle - React, Tailwind, and code Playground
by IceCreamYou
JavaScript
// TODO: docs, tests
function HitCounter() {
this.hits = [];
this.lastTimestamp = -1;
}
HitCounter.prototype.getTimestamp = function() {
return Math.floor(Date.now() / 1000);
};
HitCounter.prototype.hit = function() {
var now = this.getTimestamp();
if (now !== this.lastTimestamp) {
this.hits.unshift({ hits: 1, timestamp: now });
this.lastTimestamp = now;
if (this.hits.length > 300) { // Max 5 minutes at 1 second granularity
this.hits.length = 300; // Drop counts past 5 minutes
// A possible extension would be to "roll up" counts to coarser granularity
}
}
else {
this.hits[0].hits++;
}
};
// Has an error of +/- 1 second
HitCounter.prototype.getHitsInLastNSeconds = function(n) {
var sum = 0,
since = this.getTimestamp() - n;
for (var i = 0; i < n; i++) {
if (this.hits[i]) {
if (this.hits[i].timestamp > since) {
sum += this.hits[i].hits;
}
else {
break;
}
}
}
return sum;
};
var counter = new HitCounter();
for (var i = 0, l = Math.floor(Math.random() * 1000); i < l; i++) {
counter.hit();
}
console.log(counter.getHitsInLastNSeconds(1));