From f354ff14c4e89ad7a3fae3be106b0faec63789d4 Mon Sep 17 00:00:00 2001 From: Igor Zolotarenko Date: Fri, 29 Dec 2023 20:41:30 +0200 Subject: [PATCH] Git use another approach. Suppress loading intervals together. --- .../src/bandwidth-calculator.ts | 76 +++++++++++-------- .../p2p-media-loader-core/src/linked-map.ts | 14 ---- packages/p2p-media-loader-core/src/request.ts | 2 - 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/packages/p2p-media-loader-core/src/bandwidth-calculator.ts b/packages/p2p-media-loader-core/src/bandwidth-calculator.ts index 8cae886a..11807c9a 100644 --- a/packages/p2p-media-loader-core/src/bandwidth-calculator.ts +++ b/packages/p2p-media-loader-core/src/bandwidth-calculator.ts @@ -1,10 +1,14 @@ import { arrayBackwards } from "./utils/utils"; +type Interval = { start: number; end?: number }; + +const CLEAR_THRESHOLD_MS = 3000; + export class BandwidthCalculator { private simultaneousLoadingsCount = 0; private readonly bytes: number[] = []; private readonly timestamps: number[] = []; - private loadingIntervals: { start: number; end?: number }[] = []; + private loadingIntervals: Interval[] = []; addBytes(bytesLength: number) { this.bytes.push(bytesLength); @@ -30,45 +34,57 @@ export class BandwidthCalculator { // in bits per second getBandwidthForLastNSeconds(seconds: number) { - this.clearStale(); - const { bytes, timestamps, loadingIntervals } = this; - const samplesLength = bytes.length; + const { bytes, timestamps } = this; + if (!bytes.length) return 0; + const milliseconds = seconds * 1000; const now = performance.now(); - const threshold = now - seconds * 1000; + let totalTime = 0; - let loadedBytes = 0; - for (let i = samplesLength - 1; i >= 0; i--) { - if (timestamps[i] < threshold) break; - loadedBytes += bytes[i]; + let firstIntervalStart = Number.POSITIVE_INFINITY; + for (const { start, end = now } of arrayBackwards(this.loadingIntervals)) { + const duration = end - start; + if (totalTime + duration < milliseconds) { + totalTime += duration; + firstIntervalStart = start; + continue; + } + firstIntervalStart = end - (milliseconds - totalTime); + totalTime = milliseconds; + break; } + if (totalTime === 0) return 0; - let clearLoadingTime = 0; - for (const { start, end } of arrayBackwards(loadingIntervals)) { - if (start < threshold && end !== undefined && end < threshold) break; - const from = Math.max(start, threshold); - const to = end ?? now; - clearLoadingTime += to - from; + let totalBytes = 0; + for (let i = bytes.length - 1; i >= 0; i--) { + if (timestamps[i] < firstIntervalStart) break; + totalBytes += bytes[i]; } - if (clearLoadingTime === 0) return 0; - return (loadedBytes * 8000) / clearLoadingTime; + return (totalBytes * 8000) / totalTime; } - private clearStale() { - const { timestamps, bytes, loadingIntervals } = this; - const samplesLength = bytes.length; - const threshold = performance.now() - 15000; + clearStale() { + if (!this.loadingIntervals.length) return; + const now = performance.now(); + let totalTime = 0; - let count = 0; - while (count < samplesLength && timestamps[count] < threshold) count++; - bytes.splice(0, count); - timestamps.splice(0, count); + let intervalsToLeave = 0; + for (const { start, end = now } of arrayBackwards(this.loadingIntervals)) { + const duration = end - start; + intervalsToLeave++; + if (totalTime + duration >= CLEAR_THRESHOLD_MS) break; + totalTime += duration; + } + const intervalsToRemove = this.loadingIntervals.length - intervalsToLeave; + this.loadingIntervals.splice(0, intervalsToRemove); - count = 0; - for (const { start, end } of loadingIntervals) { - if (!(start < threshold && end !== undefined && end <= threshold)) break; - count++; + const { start: firstIntervalStart } = this.loadingIntervals[0]; + let samplesToRemove = 0; + for (const timestamp of this.timestamps) { + if (timestamp >= firstIntervalStart) break; + samplesToRemove++; } - loadingIntervals.splice(0, count); + this.bytes.splice(0, samplesToRemove); + this.timestamps.splice(0, samplesToRemove); } } diff --git a/packages/p2p-media-loader-core/src/linked-map.ts b/packages/p2p-media-loader-core/src/linked-map.ts index 3af745ec..78ee364d 100644 --- a/packages/p2p-media-loader-core/src/linked-map.ts +++ b/packages/p2p-media-loader-core/src/linked-map.ts @@ -9,14 +9,6 @@ export class LinkedMap { private _first?: LinkedObject; private _last?: LinkedObject; - get first() { - return this._first?.item; - } - - get last() { - return this._last?.item; - } - get size() { return this.map.size; } @@ -53,12 +45,6 @@ export class LinkedMap { this.map.delete(key); } - clear() { - this._first = undefined; - this._last = undefined; - this.map.clear(); - } - *values(key?: K) { let value = key ? this.map.get(key) : this._first; if (value === undefined) return; diff --git a/packages/p2p-media-loader-core/src/request.ts b/packages/p2p-media-loader-core/src/request.ts index c82717fa..5875b8dc 100644 --- a/packages/p2p-media-loader-core/src/request.ts +++ b/packages/p2p-media-loader-core/src/request.ts @@ -208,9 +208,7 @@ export class Request { resolveEngineCallbacksSuccessfully() { if (!this.finalData) return; const bandwidth = this.bandwidthCalculator.getBandwidthForLastNSeconds(3); - const bandwidth6 = this.bandwidthCalculator.getBandwidthForLastNSeconds(6); console.log("bandwidth", bandwidth / 1000); - console.log("bandwidth6", bandwidth6 / 1000); this._engineCallbacks?.onSuccess({ data: this.finalData, bandwidth }); this._engineCallbacks = undefined; }