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
67impl From<u32> for ByLength {
68    fn from(max_length: u32) -> Self {
69        Self::new(max_length)
70    }
71}
72
73/// A limiter for a map which is limited by memory usage.
74#[derive(Copy, Clone, Debug)]
75#[repr(transparent)]
76pub struct ByMemoryUsage {
77    max_bytes: usize,
78}
79
80impl ByMemoryUsage {
81    /// Creates a new memory usage limiter with a given limit in bytes.
82    pub const fn new(max_bytes: usize) -> Self {
83        ByMemoryUsage { max_bytes }
84    }
85
86    /// Returns the max memory usage.
87    pub const fn max_memory_usage(&self) -> usize {
88        self.max_bytes
89    }
90}
91
92impl<K, V> Limiter<K, V> for ByMemoryUsage {
93    type KeyToInsert<'a> = K;
94    type LinkType = u32;
95
96    #[inline]
97    fn is_over_the_limit(&self, _: usize) -> bool {
98        false
99    }
100
101    #[inline]
102    fn on_insert(&mut self, _length: usize, key: Self::KeyToInsert<'_>, value: V) -> Option<(K, V)> {
103        Some((key, value))
104    }
105
106    #[inline]
107    fn on_replace(
108        &mut self,
109        _length: usize,
110        _old_key: &mut K,
111        _new_key: K,
112        _old_value: &mut V,
113        _new_value: &mut V,
114    ) -> bool {
115        true
116    }
117
118    #[inline]
119    fn on_removed(&mut self, _key: &mut K, _value: &mut V) {}
120
121    #[inline]
122    fn on_cleared(&mut self) {}
123
124    #[inline]
125    fn on_grow(&mut self, new_memory_usage: usize) -> bool {
126        new_memory_usage <= self.max_bytes
127    }
128}
129
130impl From<usize> for ByMemoryUsage {
131    fn from(max_bytes: usize) -> Self {
132        Self::new(max_bytes)
133    }
134}
135
136/// A limiter for a map which can hold an unlimited number of elements.
137///
138/// With this limiter the map will act like a normal ordered hashmap.
139///
140/// On 64-bit systems it is less efficient and uses more memory than [`UnlimitedCompact`],
141/// but can hold a truly unlimited number of elements.
142///
143/// On 32-bit systems it is exactly the same as [`UnlimitedCompact`].
144#[derive(Copy, Clone, Debug, Default)]
145pub struct Unlimited;
146
147impl<K, V> Limiter<K, V> for Unlimited {
148    type KeyToInsert<'a> = K;
149    type LinkType = usize;
150
151    #[inline]
152    fn is_over_the_limit(&self, _: usize) -> bool {
153        false
154    }
155
156    #[inline]
157    fn on_insert(&mut self, _length: usize, key: Self::KeyToInsert<'_>, value: V) -> Option<(K, V)> {
158        Some((key, value))
159    }
160
161    #[inline]
162    fn on_replace(
163        &mut self,
164        _length: usize,
165        _old_key: &mut K,
166        _new_key: K,
167        _old_value: &mut V,
168        _new_value: &mut V,
169    ) -> bool {
170        true
171    }
172
173    #[inline]
174    fn on_removed(&mut self, _key: &mut K, _value: &mut V) {}
175
176    #[inline]
177    fn on_cleared(&mut self) {}
178
179    #[inline]
180    fn on_grow(&mut self, _new_memory_usage: usize) -> bool {
181        true
182    }
183}
184
185/// A limiter for a map which can hold an unlimited** number of elements.
186///
187/// ** - limited to around somewhere between a billion elements and two billion elements.
188/// If you need to store more use [`Unlimited`].
189#[derive(Copy, Clone, Debug, Default)]
190pub struct UnlimitedCompact;
191
192impl<K, V> Limiter<K, V> for UnlimitedCompact {
193    type KeyToInsert<'a> = K;
194    type LinkType = u32;
195
196    #[inline]
197    fn is_over_the_limit(&self, _: usize) -> bool {
198        false
199    }
200
201    #[inline]
202    fn on_insert(&mut self, _length: usize, key: Self::KeyToInsert<'_>, value: V) -> Option<(K, V)> {
203        Some((key, value))
204    }
205
206    #[inline]
207    fn on_replace(
208        &mut self,
209        _length: usize,
210        _old_key: &mut K,
211        _new_key: K,
212        _old_value: &mut V,
213        _new_value: &mut V,
214    ) -> bool {
215        true
216    }
217
218    #[inline]
219    fn on_removed(&mut self, _key: &mut K, _value: &mut V) {}
220
221    #[inline]
222    fn on_cleared(&mut self) {}
223
224    #[inline]
225    fn on_grow(&mut self, _new_memory_usage: usize) -> bool {
226        true
227    }
228}