1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use std::collections::{HashMap, HashSet};
use std::sync::Arc;

use chrono::{DateTime, Utc};
use log::error;

use super::{ExportEntry, Families};

pub struct SessionRoutes {
    pub families: Families,
    pub routes: HashMap<DateTime<Utc>, Arc<ExportEntry>>,
    pending: HashSet<DateTime<Utc>>,
    advertised: HashSet<DateTime<Utc>>,
}

impl SessionRoutes {
    pub fn new(families: Families) -> Self {
        Self {
            families,
            routes: HashMap::new(),
            pending: HashSet::new(),
            advertised: HashSet::new(),
        }
    }

    pub fn pending(&self) -> Vec<Arc<ExportEntry>> {
        self.routes
            .iter()
            .filter(|(ts, _)| self.pending.contains(ts))
            .filter(|(_, entry)| self.families.contains(entry.update.family))
            .map(|(_, entry)| entry.clone())
            .collect()
    }
    pub fn advertised(&self) -> Vec<Arc<ExportEntry>> {
        self.routes
            .iter()
            .filter(|(ts, _)| self.advertised.contains(ts))
            .filter(|(_, entry)| self.families.contains(entry.update.family))
            .map(|(_, entry)| entry.clone())
            .collect()
    }

    pub fn insert_routes(&mut self, entries: Vec<Arc<ExportEntry>>) {
        for entry in entries.into_iter() {
            let ts = entry.timestamp;
            // If this entry is not present, add to pending routes
            if self.routes.insert(ts, entry).is_none() {
                self.pending.insert(ts);
            }
        }
    }

    pub fn mark_advertised(&mut self, entry: &Arc<ExportEntry>) {
        let ts = entry.timestamp;
        if !self.pending.remove(&ts) {
            error!("No route to remove: {}", ts);
        }
        self.advertised.insert(ts);
    }
}