dfir_rs/util/
sparse_vec.rs1use std::collections::HashMap;
3use std::hash::Hash;
4use std::iter::FusedIterator;
5
6#[derive(Clone, Debug)]
8pub struct SparseVec<T> {
9 items: Vec<Option<T>>,
10 item_locs: HashMap<T, Vec<usize>>,
11}
12
13impl<T> Default for SparseVec<T> {
14 fn default() -> Self {
15 SparseVec {
16 items: Vec::default(),
17 item_locs: HashMap::default(),
18 }
19 }
20}
21
22impl<T: Clone + Eq + Hash> SparseVec<T> {
23 pub fn push(&mut self, item: T) {
25 self.items.push(Some(item.clone()));
26 self.item_locs
27 .entry(item)
28 .or_insert(Vec::with_capacity(1))
29 .push(self.items.len() - 1);
30 }
31
32 pub fn delete(&mut self, item: &T) {
34 if let Some(indices) = self.item_locs.remove(item) {
35 for index in indices {
36 self.items[index] = None;
37 }
38 }
39 }
40
41 pub fn iter(&self) -> SparseVecIter<'_, T> {
43 SparseVecIter { vec: self, idx: 0 }
44 }
45}
46
47#[derive(Clone)]
49pub struct SparseVecIter<'a, T> {
50 vec: &'a SparseVec<T>,
51 idx: usize,
52}
53
54impl<'a, T> Iterator for SparseVecIter<'a, T> {
55 type Item = &'a T;
56
57 fn next(&mut self) -> Option<Self::Item> {
58 while self.idx < self.vec.items.len() {
59 let item = &self.vec.items[self.idx];
60 self.idx += 1;
61 if let Some(item) = item {
62 return Some(item);
63 }
64 }
65 None
66 }
67}
68
69impl<'a, T> FusedIterator for SparseVecIter<'a, T> {}
70
71#[cfg(test)]
72mod test {
73 use super::*;
74
75 fn collect<T: Eq + Hash + Clone>(sv: &SparseVec<T>) -> Vec<T> {
76 sv.iter().cloned().collect()
77 }
78
79 #[test]
80 fn basic() {
81 let mut x = SparseVec::default();
82
83 x.push(0);
84 x.push(1);
85 x.push(2);
86
87 x.delete(&1);
88
89 assert_eq!(collect(&x), vec![0, 2]);
90 }
91
92 #[test]
93 fn can_implement_default_on_types_that_dont_implement_default() {
94 struct NoDefault;
95
96 let x = SparseVec::<NoDefault>::default();
97
98 assert_eq!(x.items.len(), 0);
99 assert_eq!(x.item_locs.len(), 0);
100 }
101}