From 8761644af158c5e7f05e999e9834b6496ce414e7 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期六, 29 八月 2026 16:04:31 +0800
Subject: [PATCH] 优化采集器长时历史的有界读取
---
ruoyi-admin/src/main/java/com/ruoyi/config/RedisBtsSimulatorStateStore.java | 54 ++++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/config/RedisBtsSimulatorStateStore.java b/ruoyi-admin/src/main/java/com/ruoyi/config/RedisBtsSimulatorStateStore.java
index 6c9d1eb..1733bf7 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/config/RedisBtsSimulatorStateStore.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/config/RedisBtsSimulatorStateStore.java
@@ -25,7 +25,6 @@
static final String HISTORY_KEYS_KEY = "dev:bts-simulator:collector-history-keys:v1";
static final String HISTORY_KEY_PREFIX = "dev:bts-simulator:collector-history:v1:";
private static final long RECENT_REQUESTS_TTL_HOURS = 1;
- private static final int HISTORY_READ_BATCH_SIZE = 1000;
private final RedisTemplate<Object, Object> redisTemplate;
private List<CollectorHistoryAppend> pendingEmbeddedHistory = List.of();
@@ -99,25 +98,56 @@
}
@Override
- public List<CollectorMeasurementRecord> loadCollectorHistory(String collectorCode)
+ public CollectorHistoryBatch loadCollectorHistoryPage(String collectorCode, long offset, int limit,
+ boolean reverse)
{
+ if (offset < 0) throw new IllegalArgumentException("offset must not be negative");
+ if (limit < 1 || limit > MAX_HISTORY_BATCH_SIZE)
+ throw new IllegalArgumentException("limit must be between 1 and " + MAX_HISTORY_BATCH_SIZE);
String key = historyKey(collectorCode);
Long storedSize = redisTemplate.opsForList().size(key);
- List<CollectorMeasurementRecord> records = new ArrayList<>();
- if (storedSize != null)
+ long redisCount = storedSize == null ? 0 : storedSize;
+ List<CollectorMeasurementRecord> embedded = pendingEmbeddedHistory.stream()
+ .filter(append -> append.collectorCode().equals(collectorCode))
+ .findFirst().map(CollectorHistoryAppend::records).orElse(List.of());
+ long total = redisCount + embedded.size();
+ long from = Math.min(offset, total);
+ int count = (int) Math.min(limit, total - from);
+ List<CollectorMeasurementRecord> records = new ArrayList<>(count);
+ if (reverse)
{
- for (long start = 0; start < storedSize; start += HISTORY_READ_BATCH_SIZE)
+ long lower = total - from - count;
+ long upper = total - from;
+ long embeddedLower = Math.max(lower, redisCount);
+ for (long index = upper - 1; index >= embeddedLower; index--)
+ records.add(embedded.get((int) (index - redisCount)));
+ long redisUpper = Math.min(upper, redisCount);
+ if (lower < redisUpper)
{
- long end = Math.min(start + HISTORY_READ_BATCH_SIZE, storedSize) - 1;
- List<Object> stored = redisTemplate.opsForList().range(key, start, end);
+ List<Object> stored = redisTemplate.opsForList().range(key, lower, redisUpper - 1);
if (stored != null)
- stored.forEach(item -> records.add(collectorMeasurementRecord(item)));
+ for (int index = stored.size() - 1; index >= 0; index--)
+ records.add(collectorMeasurementRecord(stored.get(index)));
}
}
- pendingEmbeddedHistory.stream()
- .filter(append -> append.collectorCode().equals(collectorCode))
- .forEach(append -> records.addAll(append.records()));
- return List.copyOf(records);
+ else
+ {
+ long upper = from + count;
+ long redisUpper = Math.min(upper, redisCount);
+ if (from < redisUpper)
+ {
+ List<Object> stored = redisTemplate.opsForList().range(key, from, redisUpper - 1);
+ if (stored != null) stored.forEach(item -> records.add(collectorMeasurementRecord(item)));
+ }
+ long embeddedFrom = Math.max(from, redisCount);
+ if (embeddedFrom < upper)
+ records.addAll(embedded.subList((int) (embeddedFrom - redisCount),
+ (int) (upper - redisCount)));
+ }
+ if (records.size() != count)
+ throw new IllegalStateException("Collector history page changed while reading Redis");
+ long nextOffset = from + records.size();
+ return new CollectorHistoryBatch(offset, nextOffset, nextOffset < total, total, records);
}
@Override
--
Gitblit v1.7.1