toolbox_rs/
renumbering_table.rs1use fxhash::FxHashMap;
2
3enum Implementation {
4 Vec(Vec<usize>),
5 Map(FxHashMap<usize, usize>),
6}
7
8pub struct RenumberingTable {
9 table: Implementation,
10}
11
12impl RenumberingTable {
13 pub fn new_with_size_hint(universe_size: usize, usage_bound: usize) -> Self {
14 debug_assert!(universe_size >= usage_bound);
15
16 let factor = universe_size / usage_bound;
17 if factor > 8 {
18 return Self {
20 table: Implementation::Map(FxHashMap::default()),
21 };
22 }
23
24 let mut vector = Vec::new();
25 vector.resize(universe_size, usize::MAX);
26 Self {
27 table: Implementation::Vec(vector),
28 }
29 }
30
31 pub fn set(&mut self, key: usize, value: usize) {
32 match &mut self.table {
33 Implementation::Vec(vector) => vector[key] = value,
34 Implementation::Map(map) => {
35 map.insert(key, value);
36 }
37 }
38 }
39
40 pub fn get(&self, key: usize) -> usize {
41 match &self.table {
42 Implementation::Vec(vector) => vector[key],
43 Implementation::Map(map) => *map.get(&key).unwrap(),
44 }
45 }
46
47 pub fn contains_key(&self, key: usize) -> bool {
48 match &self.table {
49 Implementation::Vec(vector) => vector[key] != usize::MAX,
50 Implementation::Map(map) => map.contains_key(&key),
51 }
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::RenumberingTable;
58
59 #[test]
60 fn full_universe() {
61 let mut table = RenumberingTable::new_with_size_hint(10, 10);
62 for i in 0..10 {
63 table.set(i, 10 - i);
64 }
65 for i in 0..10 {
66 assert_eq!(10 - i, table.get(i));
67 }
68 }
69
70 #[test]
71 fn sparse_universe() {
72 let mut table = RenumberingTable::new_with_size_hint(10000, 10);
73 for i in 0..10 {
74 table.set(1234 + i, i);
75 }
76 for i in 0..10 {
77 assert_eq!(i, table.get(1234 + i));
78 }
79 for i in 0..1234 {
80 assert!(!table.contains_key(i));
81 }
82 for i in 1234..1244 {
83 assert!(table.contains_key(i));
84 }
85 for i in 1244..10000 {
86 assert!(!table.contains_key(i));
87 }
88 }
89}