From e842032cadc5ff4567b82dae7371eaebecd675b1 Mon Sep 17 00:00:00 2001 From: sh123 Date: Sun, 2 Jul 2023 22:33:40 +0300 Subject: [PATCH] Aprs heard list --- .../protocol/aprs/tools/AprsHeardList.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/aprs/tools/AprsHeardList.java b/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/aprs/tools/AprsHeardList.java index 37b6ac1..ce4e3e1 100644 --- a/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/aprs/tools/AprsHeardList.java +++ b/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/aprs/tools/AprsHeardList.java @@ -1,4 +1,69 @@ package com.radio.codec2talkie.protocol.aprs.tools; +import java.util.Map; + +import java.util.Timer; +import java.util.TimerTask; +import java.util.TreeMap; + public class AprsHeardList { + + private final int CLEANUP_PERIOD_MS = 30000; + + private static class AprsHeardListItem { + public long timestamp; + public String callsign; + + public AprsHeardListItem(long timestamp, String callsign) { + this.timestamp = timestamp; + this.callsign = callsign; + } + } + + private final int _keepSeconds; + private final TreeMap _data = new TreeMap<>(); + + public AprsHeardList(int keepSeconds) { + _keepSeconds = keepSeconds; + scheduleCleanup(); + } + + public void add(String callsign) { + synchronized (_data) { + AprsHeardListItem heardItem = _data.get(callsign); + if (heardItem == null) { + AprsHeardListItem newHeardItem = new AprsHeardListItem(System.currentTimeMillis(), callsign); + _data.put(callsign, newHeardItem); + } else { + heardItem.timestamp = System.currentTimeMillis(); + } + } + } + + public boolean contains(String callsign) { + synchronized (_data) { + return _data.containsKey(callsign); + } + } + + private void scheduleCleanup() { + Timer cleanupTimer = new Timer(); + cleanupTimer.schedule(new TimerTask() { + @Override + public void run() { + cleanup(); + } + }, CLEANUP_PERIOD_MS, CLEANUP_PERIOD_MS); + } + + private void cleanup() { + long removeOlderThan = System.currentTimeMillis() - _keepSeconds * 1000L; + synchronized (_data) { + for (Map.Entry entryElement : _data.entrySet()) { + if (entryElement.getValue().timestamp < removeOlderThan) { + _data.remove(entryElement.getKey()); + } + } + } + } }