dynamo_mocker/cache/
hash_cache.rs1use crate::common::evictor::LRUEvictor;
5use dynamo_tokens::blocks::UniqueBlock;
6use std::collections::HashMap;
7
8pub struct HashCache {
11 active_blocks: HashMap<UniqueBlock, usize>,
12 inactive_blocks: LRUEvictor<UniqueBlock>,
13 max_capacity: usize,
14}
15
16impl HashCache {
17 pub fn new(max_capacity: usize) -> Self {
19 Self {
20 active_blocks: HashMap::new(),
21 inactive_blocks: LRUEvictor::default(),
22 max_capacity,
23 }
24 }
25
26 pub fn get_active_ref_count(&self, block: &UniqueBlock) -> Option<usize> {
28 self.active_blocks.get(block).copied()
29 }
30
31 pub fn increment_ref(&mut self, block: &UniqueBlock) -> usize {
33 let ref_count = self
34 .active_blocks
35 .get_mut(block)
36 .expect("block must be active to increment ref");
37 *ref_count += 1;
38 *ref_count
39 }
40
41 pub fn decrement_ref(&mut self, block: &UniqueBlock) -> usize {
43 let ref_count = self
44 .active_blocks
45 .get_mut(block)
46 .expect("block must be active to decrement ref");
47 *ref_count -= 1;
48 *ref_count
49 }
50
51 pub fn insert_active(&mut self, block: UniqueBlock, ref_count: usize) {
53 self.active_blocks.insert(block, ref_count);
54 }
55
56 pub fn remove_active(&mut self, block: &UniqueBlock) -> Option<usize> {
58 self.active_blocks.remove(block)
59 }
60
61 pub fn contains_active(&self, block: &UniqueBlock) -> bool {
63 self.active_blocks.contains_key(block)
64 }
65
66 pub fn insert_inactive(&mut self, block: UniqueBlock) {
68 self.inactive_blocks.insert(block);
69 }
70
71 pub fn remove_inactive(&mut self, block: &UniqueBlock) -> bool {
73 self.inactive_blocks.remove(block)
74 }
75
76 pub fn evict_inactive(&mut self) -> Option<UniqueBlock> {
78 self.inactive_blocks.evict()
79 }
80
81 pub fn contains_inactive(&self, block: &UniqueBlock) -> bool {
83 self.inactive_blocks.contains(block)
84 }
85
86 pub fn contains(&self, block: &UniqueBlock) -> bool {
88 self.active_blocks.contains_key(block) || self.inactive_blocks.contains(block)
89 }
90
91 pub fn deactivate(&mut self, block: &UniqueBlock) {
93 debug_assert!(
94 self.active_blocks.contains_key(block),
95 "deactivate called on non-active block"
96 );
97 debug_assert!(
98 !self.inactive_blocks.contains(block),
99 "deactivate called on already-inactive block"
100 );
101 self.active_blocks.remove(block);
102 self.inactive_blocks.insert(block.clone());
103 }
104
105 pub fn reactivate(&mut self, block: &UniqueBlock) -> bool {
107 if self.inactive_blocks.remove(block) {
108 self.active_blocks.insert(block.clone(), 1);
109 true
110 } else {
111 false
112 }
113 }
114
115 pub fn is_at_capacity(&self) -> bool {
117 self.active_blocks.len() + self.inactive_blocks.len() >= self.max_capacity
118 }
119
120 pub fn num_active(&self) -> usize {
122 self.active_blocks.len()
123 }
124
125 pub fn num_inactive(&self) -> usize {
127 self.inactive_blocks.len()
128 }
129
130 pub fn max_capacity(&self) -> usize {
132 self.max_capacity
133 }
134
135 pub fn current_capacity(&self) -> usize {
137 self.active_blocks.len() + self.inactive_blocks.len()
138 }
139
140 pub fn active_keys(&self) -> impl Iterator<Item = &UniqueBlock> {
142 self.active_blocks.keys()
143 }
144
145 pub fn inactive_keys(&self) -> impl Iterator<Item = &UniqueBlock> {
147 self.inactive_blocks.keys()
148 }
149
150 pub fn active_blocks(&self) -> &HashMap<UniqueBlock, usize> {
152 &self.active_blocks
153 }
154}