*
L
16 小时以前 daa2cec25875276f3462e09d102f9d2fd52a96e1
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
60
61
62
63
64
package com.zy.asrs.utils;
 
import java.util.Date;
 
/**
 * 时间优先级工具:
 * 参考SchedulingCarUtil优化:
 * 阈值前基础值,阈值后指数增长,超长等待线性补偿,最终归一化到 [0, 1]
 */
public final class TimePriorityUtil {
 
    private static final double BASE_PRIORITY = 0.2D;
    private static final int CACHE_SIZE = 1800;
    private static final double[] EXP_CACHE = new double[CACHE_SIZE];
 
    static {
        for (int i = 0; i < CACHE_SIZE; i++) {
            EXP_CACHE[i] = 0.8D * (1D - Math.exp(-0.02D * i));
        }
    }
 
    private TimePriorityUtil() {
    }
 
    public static double calculate(Date createTime, Date now, long maxWaitMs) {
        if (createTime == null || now == null || maxWaitMs <= 0L) {
            return 0D;
        }
        long waitMs = Math.max(0L, now.getTime() - createTime.getTime());
        return clamp01((double) waitMs / (double) maxWaitMs);
    }
 
    public static double calculateDynamic(Date createTime,
                                          Date now,
                                          double waitThresholdSeconds,
                                          double linearThresholdSeconds,
                                          double linearFactor) {
        if (createTime == null || now == null) {
            return 0D;
        }
        double waitSeconds = Math.max(0D, (now.getTime() - createTime.getTime()) / 1000D);
        if (waitSeconds <= waitThresholdSeconds) {
            return BASE_PRIORITY;
        }
        double exceedSeconds = waitSeconds - waitThresholdSeconds;
        double expPart = exceedSeconds < CACHE_SIZE
                ? EXP_CACHE[(int) exceedSeconds]
                : 0.8D * (1D - Math.exp(-0.02D * exceedSeconds));
        double linearPart = exceedSeconds > linearThresholdSeconds
                ? linearFactor * (exceedSeconds - linearThresholdSeconds)
                : 0D;
        return clamp01(BASE_PRIORITY + expPart + linearPart);
    }
 
    private static double clamp01(double value) {
        if (value < 0D) {
            return 0D;
        }
        if (value > 1D) {
            return 1D;
        }
        return value;
    }
}