risotto_lib/state_store/
memory.rs1use serde::{Deserialize, Serialize};
2use std::collections::{HashMap, HashSet};
3use std::net::IpAddr;
4
5use crate::state::TimedPrefix;
6use crate::state_store::store::StateStore;
7use crate::update::Update;
8
9#[derive(Serialize, Deserialize)]
10pub struct MemoryStore {
11 routers: HashMap<IpAddr, Router>,
12}
13
14impl MemoryStore {
15 pub fn new() -> MemoryStore {
16 MemoryStore {
17 routers: HashMap::new(),
18 }
19 }
20
21 fn _get_router(&mut self, router_addr: &IpAddr) -> &mut Router {
22 let router = self.routers.entry(*router_addr).or_insert(Router::new());
23 router
24 }
25}
26
27impl StateStore for MemoryStore {
28 fn add_peer(&mut self, router_addr: &IpAddr, peer_addr: &IpAddr) {
29 let router = self._get_router(router_addr);
30 router.add_peer(peer_addr);
31 }
32
33 fn remove_peer(&mut self, router_addr: &IpAddr, peer_addr: &IpAddr) {
34 let router = self._get_router(router_addr);
35 router.remove_peer(peer_addr);
36 }
37
38 fn get_peers(&self) -> Vec<(IpAddr, IpAddr)> {
39 let mut peers = Vec::new();
40 for (router_addr, router) in &self.routers {
41 for peer_addr in router.peers.keys() {
42 peers.push((*router_addr, *peer_addr));
43 }
44 }
45 peers
46 }
47
48 fn get_updates_by_peer(&self, router_addr: &IpAddr, peer_addr: &IpAddr) -> Vec<TimedPrefix> {
49 let router_binding = Router::new();
50 let router = self.routers.get(router_addr).unwrap_or(&router_binding);
51 let peer = match router.peers.get(&*peer_addr) {
52 Some(peer) => peer,
53 None => return Vec::new(),
54 };
55
56 peer.updates.iter().cloned().collect()
57 }
58
59 fn update(&mut self, router_addr: &IpAddr, peer_addr: &IpAddr, update: &Update) -> bool {
60 let router = self._get_router(router_addr);
61 router.update(peer_addr, update)
62 }
63}
64
65#[derive(Serialize, Deserialize, Clone)]
66pub struct Peer {
67 pub peer_addr: IpAddr,
68 pub updates: HashSet<TimedPrefix>,
69}
70
71#[derive(Serialize, Deserialize)]
72pub struct Router {
73 peers: HashMap<IpAddr, Peer>,
74}
75
76impl Router {
77 fn new() -> Router {
78 Router {
79 peers: HashMap::new(),
80 }
81 }
82
83 fn add_peer(&mut self, peer_addr: &IpAddr) {
84 self.peers.entry(*peer_addr).or_insert_with(|| Peer {
85 peer_addr: peer_addr.clone(),
86 updates: HashSet::new(),
87 });
88 }
89
90 fn remove_peer(&mut self, peer_addr: &IpAddr) {
91 self.peers.remove(&peer_addr);
92 }
93
94 fn update(&mut self, peer_addr: &IpAddr, update: &Update) -> bool {
95 self.add_peer(peer_addr);
96 let peer = self.peers.get_mut(&peer_addr).unwrap();
97
98 let now: i64 = chrono::Utc::now().timestamp_millis();
99 let timed_prefix = TimedPrefix {
100 prefix_addr: update.prefix_addr,
101 prefix_len: update.prefix_len,
102 is_post_policy: update.is_post_policy,
103 is_adj_rib_out: update.is_adj_rib_out,
104 timestamp: now,
105 };
106
107 let emit = update.announced ^ peer.updates.contains(&timed_prefix);
110
111 if update.announced {
112 peer.updates.replace(timed_prefix);
114 } else {
115 peer.updates.remove(&timed_prefix);
117 }
118 emit
119 }
120}