1use std::collections::HashMap;
2use std::time::Instant;
3
4#[derive(Clone, Debug, PartialEq, Eq)]
5pub struct PeerEntry {
6 pub coord_id: String,
7 pub last_seen: Instant,
8}
9
10pub trait PeerStore {
11 fn upsert(&mut self, meta: PeerEntry) -> bool;
14
15 fn mark_alive(&mut self, id: &str);
17
18 fn all_known(&self) -> Vec<PeerEntry>;
20
21 fn expire_old(&mut self, cutoff: Instant);
23}
24
25#[derive(Default)]
26pub struct InMemoryPeerStore {
27 peers: HashMap<String, PeerEntry>,
28}
29
30impl InMemoryPeerStore {
31 pub fn new() -> Self {
32 Self {
33 peers: HashMap::new(),
34 }
35 }
36}
37
38impl PeerStore for InMemoryPeerStore {
39 fn upsert(&mut self, meta: PeerEntry) -> bool {
40 self.peers.insert(meta.coord_id.clone(), meta).is_none()
41 }
42
43 fn mark_alive(&mut self, id: &str) {
44 if let Some(entry) = self.peers.get_mut(id) {
45 entry.last_seen = Instant::now();
46 }
47 }
48
49 fn all_known(&self) -> Vec<PeerEntry> {
50 self.peers.values().cloned().collect()
51 }
52
53 fn expire_old(&mut self, cutoff: Instant) {
54 self.peers.retain(|_, e| e.last_seen >= cutoff);
55 }
56}