马宇豪
2024-07-16 f591c27b57e2418c9495bc02ae8cfff84d35bc18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/*
    MIT License http://www.opensource.org/licenses/mit-license.php
    Author Tobias Koppers @sokra
*/
 
"use strict";
 
const binarySearchBounds = require("../util/binarySearchBounds");
 
class ParallelismFactorCalculator {
    constructor() {
        this._rangePoints = [];
        this._rangeCallbacks = [];
    }
 
    range(start, end, callback) {
        if (start === end) return callback(1);
        this._rangePoints.push(start);
        this._rangePoints.push(end);
        this._rangeCallbacks.push(callback);
    }
 
    calculate() {
        const segments = Array.from(new Set(this._rangePoints)).sort((a, b) =>
            a < b ? -1 : 1
        );
        const parallelism = segments.map(() => 0);
        const rangeStartIndices = [];
        for (let i = 0; i < this._rangePoints.length; i += 2) {
            const start = this._rangePoints[i];
            const end = this._rangePoints[i + 1];
            let idx = binarySearchBounds.eq(segments, start);
            rangeStartIndices.push(idx);
            do {
                parallelism[idx]++;
                idx++;
            } while (segments[idx] < end);
        }
        for (let i = 0; i < this._rangeCallbacks.length; i++) {
            const start = this._rangePoints[i * 2];
            const end = this._rangePoints[i * 2 + 1];
            let idx = rangeStartIndices[i];
            let sum = 0;
            let totalDuration = 0;
            let current = start;
            do {
                const p = parallelism[idx];
                idx++;
                const duration = segments[idx] - current;
                totalDuration += duration;
                current = segments[idx];
                sum += p * duration;
            } while (current < end);
            this._rangeCallbacks[i](sum / totalDuration);
        }
    }
}
 
module.exports = ParallelismFactorCalculator;