mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-11-04 14:22:11 +08:00
perf(traffic): optimize traffic data handling and improve performance
This commit is contained in:
@@ -15,7 +15,9 @@ export const formatTrafficName = (timestamp: number) =>
|
||||
|
||||
export class TrafficDataSampler {
|
||||
private rawBuffer: ITrafficDataPoint[] = [];
|
||||
private rawHead = 0;
|
||||
private compressedBuffer: ICompressedDataPoint[] = [];
|
||||
private compressedHead = 0;
|
||||
private compressionQueue: ITrafficDataPoint[] = [];
|
||||
|
||||
constructor(private config: ISamplingConfig) {}
|
||||
@@ -24,7 +26,17 @@ export class TrafficDataSampler {
|
||||
this.rawBuffer.push(point);
|
||||
|
||||
const rawCutoff = Date.now() - this.config.rawDataMinutes * 60 * 1000;
|
||||
this.rawBuffer = this.rawBuffer.filter((p) => p.timestamp > rawCutoff);
|
||||
// O(1) amortized trimming using moving head; compact occasionally
|
||||
while (
|
||||
this.rawHead < this.rawBuffer.length &&
|
||||
this.rawBuffer[this.rawHead]?.timestamp <= rawCutoff
|
||||
) {
|
||||
this.rawHead++;
|
||||
}
|
||||
if (this.rawHead > 512 && this.rawHead > this.rawBuffer.length / 2) {
|
||||
this.rawBuffer = this.rawBuffer.slice(this.rawHead);
|
||||
this.rawHead = 0;
|
||||
}
|
||||
|
||||
this.compressionQueue.push(point);
|
||||
if (this.compressionQueue.length >= this.config.compressionRatio) {
|
||||
@@ -33,9 +45,19 @@ export class TrafficDataSampler {
|
||||
|
||||
const compressedCutoff =
|
||||
Date.now() - this.config.compressedDataMinutes * 60 * 1000;
|
||||
this.compressedBuffer = this.compressedBuffer.filter(
|
||||
(p) => p.timestamp > compressedCutoff,
|
||||
);
|
||||
while (
|
||||
this.compressedHead < this.compressedBuffer.length &&
|
||||
this.compressedBuffer[this.compressedHead]?.timestamp <= compressedCutoff
|
||||
) {
|
||||
this.compressedHead++;
|
||||
}
|
||||
if (
|
||||
this.compressedHead > 256 &&
|
||||
this.compressedHead > this.compressedBuffer.length / 2
|
||||
) {
|
||||
this.compressedBuffer = this.compressedBuffer.slice(this.compressedHead);
|
||||
this.compressedHead = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private compressData() {
|
||||
@@ -60,18 +82,34 @@ export class TrafficDataSampler {
|
||||
|
||||
getDataForTimeRange(minutes: number): ITrafficDataPoint[] {
|
||||
const cutoff = Date.now() - minutes * 60 * 1000;
|
||||
const rawData = this.rawBuffer.filter((p) => p.timestamp > cutoff);
|
||||
|
||||
let rawStart = this.rawHead;
|
||||
while (
|
||||
rawStart < this.rawBuffer.length &&
|
||||
this.rawBuffer[rawStart]?.timestamp <= cutoff
|
||||
) {
|
||||
rawStart++;
|
||||
}
|
||||
const rawData = this.rawBuffer.slice(rawStart);
|
||||
|
||||
if (minutes <= this.config.rawDataMinutes) {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
const compressedCutoffUpper =
|
||||
Date.now() - this.config.rawDataMinutes * 60 * 1000;
|
||||
|
||||
let compressedStart = this.compressedHead;
|
||||
while (
|
||||
compressedStart < this.compressedBuffer.length &&
|
||||
this.compressedBuffer[compressedStart]?.timestamp <= cutoff
|
||||
) {
|
||||
compressedStart++;
|
||||
}
|
||||
|
||||
const compressedData = this.compressedBuffer
|
||||
.filter(
|
||||
(p) =>
|
||||
p.timestamp > cutoff &&
|
||||
p.timestamp <= Date.now() - this.config.rawDataMinutes * 60 * 1000,
|
||||
)
|
||||
.slice(compressedStart)
|
||||
.filter((p) => p.timestamp <= compressedCutoffUpper)
|
||||
.map((p) => ({
|
||||
up: p.up,
|
||||
down: p.down,
|
||||
@@ -86,16 +124,21 @@ export class TrafficDataSampler {
|
||||
|
||||
getStats(): ISamplerStats {
|
||||
return {
|
||||
rawBufferSize: this.rawBuffer.length,
|
||||
compressedBufferSize: this.compressedBuffer.length,
|
||||
rawBufferSize: this.rawBuffer.length - this.rawHead,
|
||||
compressedBufferSize: this.compressedBuffer.length - this.compressedHead,
|
||||
compressionQueueSize: this.compressionQueue.length,
|
||||
totalMemoryPoints: this.rawBuffer.length + this.compressedBuffer.length,
|
||||
totalMemoryPoints:
|
||||
this.rawBuffer.length -
|
||||
this.rawHead +
|
||||
(this.compressedBuffer.length - this.compressedHead),
|
||||
};
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.rawBuffer = [];
|
||||
this.rawHead = 0;
|
||||
this.compressedBuffer = [];
|
||||
this.compressedHead = 0;
|
||||
this.compressionQueue = [];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user