From cbb00d4729243e4949b3c921fc2f94cb03ca8aaa Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期五, 27 三月 2026 18:47:43 +0800
Subject: [PATCH] #

---
 src/main/java/com/zy/core/thread/support/RecentStationArrivalTracker.java |   77 +++++++++++++-------------------------
 1 files changed, 26 insertions(+), 51 deletions(-)

diff --git a/src/main/java/com/zy/core/thread/support/RecentStationArrivalTracker.java b/src/main/java/com/zy/core/thread/support/RecentStationArrivalTracker.java
index a153465..193e43d 100644
--- a/src/main/java/com/zy/core/thread/support/RecentStationArrivalTracker.java
+++ b/src/main/java/com/zy/core/thread/support/RecentStationArrivalTracker.java
@@ -1,82 +1,57 @@
 package com.zy.core.thread.support;
 
+import com.zy.common.utils.RedisUtil;
+
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.function.LongSupplier;
 
 public class RecentStationArrivalTracker {
 
     static final long DEFAULT_RETAIN_MS = 10_000L;
+    static final String KEY_PREFIX = "station_recent_arrival_";
 
-    private final long retainMs;
-    private final LongSupplier nowSupplier;
-    private final Map<Long, Long> arrivalTimeMap = new ConcurrentHashMap<>();
-    private final AtomicLong lastCleanupAt = new AtomicLong(0L);
+    private final RedisUtil redisUtil;
+    private final long retainSeconds;
+    private final Map<Integer, Integer> lastLoadedTaskByStation = new ConcurrentHashMap<>();
 
-    public RecentStationArrivalTracker() {
-        this(DEFAULT_RETAIN_MS, System::currentTimeMillis);
+    public RecentStationArrivalTracker(RedisUtil redisUtil) {
+        this(redisUtil, DEFAULT_RETAIN_MS);
     }
 
-    public RecentStationArrivalTracker(long retainMs, LongSupplier nowSupplier) {
-        this.retainMs = retainMs <= 0L ? DEFAULT_RETAIN_MS : retainMs;
-        this.nowSupplier = nowSupplier == null ? System::currentTimeMillis : nowSupplier;
+    public RecentStationArrivalTracker(RedisUtil redisUtil, long retainMs) {
+        this.redisUtil = redisUtil;
+        long effectiveRetainMs = retainMs <= 0L ? DEFAULT_RETAIN_MS : retainMs;
+        this.retainSeconds = Math.max(1L, (long) Math.ceil(effectiveRetainMs / 1000d));
     }
 
     public void observe(Integer stationId, Integer taskNo, boolean loading) {
-        if (!loading) {
+        if (stationId == null || stationId <= 0) {
             return;
         }
-        record(stationId, taskNo);
-    }
-
-    public void record(Integer stationId, Integer taskNo) {
-        Long key = buildKey(stationId, taskNo);
-        if (key == null) {
+        if (!loading || taskNo == null || taskNo <= 0) {
+            lastLoadedTaskByStation.remove(stationId);
             return;
         }
-        long now = nowSupplier.getAsLong();
-        arrivalTimeMap.put(key, now);
-        cleanupIfNeeded(now);
+        Integer previousTaskNo = lastLoadedTaskByStation.put(stationId, taskNo);
+        if (Objects.equals(previousTaskNo, taskNo) || redisUtil == null) {
+            return;
+        }
+        redisUtil.set(buildKey(stationId, taskNo), "1", retainSeconds);
     }
 
     public boolean hasRecentArrival(Integer stationId, Integer taskNo) {
-        Long key = buildKey(stationId, taskNo);
-        if (key == null) {
+        if (redisUtil == null) {
             return false;
         }
-        long now = nowSupplier.getAsLong();
-        Long arrivalAt = arrivalTimeMap.get(key);
-        if (arrivalAt == null) {
-            cleanupIfNeeded(now);
-            return false;
-        }
-        if (now - arrivalAt > retainMs) {
-            arrivalTimeMap.remove(key, arrivalAt);
-            cleanupIfNeeded(now);
-            return false;
-        }
-        cleanupIfNeeded(now);
-        return true;
+        String key = buildKey(stationId, taskNo);
+        return key != null && redisUtil.get(key) != null;
     }
 
-    private void cleanupIfNeeded(long now) {
-        long lastCleanup = lastCleanupAt.get();
-        if (now - lastCleanup < retainMs || !lastCleanupAt.compareAndSet(lastCleanup, now)) {
-            return;
-        }
-        for (Map.Entry<Long, Long> entry : arrivalTimeMap.entrySet()) {
-            if (entry == null || now - entry.getValue() <= retainMs) {
-                continue;
-            }
-            arrivalTimeMap.remove(entry.getKey(), entry.getValue());
-        }
-    }
-
-    private Long buildKey(Integer stationId, Integer taskNo) {
+    private String buildKey(Integer stationId, Integer taskNo) {
         if (stationId == null || stationId <= 0 || taskNo == null || taskNo <= 0) {
             return null;
         }
-        return (((long) stationId) << 32) | (taskNo.longValue() & 0xffffffffL);
+        return KEY_PREFIX + stationId + "_" + taskNo;
     }
 }

--
Gitblit v1.9.1