Junjie
2026-04-14 088d6d943e2669426a1b410e438e9da3a29f1203
#算法耗时优化loadLoopMergeGuardContext增加缓存
2个文件已修改
48 ■■■■■ 已修改文件
src/main/java/com/zy/common/utils/NavigateUtils.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/trace/StationTaskTraceRegistry.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/NavigateUtils.java
@@ -80,6 +80,9 @@
    private final Object runtimeSnapshotLock = new Object();
    private volatile CachedStationPathRuntimeSnapshot cachedRuntimeSnapshot;
    private final Object loopMergeGuardLock = new Object();
    private volatile CachedLoopMergeGuardContext cachedLoopMergeGuardContext;
    public List<NavigateNode> calcOptimalPathByStationId(Integer startStationId,
                                                         Integer endStationId,
                                                         Integer currentTaskNo,
@@ -1766,6 +1769,23 @@
    }
    private LoopMergeGuardContext loadLoopMergeGuardContext() {
        long now = System.currentTimeMillis();
        CachedLoopMergeGuardContext cached = cachedLoopMergeGuardContext;
        if (cached != null && now - cached.cacheAtMs <= STATION_PATH_RUNTIME_SNAPSHOT_TTL_MS) {
            return new LoopMergeGuardContext(cached.context);
        }
        synchronized (loopMergeGuardLock) {
            cached = cachedLoopMergeGuardContext;
            if (cached != null && now - cached.cacheAtMs <= STATION_PATH_RUNTIME_SNAPSHOT_TTL_MS) {
                return new LoopMergeGuardContext(cached.context);
            }
            LoopMergeGuardContext context = buildLoopMergeGuardContext();
            cachedLoopMergeGuardContext = new CachedLoopMergeGuardContext(System.currentTimeMillis(), context);
            return new LoopMergeGuardContext(context);
        }
    }
    private LoopMergeGuardContext buildLoopMergeGuardContext() {
        LoopMergeGuardContext context = new LoopMergeGuardContext();
        try {
            if (stationCycleCapacityService == null) {
@@ -3083,6 +3103,16 @@
        }
    }
    private static class CachedLoopMergeGuardContext {
        private final long cacheAtMs;
        private final LoopMergeGuardContext context;
        private CachedLoopMergeGuardContext(long cacheAtMs, LoopMergeGuardContext context) {
            this.cacheAtMs = cacheAtMs;
            this.context = context;
        }
    }
    private static class PathCandidateMetrics {
        private List<NavigateNode> path;
        private int pathLen;
@@ -3136,6 +3166,16 @@
    private static class LoopMergeGuardContext {
        private final Set<Integer> loopStationIdSet = new HashSet<>();
        private final Map<Integer, Set<Integer>> loopNeighborMap = new HashMap<>();
        private LoopMergeGuardContext() {
        }
        private LoopMergeGuardContext(LoopMergeGuardContext source) {
            this.loopStationIdSet.addAll(source.loopStationIdSet);
            for (Map.Entry<Integer, Set<Integer>> entry : source.loopNeighborMap.entrySet()) {
                this.loopNeighborMap.put(entry.getKey(), new LinkedHashSet<>(entry.getValue()));
            }
        }
    }
    private static class LoopMergeEntry {
src/main/java/com/zy/core/trace/StationTaskTraceRegistry.java
@@ -11,6 +11,7 @@
import com.zy.core.model.command.StationCommand;
import com.zy.core.enums.RedisKeyType;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -22,6 +23,7 @@
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Component
public class StationTaskTraceRegistry {
@@ -302,7 +304,13 @@
            if (loadedFromRedis) {
                return;
            }
            long redisStartNs = System.nanoTime();
            Map<Object, Object> cacheMap = redisUtil == null ? null : redisUtil.hmget(TRACE_CACHE_KEY);
            long redisCostMs = (System.nanoTime() - redisStartNs) / 1_000_000L;
            if (redisCostMs > 100) {
                log.info("StationTaskTraceRegistry Redis加载耗时={}ms, entries={}", redisCostMs,
                        cacheMap == null ? 0 : cacheMap.size());
            }
            if (cacheMap != null && !cacheMap.isEmpty()) {
                long now = System.currentTimeMillis();
                for (Map.Entry<Object, Object> entry : cacheMap.entrySet()) {