aboutsummaryrefslogtreecommitdiff
path: root/src/ageset.rs
blob: 084afbac35c60645a533a0245ec5568011a1ad0d (plain)
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
use std::collections::HashSet;
use std::hash::Hash;

use blist::BList;

/// So... this is a rather weird thing.
/// It allows to semi-efficiently check the oldest (earliest insertion)
/// elements for certain criteria and remove them in the order of insertion
/// if the criteria is met.
pub struct AgeSet<T> {
    fifo: BList<T>,
    set: HashSet<T>
}

impl<T> AgeSet<T> where T: Eq + Hash + Clone {
    pub fn new() -> Self {
        AgeSet {
            fifo: BList::new(),
            set: HashSet::new()
        }
    }

    pub fn contains(&self, t: &T) -> bool {
        self.set.contains(t)
    }

    pub fn prune<F>(&mut self, kill: F) where F: Fn(&T) -> bool {
        while let Some(ref e) = self.fifo.front().map(T::clone) {
            if kill(&e) {
                let removed = self.fifo.pop_front().unwrap();
                self.set.remove(&e);
                assert!(*e == removed);
            } else { break }
        }
    }

    pub fn push(&mut self, t: T) {
        self.fifo.push_back(t.clone());
        self.set.insert(t);
    }
}