pandora-metrics
Version:
## Overview
125 lines • 3.95 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Counter_1 = require("./Counter");
class BucketDeque {
constructor(length = 11) {
this.queue = [];
this.current = 0;
this.size = 11;
this.size = length;
// init buckets
for (let i = 0; i < length; i++) {
this.queue[i] = this.createQueueItem();
}
}
createQueueItem() {
return {
timestamp: -1,
count: 0,
};
}
addLast(e) {
this.current = (this.current + 1) % this.size;
this.queue[this.current] = e;
}
peek() {
return this.queue[this.current];
}
/**
* Example1:
* 10:00 10:01 10:02 09:57 09:58 09:59
* 70 80 90 40 50 60
* | \
* startPos latestIndex
* Example2:
* 10:00 09:55 09:56 09:57 09:58 09:59
* 70 20 30 40 50 60
* | |
* latestIndex startPos
*/
getBucketList() {
let length = this.queue.length - 1;
let bucketList = [];
let startPos = this.current;
let startTs = this.queue[this.current].timestamp;
if (startPos < 0) {
startPos = 0;
}
for (let i = startPos; i >= 0 && startPos - i < length; i--) {
bucketList.push(this.queue[i]);
}
for (let i = length; i > startPos + 1; i--) {
if (this.queue[i].timestamp > startTs) {
// the current index has been update during this iteration
// therefore the data shall not be collected
}
else {
bucketList.push(this.queue[i]);
}
}
return bucketList;
}
}
exports.BucketDeque = BucketDeque;
class BucketCounter extends Counter_1.BaseCounter {
constructor(interval = 1, numberOfBucket = 10, updateTotalCount = true) {
super();
/**
* 是否更新总次数
*/
this.updateTotalCount = false;
this.totalCount = new Counter_1.BaseCounter();
this.interval = interval;
this.buckets = new BucketDeque(numberOfBucket + 1);
this.updateTotalCount = updateTotalCount;
}
update(n = 1) {
if (this.updateTotalCount) {
this.totalCount.inc(n);
}
let curTs = this.calculateCurrentTimestamp(Date.now());
let lastBucket = this.buckets.peek();
if (curTs > lastBucket.timestamp) {
// create a new bucket and evict the oldest one
let newBucket = {
count: 0,
timestamp: curTs
};
this.buckets.addLast(newBucket);
lastBucket = newBucket;
}
lastBucket.count += n;
}
/**
* Return the bucket count, keyed by timestamp
* @return the bucket count, keyed by timestamp
*/
getBucketCounts(startTime = 0) {
let counts = new Map();
let curTs = this.calculateCurrentTimestamp(Date.now());
for (let bucket of this.buckets.getBucketList()) {
if (1000 * bucket.timestamp >= startTime && bucket.timestamp <= curTs) {
counts.set(bucket.timestamp * 1000, bucket.count);
}
}
return counts;
}
calculateCurrentTimestamp(timestamp) {
// transform to seconds and discard fractional part
return Math.floor(Math.floor(timestamp / 1000) / this.interval) * this.interval;
}
getCount() {
return this.totalCount.getCount();
}
inc(n) {
this.update(n);
}
dec(n = 1) {
this.update(-n);
}
getBucketInterval() {
return this.interval;
}
}
exports.BucketCounter = BucketCounter;
//# sourceMappingURL=BucketCounter.js.map