package com.ruoyi.device.simulator; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import com.ruoyi.device.simulator.BtsSimulatorStateStore.CollectorHistoryAppend; import com.ruoyi.device.simulator.BtsSimulatorStateStore.CollectorHistoryBatch; import com.ruoyi.device.simulator.BtsSimulatorStateStore.CollectorMeasurementRecord; import com.ruoyi.device.simulator.BtsSimulatorStateStore.BtsHistoryRecord; import com.ruoyi.device.simulator.BtsSimulatorStateStore.BtsHistoryBatch; import com.ruoyi.device.simulator.BtsSimulatorStateStore.RecentRequest; import com.ruoyi.device.simulator.BtsSimulatorStateStore.SimulatorState; import com.ruoyi.device.simulator.BtsSimulatorStateStore.BtsPlaybackState; /** 测试和独立协议合同使用的内存状态存储。 */ public final class InMemoryBtsSimulatorStateStore implements BtsSimulatorStateStore { private SimulatorState state; private List recentRequests = List.of(); private final Map> collectorHistory = new LinkedHashMap<>(); private final Map> btsHistory = new LinkedHashMap<>(); private final Map btsPlayback = new LinkedHashMap<>(); public InMemoryBtsSimulatorStateStore() { } public InMemoryBtsSimulatorStateStore(SimulatorState state) { this.state = state; } @Override public synchronized SimulatorState loadOrInitialize(SimulatorState defaultState) { if (state == null) state = defaultState; return state; } @Override public synchronized void save(SimulatorState state) { this.state = state; } @Override public synchronized void save(SimulatorState state, List historyAppends) { for (CollectorHistoryAppend append : historyAppends) { ArrayList history = collectorHistory.computeIfAbsent( append.collectorCode(), key -> new ArrayList<>()); history.addAll(append.records()); int overflow = history.size() - (int) MAX_HISTORY_RECORDS; if (overflow > 0) history.subList(0, overflow).clear(); } this.state = state; } @Override public synchronized 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); List history = collectorHistory.getOrDefault(collectorCode, new ArrayList<>()); long total = history.size(); int from = (int) Math.min(offset, total); int count = Math.min(limit, history.size() - from); List records = new ArrayList<>(count); if (reverse) { for (int index = history.size() - 1 - from; index >= history.size() - from - count; index--) records.add(history.get(index)); } else { records.addAll(history.subList(from, from + count)); } long nextOffset = from + records.size(); return new CollectorHistoryBatch(offset, nextOffset, nextOffset < total, total, records); } @Override public synchronized void saveAndDeleteCollectorHistory(SimulatorState state, String collectorCode) { collectorHistory.remove(collectorCode); this.state = state; } @Override public synchronized BtsHistoryBatch loadBtsHistoryPage(String historyKey, long offset, int limit) { List history = btsHistory.getOrDefault(historyKey, new ArrayList<>()); int from = (int) Math.min(offset, history.size()); int count = Math.min(limit, history.size() - from); List records = new ArrayList<>(history.subList(from, from + count)); long next = from + records.size(); return new BtsHistoryBatch(offset, next, next < history.size(), history.size(), records); } @Override public synchronized void appendBtsHistory(String historyKey, BtsHistoryRecord record) { ArrayList history = btsHistory.computeIfAbsent(historyKey, key -> new ArrayList<>()); history.add(record); if (history.size() > MAX_HISTORY_RECORDS) history.remove(0); } @Override public synchronized BtsPlaybackState loadBtsPlaybackState(String historyKey) { return btsPlayback.get(historyKey); } @Override public synchronized void saveBtsPlaybackState(String historyKey, BtsPlaybackState playback) { btsPlayback.put(historyKey, playback); } @Override public synchronized void deleteBtsPlaybackState(String historyKey) { btsPlayback.remove(historyKey); } @Override public synchronized void deleteBtsHistory(String historyKey) { btsHistory.remove(historyKey); } @Override public synchronized void saveBtsPlaybackAndAppendHistory(String historyKey, BtsPlaybackState playback, List records) { ArrayList history = btsHistory.computeIfAbsent(historyKey, key -> new ArrayList<>()); history.addAll(records); int overflow = history.size() - (int) MAX_HISTORY_RECORDS; if (overflow > 0) history.subList(0, overflow).clear(); btsPlayback.put(historyKey, playback); } @Override public synchronized List loadRecentRequests() { return recentRequests; } @Override public synchronized void saveRecentRequests(List requests) { recentRequests = List.copyOf(requests); } @Override public synchronized void reset(SimulatorState defaultState) { state = defaultState; recentRequests = List.of(); collectorHistory.clear(); btsHistory.clear(); btsPlayback.clear(); } }