schnellru/
limiters.rs

1use crate::Limiter;
2
3/// A limiter for a map which is limited by the number of elements.
4#[derive(Copy, Clone, Debug)]
5#[repr(transparent)]
6pub struct ByLength {
7    max_length: u32,
8}
9
10impl ByLength {
11    /// Creates a new length limiter with a given `max_length`.
12    ///
13    /// If you don't need to strictly cap the number of elements and just want to limit
14    /// the memory usage then prefer using [`ByMemoryUsage`].
15    pub const fn new(max_length: u32) -> Self {
16        ByLength { max_length }
17    }
18
19    /// Returns the max length.
20    pub const fn max_length(&self) -> u32 {
21        self.max_length
22    }
23}
24
25impl<K, V> Limiter<K, V> for ByLength {
26    type KeyToInsert<'a> = K;
27    type LinkType = u32;
28
29    #[inline]
30    fn is_over_the_limit(&self, length: usize) -> bool {
31        length > self.max_length as usize
32    }
33
34    #[inline]
35    fn on_insert(&mut self, _length: usize, key: Self::KeyToInsert<'_>, value: V) -> Option<(K, V)> {
36        if self.max_length > 0 {
37            Some((key, value))
38        } else {
39            None
40        }
41    }
42
43    #[inline]
44    fn on_replace(
45        &mut self,
46        _length: usize,
47        _old_key: &mut K,
48        _new_key: K,
49        _old_value: &mut V,
50        _new_value: &mut V,
51    ) -> bool {
52        true
53    }
54
55    #[inline]
56    fn on_removed(&mut self, _key: &mut K, _value: &mut V) {}
57
58    #[inline]
59    fn on_cleared(&mut self) {}
60
61    #[inline]
62    fn on_grow(&mut self, _new_memory_usage: usize) -> bool {
63        true
64    }
65}
66
67/// A limiter for a map which is limited by memory usage.
68#[derive(Copy, Clone, Debug)]
69#[repr(transparent)]
70pub struct ByMemoryUsage {
71    max_bytes: usize,
72}
73
74impl ByMemoryUsage {
75    /// Creates a new memory usage limiter with a given limit in bytes.
76    pub const fn new(max_bytes: usize) -> Self {
77        ByMemoryUsage { max_bytes }
78    }
79
80    /// Returns the max memory usage.
81    pub const fn max_memory_usage(&self) -> usize {
82        self.max_bytes
83    }
84}
85
86impl<K, V> Limiter<K, V> for ByMemoryUsage {
87    type KeyToInsert<'a> = K;
88    type LinkType = u32;
89
90    #[inline]
91    fn is_over_the_limit(&self, _: usize) -> bool {
92        false
93    }
94
95    #[inline]
96    fn on_insert(&mut self, _length: usize, key: Self::KeyToInsert<'_>, value: V) -> Option<(K, V)> {
97        Some((key, value))
98    }
99
100    #[inline]
101    fn on_replace(
102        &mut self,
103        _length: usize,
104        _old_key: &mut K,
105        _new_key: K,
106        _old_value: &mut V,
107        _new_value: &mut V,
108    ) -> bool {
109        true
110    }
111
112    #[inline]
113    fn on_removed(&mut self, _key: &mut K, _value: &mut V) {}
114
115    #[inline]
116    fn on_cleared(&mut self) {}
117
118    #[inline]
119    fn on_grow(&mut self, new_memory_usage: usize) -> bool {
120        new_memory_usage <= self.max_bytes
121    }
122}
123
124/// A limiter for a map which can hold an unlimited number of elements.
125///
126/// With this limiter the map will act like a normal ordered hashmap.
127///
128/// On 64-bit systems it is less efficient and uses more memory than [`UnlimitedCompact`],
129/// but can hold a truly unlimited number of elements.
130///
131/// On 32-bit systems it is exactly the same as [`UnlimitedCompact`].
132#[derive(Copy, Clone, Debug, Default)]
133pub struct Unlimited;
134
135impl<K, V> Limiter<K, V> for Unlimited {
136    type KeyToInsert<'a> = K;
137    type LinkType = usize;
138
139    #[inline]
140    fn is_over_the_limit(&self, _: usize) -> bool {
141        false
142    }
143
144    #[inline]
145    fn on_insert(&mut self, _length: usize, key: Self::KeyToInsert<'_>, value: V) -> Option<(K, V)> {
146        Some((key, value))
147    }
148
149    #[inline]
150    fn on_replace(
151        &mut self,
152        _length: usize,
153        _old_key: &mut K,
154        _new_key: K,
155        _old_value: &mut V,
156        _new_value: &mut V,
157    ) -> bool {
158        true
159    }
160
161    #[inline]
162    fn on_removed(&mut self, _key: &mut K, _value: &mut V) {}
163
164    #[inline]
165    fn on_cleared(&mut self) {}
166
167    #[inline]
168    fn on_grow(&mut self, _new_memory_usage: usize) -> bool {
169        true
170    }
171}
172
173/// A limiter for a map which can hold an unlimited** number of elements.
174///
175/// ** - limited to around somewhere between a billion elements and two billion elements.
176/// If you need to store more use [`Unlimited`].
177#[derive(Copy, Clone, Debug, Default)]
178pub struct UnlimitedCompact;
179
180impl<K, V> Limiter<K, V> for UnlimitedCompact {
181    type KeyToInsert<'a> = K;
182    type LinkType = u32;
183
184    #[inline]
185    fn is_over_the_limit(&self, _: usize) -> bool {
186        false
187    }
188
189    #[inline]
190    fn on_insert(&mut self, _length: usize, key: Self::KeyToInsert<'_>, value: V) -> Option<(K, V)> {
191        Some((key, value))
192    }
193
194    #[inline]
195    fn on_replace(
196        &mut self,
197        _length: usize,
198        _old_key: &mut K,
199        _new_key: K,
200        _old_value: &mut V,
201        _new_value: &mut V,
202    ) -> bool {
203        true
204    }
205
206    #[inline]
207    fn on_removed(&mut self, _key: &mut K, _value: &mut V) {}
208
209    #[inline]
210    fn on_cleared(&mut self) {}
211
212    #[inline]
213    fn on_grow(&mut self, _new_memory_usage: usize) -> bool {
214        true
215    }
216}