Skip to main content

dtrees_rs/caching/
helpers.rs

1use std::collections::BTreeSet;
2
3/// How to find an entry: by its position, or by its itemset.
4pub enum CacheKey {
5    /// Position in the cache.
6    Index(usize),
7    /// Sorted itemset of the path to the entry.
8    Path(Vec<usize>),
9}
10
11/// The set of items on the path from the root to the current node, kept
12/// sorted.
13#[derive(Default)]
14pub struct SearchPath {
15    inner: BTreeSet<usize>,
16}
17
18/// Result of a cache insertion.
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20pub enum Index {
21    /// A new entry whose position is not known.
22    NewUnknown,
23    /// A new (or never evaluated) entry at this position.
24    New(usize),
25    /// An entry evaluated before, at this position.
26    Existing(usize),
27}
28
29impl SearchPath {
30    pub fn new() -> Self {
31        Self {
32            inner: BTreeSet::new(),
33        }
34    }
35
36    pub fn push(&mut self, value: usize) {
37        self.inner.insert(value);
38    }
39
40    pub fn remove(&mut self, value: &usize) {
41        self.inner.remove(value);
42    }
43
44    /// The path as a cache key.
45    pub fn to_key(&self) -> CacheKey {
46        CacheKey::Path(self.inner.iter().copied().collect())
47    }
48
49    /// The items of the path, sorted.
50    pub fn to_sorted_vec(&self) -> Vec<usize> {
51        self.inner.iter().copied().collect()
52    }
53}
54
55impl CacheKey {
56    pub fn from_index(index: usize) -> CacheKey {
57        CacheKey::Index(index)
58    }
59
60    pub fn from_path(path: &SearchPath) -> CacheKey {
61        path.to_key()
62    }
63}
64
65impl Index {
66    pub fn new_unknown() -> Self {
67        Index::NewUnknown
68    }
69
70    pub fn new_at(position: usize) -> Self {
71        Index::New(position)
72    }
73
74    pub fn existing(position: usize) -> Self {
75        Index::Existing(position)
76    }
77
78    /// Whether the entry has not been evaluated yet.
79    pub fn is_new(&self) -> bool {
80        matches!(self, Index::New(_) | Index::NewUnknown)
81    }
82
83    pub fn position(&self) -> Option<usize> {
84        match self {
85            Index::New(pos) | Index::Existing(pos) => Some(*pos),
86            Index::NewUnknown => None,
87        }
88    }
89
90    pub fn has_position(&self) -> bool {
91        !matches!(self, Index::NewUnknown)
92    }
93
94    /// A key for the entry: its position when known, `fallback_path`
95    /// otherwise.
96    pub fn to_cache_key(&self, fallback_path: &SearchPath) -> CacheKey {
97        match self {
98            Index::New(pos) | Index::Existing(pos) => CacheKey::Index(*pos),
99            Index::NewUnknown => fallback_path.to_key(),
100        }
101    }
102}