/rust/registry/src/index.crates.io-1949cf8c6b5b557f/vart-0.9.3/src/art.rs
Line | Count | Source |
1 | | use core::panic; |
2 | | use std::cmp::min; |
3 | | use std::cmp::Ordering; |
4 | | use std::ops::RangeBounds; |
5 | | use std::sync::Arc; |
6 | | |
7 | | use crate::iter::IterItem; |
8 | | use crate::iter::QueryIterator; |
9 | | use crate::iter::VersionRange; |
10 | | use crate::iter::{Iter, Range}; |
11 | | use crate::node::{FlatNode, LeafValue, Node256, Node48, NodeTrait, TwigNode}; |
12 | | use crate::{KeyTrait, TrieError}; |
13 | | |
14 | | // Minimum and maximum number of children for Node4 |
15 | | const NODE4MIN: usize = 2; |
16 | | const NODE4MAX: usize = 4; |
17 | | |
18 | | // Minimum and maximum number of children for Node16 |
19 | | const NODE16MIN: usize = NODE4MAX + 1; |
20 | | const NODE16MAX: usize = 16; |
21 | | |
22 | | // Minimum and maximum number of children for Node48 |
23 | | const NODE48MIN: usize = NODE16MAX + 1; |
24 | | const NODE48MAX: usize = 48; |
25 | | |
26 | | // Minimum and maximum number of children for Node256 |
27 | | const NODE256MIN: usize = NODE48MAX + 1; |
28 | | |
29 | | /// A struct representing a node in an Adaptive Radix Trie. |
30 | | /// |
31 | | /// The `Node` struct encapsulates a single node within the adaptive radix trie structure. |
32 | | /// It holds information about the type of the node, which can be one of the various node types |
33 | | /// defined by the `NodeType` enum. |
34 | | /// |
35 | | /// # Type Parameters |
36 | | /// |
37 | | /// - `P`: A type implementing the `Prefix` trait, defining the key prefix for the node. |
38 | | /// - `V`: The type of value associated with the node. |
39 | | /// |
40 | | /// # Fields |
41 | | /// |
42 | | /// - `node_type`: The `NodeType` variant representing the type of the node, containing its |
43 | | /// specific structure and associated data. |
44 | | /// |
45 | | pub(crate) struct Node<P: KeyTrait, V: Clone> { |
46 | | pub(crate) node_type: NodeType<P, V>, // Type of the node |
47 | | } |
48 | | |
49 | | #[derive(Copy, Clone)] |
50 | | // An enum for the different types of queries on the TwigNode |
51 | | pub enum QueryType { |
52 | | LatestByVersion(u64), |
53 | | LatestByTs(u64), |
54 | | LastLessThanTs(u64), |
55 | | LastLessOrEqualTs(u64), |
56 | | FirstGreaterThanTs(u64), |
57 | | FirstGreaterOrEqualTs(u64), |
58 | | } |
59 | | |
60 | | /// An enumeration representing different types of nodes in an Adaptive Radix Trie. |
61 | | /// |
62 | | /// The `NodeType` enum encompasses various node types that can exist within the adaptive radix trie structure. |
63 | | /// It includes different types of inner nodes, such as `Node4`, `Node16`, `Node48`, and `Node256`, as well as the |
64 | | /// leaf nodes represented by `TwigNode`. |
65 | | /// |
66 | | /// # Type Parameters |
67 | | /// |
68 | | /// - `P`: A type implementing the `Prefix` trait, which is used to define the key prefix for each node. |
69 | | /// - `V`: The type of value associated with each node. |
70 | | /// |
71 | | /// # Variants |
72 | | /// |
73 | | /// - `Twig(TwigNode<P, V>)`: Represents a Twig node, which is a leaf node in the adaptive radix trie. |
74 | | /// - `Node4(FlatNode<P, Node<P, V>, 4>)`: Represents an inner node with 4 keys and 4 children. |
75 | | /// - `Node16(FlatNode<P, Node<P, V>, 16>)`: Represents an inner node with 16 keys and 16 children. |
76 | | /// - `Node48(Node48<P, Node<P, V>>)`: Represents an inner node with 256 keys and 48 children. |
77 | | /// - `Node256(Node256<P, Node<P, V>>)`: Represents an inner node with 256 keys and 256 children. |
78 | | /// |
79 | | pub(crate) enum NodeType<P: KeyTrait, V: Clone> { |
80 | | // Twig node of the adaptive radix trie |
81 | | Twig(TwigNode<P, V>), |
82 | | // Inner node of the adaptive radix trie |
83 | | Node4(FlatNode<P, Node<P, V>, 4>), // Node with 4 keys and 4 children |
84 | | Node16(FlatNode<P, Node<P, V>, 16>), // Node with 16 keys and 16 children |
85 | | Node48(Node48<P, Node<P, V>>), // Node with 256 keys and 48 children |
86 | | Node256(Node256<P, Node<P, V>>), // Node with 256 keys and 256 children |
87 | | } |
88 | | |
89 | | impl<P: KeyTrait, V: Clone> NodeType<P, V> { |
90 | 0 | pub(crate) fn set_prefix(&mut self, prefix: P) { |
91 | 0 | match self { |
92 | 0 | NodeType::Node4(n) => n.prefix = prefix, |
93 | 0 | NodeType::Node16(n) => n.prefix = prefix, |
94 | 0 | NodeType::Node48(n) => n.prefix = prefix, |
95 | 0 | NodeType::Node256(n) => n.prefix = prefix, |
96 | 0 | NodeType::Twig(n) => n.prefix = prefix, |
97 | | } |
98 | 0 | } Unexecuted instantiation: <vart::art::NodeType<vart::VariableSizeKey, alloc::string::String>>::set_prefix Unexecuted instantiation: <vart::art::NodeType<_, _>>::set_prefix |
99 | | |
100 | 0 | fn get_inner_twig(&self) -> Option<&Node<P, V>> { |
101 | 0 | match self { |
102 | 0 | NodeType::Node4(n) => n.inner_twig.as_deref(), |
103 | 0 | NodeType::Node16(n) => n.inner_twig.as_deref(), |
104 | 0 | NodeType::Node48(n) => n.inner_twig.as_deref(), |
105 | 0 | NodeType::Node256(n) => n.inner_twig.as_deref(), |
106 | 0 | NodeType::Twig(_) => None, |
107 | | } |
108 | 0 | } Unexecuted instantiation: <vart::art::NodeType<vart::VariableSizeKey, alloc::string::String>>::get_inner_twig Unexecuted instantiation: <vart::art::NodeType<_, _>>::get_inner_twig |
109 | | |
110 | 0 | fn get_inner_twig_mut(&mut self) -> Option<&mut Node<P, V>> { |
111 | 0 | match self { |
112 | 0 | NodeType::Node4(n) => Arc::get_mut(n.inner_twig.as_mut()?), |
113 | 0 | NodeType::Node16(n) => Arc::get_mut(n.inner_twig.as_mut()?), |
114 | 0 | NodeType::Node48(n) => Arc::get_mut(n.inner_twig.as_mut()?), |
115 | 0 | NodeType::Node256(n) => Arc::get_mut(n.inner_twig.as_mut()?), |
116 | 0 | NodeType::Twig(_) => None, |
117 | | } |
118 | 0 | } Unexecuted instantiation: <vart::art::NodeType<vart::VariableSizeKey, alloc::string::String>>::get_inner_twig_mut Unexecuted instantiation: <vart::art::NodeType<_, _>>::get_inner_twig_mut |
119 | | |
120 | 0 | fn clone_inner_twig(&self) -> Option<Arc<Node<P, V>>> { |
121 | 0 | match self { |
122 | 0 | NodeType::Node4(n) => n.inner_twig.clone(), |
123 | 0 | NodeType::Node16(n) => n.inner_twig.clone(), |
124 | 0 | NodeType::Node48(n) => n.inner_twig.clone(), |
125 | 0 | NodeType::Node256(n) => n.inner_twig.clone(), |
126 | 0 | NodeType::Twig(_) => panic!("Unexpected Twig node encountered in clone_inner_twig()"), |
127 | | } |
128 | 0 | } |
129 | | } |
130 | | |
131 | | impl<P: KeyTrait, V: Clone> Node<P, V> { |
132 | | /// Creates a new Twig node with a given prefix, key, value, and version. |
133 | | /// |
134 | | /// Constructs a new Twig node using the provided prefix, key, and value. The version |
135 | | /// indicates the time of the insertion. |
136 | | /// |
137 | | /// # Parameters |
138 | | /// |
139 | | /// - `prefix`: The common prefix for the node. |
140 | | /// - `key`: The key associated with the Twig node. |
141 | | /// - `value`: The value to be associated with the key. |
142 | | /// - `ts`: The version when the value was inserted. |
143 | | /// |
144 | | /// # Returns |
145 | | /// |
146 | | /// Returns a new `Node` instance with a Twig node containing the provided key, value, and version. |
147 | | /// |
148 | | #[inline] |
149 | 0 | pub(crate) fn new_twig(prefix: P, key: P, value: V, version: u64, ts: u64) -> Node<P, V> { |
150 | | // Create a new TwigNode instance using the provided prefix and key. |
151 | 0 | let mut twig = TwigNode::new(prefix, key); |
152 | | |
153 | | // Insert the provided value into the TwigNode along with the version. |
154 | 0 | twig.insert_mut(value, version, ts); |
155 | | |
156 | | // Return a new Node instance encapsulating the constructed Twig node. |
157 | 0 | Self { |
158 | 0 | node_type: NodeType::Twig(twig), |
159 | 0 | } |
160 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::new_twig Unexecuted instantiation: <vart::art::Node<_, _>>::new_twig |
161 | | |
162 | | /// Creates a new inner Node4 node with the provided prefix. |
163 | | /// |
164 | | /// Constructs a new Node4 node using the provided prefix. Node4 is an inner node |
165 | | /// type that can store up to 4 child pointers and uses arrays for keys and pointers. |
166 | | /// |
167 | | /// # Parameters |
168 | | /// |
169 | | /// - `prefix`: The common prefix for the Node4 node. |
170 | | /// |
171 | | /// # Returns |
172 | | /// |
173 | | /// Returns a new `Node` instance with an empty Node4 node. |
174 | | /// |
175 | | #[inline] |
176 | | #[allow(dead_code)] |
177 | 0 | pub(crate) fn new_node4(prefix: P) -> Self { |
178 | | // Create a new FlatNode instance using the provided prefix. |
179 | 0 | let flat_node = FlatNode::new(prefix); |
180 | | |
181 | | // Create a new Node4 instance with the constructed FlatNode. |
182 | 0 | Self { |
183 | 0 | node_type: NodeType::Node4(flat_node), |
184 | 0 | } |
185 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::new_node4 Unexecuted instantiation: <vart::art::Node<_, _>>::new_node4 |
186 | | |
187 | | /// Checks if the current node is full based on its type. |
188 | | /// |
189 | | /// Determines if the current node is full by comparing the number of children to its |
190 | | /// capacity, which varies based on the node type. |
191 | | /// |
192 | | /// # Returns |
193 | | /// |
194 | | /// Returns `true` if the node is full, `false` otherwise. |
195 | | /// |
196 | | #[inline] |
197 | 0 | fn is_full(&self) -> bool { |
198 | 0 | match &self.node_type { |
199 | 0 | NodeType::Node4(n) => n.num_children() >= n.size(), |
200 | 0 | NodeType::Node16(n) => n.num_children() >= n.size(), |
201 | 0 | NodeType::Node48(n) => n.num_children() >= n.size(), |
202 | 0 | NodeType::Node256(n) => n.num_children() > n.size(), |
203 | 0 | NodeType::Twig(_) => panic!("Unexpected Twig node encountered in is_full()"), |
204 | | } |
205 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::is_full Unexecuted instantiation: <vart::art::Node<_, _>>::is_full |
206 | | |
207 | | /// Adds a child node with the given key to the current node. |
208 | | /// |
209 | | /// Inserts a child node with the specified key into the current node. |
210 | | /// Depending on the node type, this may lead to growth if the node becomes full. |
211 | | /// |
212 | | /// # Parameters |
213 | | /// |
214 | | /// - `key`: The key associated with the child node. |
215 | | /// - `child`: The child node to be added. |
216 | | /// |
217 | | /// # Returns |
218 | | /// |
219 | | /// Returns a new `Node` instance with the added child node. |
220 | | /// |
221 | | #[inline] |
222 | 0 | fn add_child(&self, key: u8, child: Node<P, V>) -> Self { |
223 | 0 | let cloned_node = if self.is_full() { |
224 | 0 | self.grow() |
225 | | } else { |
226 | 0 | match &self.node_type { |
227 | 0 | NodeType::Node4(n) => Self { |
228 | 0 | node_type: NodeType::Node4(n.clone()), |
229 | 0 | }, |
230 | 0 | NodeType::Node16(n) => Self { |
231 | 0 | node_type: NodeType::Node16(n.clone()), |
232 | 0 | }, |
233 | 0 | NodeType::Node48(n) => Self { |
234 | 0 | node_type: NodeType::Node48(n.clone()), |
235 | 0 | }, |
236 | 0 | NodeType::Node256(n) => Self { |
237 | 0 | node_type: NodeType::Node256(n.clone()), |
238 | 0 | }, |
239 | 0 | NodeType::Twig(_) => panic!("Unexpected Twig node encountered in add_child()"), |
240 | | } |
241 | | }; |
242 | | |
243 | 0 | match cloned_node.node_type { |
244 | 0 | NodeType::Node4(mut n) => { |
245 | | // Add the child node to the Node4 instance. |
246 | 0 | n.add_child(key, child); |
247 | 0 | let node = NodeType::Node4(n); |
248 | | |
249 | | // Create a new Node instance with the updated NodeType. |
250 | 0 | Self { node_type: node } |
251 | | } |
252 | 0 | NodeType::Node16(mut n) => { |
253 | | // Add the child node to the Node16 instance. |
254 | 0 | n.add_child(key, child); |
255 | 0 | let node = NodeType::Node16(n); |
256 | | |
257 | | // Create a new Node instance with the updated NodeType. |
258 | 0 | Self { node_type: node } |
259 | | } |
260 | 0 | NodeType::Node48(mut n) => { |
261 | | // Add the child node to the Node48 instance. |
262 | 0 | n.add_child(key, child); |
263 | 0 | let node = NodeType::Node48(n); |
264 | | |
265 | | // Create a new Node instance with the updated NodeType. |
266 | 0 | Self { node_type: node } |
267 | | } |
268 | 0 | NodeType::Node256(mut n) => { |
269 | | // Add the child node to the Node256 instance. |
270 | 0 | n.add_child(key, child); |
271 | 0 | let node = NodeType::Node256(n); |
272 | | |
273 | | // Create a new Node instance with the updated NodeType. |
274 | 0 | Self { node_type: node } |
275 | | } |
276 | 0 | NodeType::Twig(_) => panic!("Unexpected Twig node encountered in add_child_mut()"), |
277 | | } |
278 | 0 | } |
279 | | |
280 | | #[inline] |
281 | 0 | fn add_child_mut(&mut self, key: u8, child: Node<P, V>) { |
282 | 0 | if self.is_full() { |
283 | 0 | let new_node = self.grow(); |
284 | 0 | *self = new_node; |
285 | 0 | } |
286 | | |
287 | 0 | match &mut self.node_type { |
288 | 0 | NodeType::Node4(ref mut n) => { |
289 | 0 | // Add the child node to the Node4 instance. |
290 | 0 | n.add_child(key, child); |
291 | 0 | } |
292 | 0 | NodeType::Node16(ref mut n) => { |
293 | 0 | // Add the child node to the Node16 instance. |
294 | 0 | n.add_child(key, child); |
295 | 0 | } |
296 | 0 | NodeType::Node48(ref mut n) => { |
297 | 0 | // Add the child node to the Node48 instance. |
298 | 0 | n.add_child(key, child); |
299 | 0 | } |
300 | 0 | NodeType::Node256(ref mut n) => { |
301 | 0 | // Add the child node to the Node256 instance. |
302 | 0 | n.add_child(key, child); |
303 | 0 | } |
304 | 0 | NodeType::Twig(_) => panic!("Unexpected Twig node encountered in add_child()"), |
305 | | } |
306 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::add_child_mut Unexecuted instantiation: <vart::art::Node<_, _>>::add_child_mut |
307 | | |
308 | | /// Grows the current node to the next bigger size. |
309 | | /// |
310 | | /// Grows the current node to a larger size based on its type. |
311 | | /// This method is typically used to upgrade nodes when they become full. |
312 | | /// |
313 | | /// ArtNodes of type NODE4 will grow to NODE16 |
314 | | /// ArtNodes of type NODE16 will grow to NODE48. |
315 | | /// ArtNodes of type NODE48 will grow to NODE256. |
316 | | /// ArtNodes of type NODE256 will not grow, as they are the biggest type of ArtNodes |
317 | | #[inline] |
318 | 0 | fn grow(&self) -> Self { |
319 | 0 | let node_type = match &self.node_type { |
320 | 0 | NodeType::Node4(n) => { |
321 | | // Grow a Node4 to a Node16 by resizing. |
322 | 0 | NodeType::Node16(n.resize()) |
323 | | } |
324 | 0 | NodeType::Node16(n) => { |
325 | | // Grow a Node16 to a Node48 by performing growth. |
326 | 0 | NodeType::Node48(n.grow()) |
327 | | } |
328 | 0 | NodeType::Node48(n) => { |
329 | | // Grow a Node48 to a Node256 by performing growth. |
330 | 0 | NodeType::Node256(n.grow()) |
331 | | } |
332 | | NodeType::Node256 { .. } => { |
333 | 0 | panic!("Node256 cannot be grown further"); |
334 | | } |
335 | 0 | NodeType::Twig(_) => panic!("Unexpected Twig node encountered in grow()"), |
336 | | }; |
337 | 0 | Self { node_type } |
338 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::grow Unexecuted instantiation: <vart::art::Node<_, _>>::grow |
339 | | |
340 | | /// Recursively searches for a child node with the specified key. |
341 | | /// |
342 | | /// Searches for a child node with the given key in the current node. |
343 | | /// The search continues recursively in the child nodes based on the node type. |
344 | | /// |
345 | | /// # Parameters |
346 | | /// |
347 | | /// - `key`: The key associated with the child node. |
348 | | /// |
349 | | /// # Returns |
350 | | /// |
351 | | /// Returns an `Option` containing a reference to the found child node or `None` if not found. |
352 | | /// |
353 | | #[inline] |
354 | 0 | fn find_child(&self, key: u8) -> Option<&Arc<Node<P, V>>> { |
355 | | // If there are no children, return None. |
356 | 0 | if self.num_children() == 0 { |
357 | 0 | return None; |
358 | 0 | } |
359 | | |
360 | | // Match the node type to find the child using the appropriate method. |
361 | 0 | match &self.node_type { |
362 | 0 | NodeType::Node4(n) => n.find_child(key), |
363 | 0 | NodeType::Node16(n) => n.find_child(key), |
364 | 0 | NodeType::Node48(n) => n.find_child(key), |
365 | 0 | NodeType::Node256(n) => n.find_child(key), |
366 | 0 | NodeType::Twig(_) => None, |
367 | | } |
368 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::find_child Unexecuted instantiation: <vart::art::Node<_, _>>::find_child |
369 | | |
370 | | #[inline] |
371 | 0 | fn find_child_mut(&mut self, key: u8) -> Option<&mut Node<P, V>> { |
372 | | // If there are no children, return None. |
373 | 0 | if self.num_children() == 0 { |
374 | 0 | return None; |
375 | 0 | } |
376 | | |
377 | | // Match the node type to find the child using the appropriate method. |
378 | 0 | match &mut self.node_type { |
379 | 0 | NodeType::Node4(n) => n.find_child_mut(key), |
380 | 0 | NodeType::Node16(n) => n.find_child_mut(key), |
381 | 0 | NodeType::Node48(n) => n.find_child_mut(key), |
382 | 0 | NodeType::Node256(n) => n.find_child_mut(key), |
383 | 0 | NodeType::Twig(_) => None, |
384 | | } |
385 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::find_child_mut Unexecuted instantiation: <vart::art::Node<_, _>>::find_child_mut |
386 | | |
387 | | /// Replaces a child node with a new node for the given key. |
388 | | /// |
389 | | /// Replaces the child node associated with the specified key with the provided new node. |
390 | | /// |
391 | | /// # Parameters |
392 | | /// |
393 | | /// - `key`: The key associated with the child node to be replaced. |
394 | | /// - `node`: The new node to replace the existing child node. |
395 | | /// |
396 | | /// # Returns |
397 | | /// |
398 | | /// Returns a new `Node` instance with the child node replaced. |
399 | | /// |
400 | 0 | fn replace_child(&self, key: u8, node: Arc<Node<P, V>>) -> Self { |
401 | 0 | match &self.node_type { |
402 | 0 | NodeType::Node4(n) => { |
403 | | // Replace the child node in the Node4 instance and update the NodeType. |
404 | 0 | let node = NodeType::Node4(n.replace_child(key, node)); |
405 | 0 | Self { node_type: node } |
406 | | } |
407 | 0 | NodeType::Node16(n) => { |
408 | | // Replace the child node in the Node16 instance and update the NodeType. |
409 | 0 | let node = NodeType::Node16(n.replace_child(key, node)); |
410 | 0 | Self { node_type: node } |
411 | | } |
412 | 0 | NodeType::Node48(n) => { |
413 | | // Replace the child node in the Node48 instance and update the NodeType. |
414 | 0 | let node = NodeType::Node48(n.replace_child(key, node)); |
415 | 0 | Self { node_type: node } |
416 | | } |
417 | 0 | NodeType::Node256(n) => { |
418 | | // Replace the child node in the Node256 instance and update the NodeType. |
419 | 0 | let node = NodeType::Node256(n.replace_child(key, node)); |
420 | 0 | Self { node_type: node } |
421 | | } |
422 | 0 | NodeType::Twig(_) => panic!("Unexpected Twig node encountered in replace_child()"), |
423 | | } |
424 | 0 | } |
425 | | |
426 | | /// Removes a child node with the specified key from the current node. |
427 | | /// |
428 | | /// Removes a child node with the provided key from the current node. |
429 | | /// Depending on the node type, this may trigger shrinking if the number of children becomes low. |
430 | | /// |
431 | | /// # Parameters |
432 | | /// |
433 | | /// - `key`: The key associated with the child node to be removed. |
434 | | /// |
435 | | /// # Returns |
436 | | /// |
437 | | /// Returns a new `Node` instance with the child node removed. |
438 | | /// |
439 | | #[inline] |
440 | 0 | fn delete_child(&self, key: u8) -> Self { |
441 | 0 | match &self.node_type { |
442 | 0 | NodeType::Node4(n) => { |
443 | | // Delete the child node from the Node4 instance and update the NodeType. |
444 | 0 | let node = NodeType::Node4(n.delete_child(key)); |
445 | 0 | let mut new_node = Self { node_type: node }; |
446 | | |
447 | | // Shrink if the number of remaining children is below the threshold and |
448 | | // there's no inner twig. |
449 | | // |
450 | | // Checking for the inner twig is only needed for Node4, because only its |
451 | | // shrink() implementation pulls up a single remaining child and replaces |
452 | | // itself with it in the tree. |
453 | 0 | if new_node.num_children() < NODE4MIN && new_node.get_inner_twig().is_none() { |
454 | 0 | new_node.shrink(); |
455 | 0 | } |
456 | | |
457 | 0 | new_node |
458 | | } |
459 | 0 | NodeType::Node16(n) => { |
460 | | // Delete the child node from the Node16 instance and update the NodeType. |
461 | 0 | let node = NodeType::Node16(n.delete_child(key)); |
462 | 0 | let mut new_node = Self { node_type: node }; |
463 | | |
464 | | // Check if the number of remaining children is below the threshold. |
465 | 0 | if new_node.num_children() < NODE16MIN { |
466 | 0 | new_node.shrink(); |
467 | 0 | } |
468 | | |
469 | 0 | new_node |
470 | | } |
471 | 0 | NodeType::Node48(n) => { |
472 | | // Delete the child node from the Node48 instance and update the NodeType. |
473 | 0 | let node = NodeType::Node48(n.delete_child(key)); |
474 | 0 | let mut new_node = Self { node_type: node }; |
475 | | |
476 | | // Check if the number of remaining children is below the threshold. |
477 | 0 | if new_node.num_children() < NODE48MIN { |
478 | 0 | new_node.shrink(); |
479 | 0 | } |
480 | | |
481 | 0 | new_node |
482 | | } |
483 | 0 | NodeType::Node256(n) => { |
484 | | // Delete the child node from the Node256 instance and update the NodeType. |
485 | 0 | let node = NodeType::Node256(n.delete_child(key)); |
486 | 0 | let mut new_node = Self { node_type: node }; |
487 | | |
488 | | // Check if the number of remaining children is below the threshold. |
489 | 0 | if new_node.num_children() < NODE256MIN { |
490 | 0 | new_node.shrink(); |
491 | 0 | } |
492 | | |
493 | 0 | new_node |
494 | | } |
495 | 0 | NodeType::Twig(_) => panic!("Unexpected Twig node encountered in delete_child()"), |
496 | | } |
497 | 0 | } |
498 | | |
499 | | /// Checks if the node type is a Twig node. |
500 | | /// |
501 | | /// Determines whether the current node is a Twig node based on its node type. |
502 | | /// |
503 | | /// # Returns |
504 | | /// |
505 | | /// Returns `true` if the node type is a Twig node, otherwise returns `false`. |
506 | | /// |
507 | | #[inline] |
508 | 0 | pub(crate) fn is_twig(&self) -> bool { |
509 | 0 | matches!(&self.node_type, NodeType::Twig(_)) |
510 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::is_twig Unexecuted instantiation: <vart::art::Node<_, _>>::is_twig |
511 | | |
512 | | /// Checks if the node type is an inner node. |
513 | | /// |
514 | | /// Determines whether the current node is an inner node, which includes Node4, Node16, Node48, and Node256. |
515 | | /// The check is performed based on the absence of a Twig node. |
516 | | /// |
517 | | /// # Returns |
518 | | /// |
519 | | /// Returns `true` if the node type is an inner node, otherwise returns `false`. |
520 | | /// |
521 | | #[allow(dead_code)] |
522 | 0 | pub(crate) fn is_inner(&self) -> bool { |
523 | 0 | !self.is_twig() |
524 | 0 | } |
525 | | |
526 | | /// Gets the prefix associated with the node. |
527 | | /// |
528 | | /// Retrieves the prefix associated with the current node based on its node type. |
529 | | /// |
530 | | /// # Returns |
531 | | /// |
532 | | /// Returns a reference to the prefix associated with the node. |
533 | | /// |
534 | | #[inline] |
535 | 0 | pub(crate) fn prefix(&self) -> &P { |
536 | 0 | match &self.node_type { |
537 | 0 | NodeType::Node4(n) => &n.prefix, |
538 | 0 | NodeType::Node16(n) => &n.prefix, |
539 | 0 | NodeType::Node48(n) => &n.prefix, |
540 | 0 | NodeType::Node256(n) => &n.prefix, |
541 | 0 | NodeType::Twig(n) => &n.prefix, |
542 | | } |
543 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::prefix Unexecuted instantiation: <vart::art::Node<_, _>>::prefix |
544 | | |
545 | | /// Sets the prefix for the node. |
546 | | /// |
547 | | /// Updates the prefix associated with the current node based on its node type. |
548 | | /// |
549 | | /// # Parameters |
550 | | /// |
551 | | /// - `prefix`: The new prefix to be associated with the node. |
552 | | /// |
553 | | #[inline] |
554 | 0 | fn set_prefix(&mut self, prefix: P) { |
555 | | // The prefixes of a node and its inner twig must be kept |
556 | | // the same, because remove() relies on this when replacing |
557 | | // a Node4 without children with its inner twig. |
558 | 0 | if let Some(inner_twig) = self.get_inner_twig_mut() { |
559 | 0 | inner_twig.prefix = prefix.clone(); |
560 | 0 | } else if let Some(inner_twig) = self.get_inner_twig() { |
561 | 0 | let mut cloned_twig = inner_twig.clone(); |
562 | 0 | cloned_twig.prefix = prefix.clone(); |
563 | 0 | self.set_inner_twig(cloned_twig); |
564 | 0 | } |
565 | | |
566 | 0 | self.node_type.set_prefix(prefix); |
567 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::set_prefix Unexecuted instantiation: <vart::art::Node<_, _>>::set_prefix |
568 | | |
569 | | /// Shrinks the current node to a smaller size. |
570 | | /// |
571 | | /// Shrinks the current node to a smaller size based on its type. |
572 | | /// This method is typically used to downgrade nodes when the number of children becomes low. |
573 | | /// |
574 | | /// ArtNodes of type NODE256 will shrink to NODE48 |
575 | | /// ArtNodes of type NODE48 will shrink to NODE16. |
576 | | /// ArtNodes of type NODE16 will shrink to NODE4. |
577 | | /// ArtNodes of type NODE4 will collapse into its first child. |
578 | | /// |
579 | | /// If that child is not a twig, it will concatenate its current prefix with that of its childs |
580 | | /// before replacing itself. |
581 | 0 | fn shrink(&mut self) { |
582 | 0 | match &mut self.node_type { |
583 | 0 | NodeType::Node4(n) => { |
584 | 0 | // Shrink Node4 to Node1 by resizing it. |
585 | 0 | // In an Adaptive Radix Tree (ART), when a node has only one child, |
586 | 0 | // it can be collapsed into its first child to save space and improve efficiency. |
587 | 0 | // During this process, the prefix of the current node and the prefix of the child node |
588 | 0 | // are combined (compressed) into a single prefix. |
589 | 0 | let (curr_prefix, child) = n.get_value_if_single_child(); |
590 | 0 | let child = child.unwrap(); |
591 | 0 | let child_type = child.node_type.clone(); |
592 | 0 | let new_prefix = curr_prefix.extend(child.prefix()); |
593 | 0 | self.node_type = child_type; |
594 | 0 | self.set_prefix(new_prefix); |
595 | 0 | } |
596 | 0 | NodeType::Node16(n) => { |
597 | 0 | // Shrink Node16 to Node4 by resizing it. |
598 | 0 | self.node_type = NodeType::Node4(n.resize()); |
599 | 0 | } |
600 | 0 | NodeType::Node48(n) => { |
601 | 0 | // Shrink Node48 to Node16 by obtaining the shrunken Node16 instance. |
602 | 0 | let n16 = n.shrink(); |
603 | 0 |
|
604 | 0 | // Update the node type to Node16 after the shrinking operation. |
605 | 0 | let new_node = NodeType::Node16(n16); |
606 | 0 | self.node_type = new_node; |
607 | 0 | } |
608 | 0 | NodeType::Node256(n) => { |
609 | 0 | // Shrink Node256 to Node48 by obtaining the shrunken Node48 instance. |
610 | 0 | let n48 = n.shrink(); |
611 | 0 |
|
612 | 0 | // Update the node type to Node48 after the shrinking operation. |
613 | 0 | self.node_type = NodeType::Node48(n48); |
614 | 0 | } |
615 | 0 | NodeType::Twig(_) => panic!("Twig node encountered in shrink()"), |
616 | | } |
617 | 0 | } |
618 | | |
619 | 0 | fn set_inner_twig(&mut self, leaf: TwigNode<P, V>) { |
620 | 0 | let node = Node { |
621 | 0 | node_type: NodeType::Twig(leaf), |
622 | 0 | }; |
623 | 0 | let new_leaf = Some(Arc::new(node)); |
624 | 0 | match &mut self.node_type { |
625 | 0 | NodeType::Node4(n) => { |
626 | 0 | n.inner_twig = new_leaf; |
627 | 0 | } |
628 | 0 | NodeType::Node16(n) => { |
629 | 0 | n.inner_twig = new_leaf; |
630 | 0 | } |
631 | 0 | NodeType::Node48(n) => { |
632 | 0 | n.inner_twig = new_leaf; |
633 | 0 | } |
634 | 0 | NodeType::Node256(n) => { |
635 | 0 | n.inner_twig = new_leaf; |
636 | 0 | } |
637 | 0 | NodeType::Twig(_) => panic!("Unexpected Twig node encountered in set_inner_twig()"), |
638 | | } |
639 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::set_inner_twig Unexecuted instantiation: <vart::art::Node<_, _>>::set_inner_twig |
640 | | |
641 | 0 | fn get_inner_twig(&self) -> Option<&TwigNode<P, V>> { |
642 | 0 | let leaf_node = self.node_type.get_inner_twig()?; |
643 | 0 | match &leaf_node.node_type { |
644 | 0 | NodeType::Twig(twig) => Some(twig), |
645 | 0 | _ => panic!("Unexpected non-Twig node encountered in get_inner_twig()"), |
646 | | } |
647 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::get_inner_twig Unexecuted instantiation: <vart::art::Node<_, _>>::get_inner_twig |
648 | | |
649 | 0 | fn get_inner_twig_mut(&mut self) -> Option<&mut TwigNode<P, V>> { |
650 | 0 | let leaf_node = self.node_type.get_inner_twig_mut()?; |
651 | 0 | match &mut leaf_node.node_type { |
652 | 0 | NodeType::Twig(twig) => Some(twig), |
653 | 0 | _ => panic!("Unexpected non-Twig node encountered in get_inner_twig_mut()"), |
654 | | } |
655 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::get_inner_twig_mut Unexecuted instantiation: <vart::art::Node<_, _>>::get_inner_twig_mut |
656 | | |
657 | 0 | fn delete_inner_twig(&self) -> Self { |
658 | 0 | let node_type = match &self.node_type { |
659 | 0 | NodeType::Node4(n) => { |
660 | 0 | let mut cloned = n.clone(); |
661 | 0 | cloned.inner_twig.take(); |
662 | 0 | NodeType::Node4(cloned) |
663 | | } |
664 | 0 | NodeType::Node16(n) => { |
665 | 0 | let mut cloned = n.clone(); |
666 | 0 | cloned.inner_twig.take(); |
667 | 0 | NodeType::Node16(cloned) |
668 | | } |
669 | 0 | NodeType::Node48(n) => { |
670 | 0 | let mut cloned = n.clone(); |
671 | 0 | cloned.inner_twig.take(); |
672 | 0 | NodeType::Node48(cloned) |
673 | | } |
674 | 0 | NodeType::Node256(n) => { |
675 | 0 | let mut cloned = n.clone(); |
676 | 0 | cloned.inner_twig.take(); |
677 | 0 | NodeType::Node256(cloned) |
678 | | } |
679 | 0 | NodeType::Twig(_) => panic!("Unexpected Twig node encountered in delete_inner_twig()"), |
680 | | }; |
681 | 0 | Self { node_type } |
682 | 0 | } |
683 | | |
684 | | #[inline] |
685 | 0 | pub(crate) fn num_children(&self) -> usize { |
686 | 0 | match &self.node_type { |
687 | 0 | NodeType::Node4(n) => n.num_children(), |
688 | 0 | NodeType::Node16(n) => n.num_children(), |
689 | 0 | NodeType::Node48(n) => n.num_children(), |
690 | 0 | NodeType::Node256(n) => n.num_children(), |
691 | 0 | NodeType::Twig(_) => 0, |
692 | | } |
693 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::num_children Unexecuted instantiation: <vart::art::Node<_, _>>::num_children |
694 | | |
695 | | #[inline] |
696 | 0 | pub(crate) fn get_leaf_by_query(&self, query_type: QueryType) -> Option<&Arc<LeafValue<V>>> { |
697 | 0 | let twig = if let NodeType::Twig(twig) = &self.node_type { |
698 | | // For a Twig node simply use its inner value. |
699 | 0 | twig |
700 | | } else { |
701 | | // For an interior node, use its inner Twig if exists. |
702 | 0 | self.get_inner_twig()? |
703 | | }; |
704 | | |
705 | 0 | twig.get_leaf_by_query(query_type) |
706 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::get_leaf_by_query Unexecuted instantiation: <vart::art::Node<_, _>>::get_leaf_by_query |
707 | | |
708 | | #[inline] |
709 | 0 | pub(crate) fn get_all_versions(&self) -> Option<Vec<(V, u64, u64)>> { |
710 | | // Unwrap the NodeType::Twig to access the TwigNode instance. |
711 | 0 | let NodeType::Twig(twig) = &self.node_type else { |
712 | 0 | return None; |
713 | | }; |
714 | | |
715 | | // Get the value from the TwigNode instance by the specified version. |
716 | 0 | let val = twig.get_all_versions(); |
717 | | |
718 | | // Return the retrieved key, value, and version as a tuple. |
719 | 0 | Some(val) |
720 | 0 | } |
721 | | |
722 | | #[allow(unused)] |
723 | 0 | pub(crate) fn node_type_name(&self) -> String { |
724 | 0 | match &self.node_type { |
725 | 0 | NodeType::Node4(_) => "Node4".to_string(), |
726 | 0 | NodeType::Node16(_) => "Node16".to_string(), |
727 | 0 | NodeType::Node48(_) => "Node48".to_string(), |
728 | 0 | NodeType::Node256(_) => "Node256".to_string(), |
729 | 0 | NodeType::Twig(_) => "Twig".to_string(), |
730 | | } |
731 | 0 | } |
732 | | |
733 | | /// Creates a clone of the current node. |
734 | | /// |
735 | | /// Creates and returns a new instance of the current node with the same node type and contents. |
736 | | /// |
737 | | /// # Returns |
738 | | /// |
739 | | /// Returns a cloned instance of the current node with the same node type and contents. |
740 | | /// |
741 | 0 | fn clone_node(&self) -> Self { |
742 | | // Create a new instance with the same node type as the current node. |
743 | 0 | Self { |
744 | 0 | node_type: self.node_type.clone(), |
745 | 0 | } |
746 | 0 | } |
747 | | |
748 | | // Common logic for insert to extract common prefix and key prefix |
749 | 0 | fn common_insert_logic<'a>( |
750 | 0 | cur_node_prefix: &P, |
751 | 0 | key: &'a P, |
752 | 0 | depth: usize, |
753 | 0 | ) -> ( |
754 | 0 | &'a [u8], // remaining_key_suffix |
755 | 0 | P, // remaining_node_suffix |
756 | 0 | P, // shared_prefix |
757 | 0 | bool, // is_prefix_match |
758 | 0 | usize, // shared_prefix_length |
759 | 0 | ) { |
760 | | // Obtain the current node's prefix and its length. |
761 | 0 | let cur_node_prefix_len = cur_node_prefix.len(); |
762 | | |
763 | | // Determine the prefix of the key after the current depth. |
764 | 0 | let remaining_key_suffix = key.prefix_after(depth); |
765 | | |
766 | | // Find the longest common prefix between the current node's prefix and the key's prefix. |
767 | 0 | let shared_prefix_length = cur_node_prefix.longest_common_prefix(remaining_key_suffix); |
768 | | |
769 | | // Create a new key that represents the remaining part of the current node's prefix after the common prefix. |
770 | 0 | let mut remaining_node_suffix = cur_node_prefix.prefix_after(shared_prefix_length); |
771 | 0 | if remaining_node_suffix.is_empty() { |
772 | 0 | // In the case where the current node's prefix is shorter than the key, |
773 | 0 | // the suffix comes from the key_prefix. For example, cur_node.prefix="key" |
774 | 0 | // and key="keyboard", then remaining_node_suffix should be "board". |
775 | 0 | remaining_node_suffix = &remaining_key_suffix[shared_prefix_length..]; |
776 | 0 | } |
777 | | |
778 | | // Extract the prefix of the current node up to the common prefix. |
779 | 0 | let shared_prefix = cur_node_prefix.prefix_before(shared_prefix_length).into(); |
780 | | // Determine whether the current node's prefix and the key's prefix match up to the common prefix. |
781 | 0 | let is_prefix_match = |
782 | 0 | min(cur_node_prefix_len, remaining_key_suffix.len()) == shared_prefix_length; |
783 | | |
784 | 0 | ( |
785 | 0 | remaining_key_suffix, // remaining_key_suffix: the part of the key that still needs to be processed |
786 | 0 | remaining_node_suffix.into(), // remaining_node_suffix: the remaining part of the node's prefix after splitting |
787 | 0 | shared_prefix, // shared_prefix: the shared prefix that will become the new parent node |
788 | 0 | is_prefix_match, // is_prefix_match: whether the prefixes match completely up to the common point |
789 | 0 | shared_prefix_length, // shared_prefix_length: length of the shared prefix between node and key |
790 | 0 | ) |
791 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::common_insert_logic Unexecuted instantiation: <vart::art::Node<_, _>>::common_insert_logic |
792 | | |
793 | | /// Recursively inserts a key-value pair into the current node and its child nodes. |
794 | 0 | pub(crate) fn insert_recurse( |
795 | 0 | cur_node: &Arc<Node<P, V>>, |
796 | 0 | key: &P, |
797 | 0 | value: V, |
798 | 0 | commit_version: u64, |
799 | 0 | ts: u64, |
800 | 0 | depth: usize, |
801 | 0 | replace: bool, |
802 | 0 | ) -> NodeArc<P, V> { |
803 | 0 | let (key_prefix, new_prefix, shared_prefix, is_prefix_match, shared_prefix_length) = |
804 | 0 | Self::common_insert_logic(cur_node.prefix(), key, depth); |
805 | | |
806 | | // Case 1: No prefix match - create new Node4 with split |
807 | 0 | if !is_prefix_match { |
808 | | // If the prefixes don't match, create a new Node4 with the old node and a new Twig as children. |
809 | 0 | let mut old_node = cur_node.clone_node(); |
810 | 0 | old_node.set_prefix(new_prefix); |
811 | 0 | let k1 = cur_node.prefix().at(shared_prefix_length); |
812 | 0 | let k2 = key_prefix[shared_prefix_length]; |
813 | 0 | let new_twig = Node::new_twig( |
814 | 0 | key_prefix[shared_prefix_length..].into(), |
815 | 0 | key.as_slice().into(), |
816 | 0 | value, |
817 | 0 | commit_version, |
818 | 0 | ts, |
819 | | ); |
820 | | |
821 | 0 | let mut n4 = Node::new_node4(shared_prefix); |
822 | 0 | n4 = n4.add_child(k1, old_node).add_child(k2, new_twig); |
823 | 0 | return Arc::new(n4); |
824 | 0 | } |
825 | | |
826 | | // Case 2: Handle prefix match scenarios |
827 | 0 | let cur_prefix_len = cur_node.prefix().len(); |
828 | 0 | let key_prefix_len = key_prefix.len(); |
829 | | |
830 | 0 | match cur_prefix_len.cmp(&key_prefix_len) { |
831 | | // Case 2a: Exact prefix match |
832 | | Ordering::Equal => { |
833 | | // If the current node is a Twig node and the prefixes match up to the end of both prefixes, |
834 | | // update the existing value in the Twig node. |
835 | 0 | if let NodeType::Twig(twig) = &cur_node.node_type { |
836 | 0 | let new_twig = twig.insert_or_replace(value, commit_version, ts, replace); |
837 | 0 | Arc::new(Node { |
838 | 0 | node_type: NodeType::Twig(new_twig), |
839 | 0 | }) |
840 | | } else { |
841 | | // If the current node is an inner node, then either insert the new value |
842 | | // in its existing inner Twig node, or create new one. |
843 | 0 | let leaf = match cur_node.get_inner_twig() { |
844 | 0 | Some(twig) => twig.insert_or_replace(value, commit_version, ts, replace), |
845 | | None => { |
846 | 0 | let mut new_twig = |
847 | 0 | TwigNode::new(cur_node.prefix().clone(), key.as_slice().into()); |
848 | 0 | new_twig.insert_mut(value, commit_version, ts); |
849 | 0 | new_twig |
850 | | } |
851 | | }; |
852 | 0 | let mut new_node = cur_node.clone_node(); |
853 | 0 | new_node.set_inner_twig(leaf); |
854 | 0 | Arc::new(new_node) |
855 | | } |
856 | | } |
857 | | |
858 | | // Case 2b: Current prefix is shorter and node is Twig |
859 | | Ordering::Less => { |
860 | | // The current node is Twig and there is a prefix match and the current node's |
861 | | // prefix is shorter than the remainder of the key, e.g. current node is "key1" |
862 | | // and "key123" is inserted. |
863 | | // Current Twig must be replaced by a Node4, made its inner Twig node, and a new |
864 | | // Twig node created as a normal child node with a prefix being the reminder of |
865 | | // the new key. |
866 | 0 | let k = key_prefix[shared_prefix_length]; |
867 | | |
868 | | // Case 2b1: Current node is Twig |
869 | 0 | if let NodeType::Twig(twig) = &cur_node.node_type { |
870 | 0 | let mut n4 = Node::new_node4(shared_prefix); |
871 | 0 | n4.set_inner_twig(twig.clone()); |
872 | 0 | let new_twig = |
873 | 0 | Node::new_twig(new_prefix, key.clone(), value, commit_version, ts); |
874 | 0 | n4.add_child_mut(k, new_twig); |
875 | 0 | Arc::new(n4) |
876 | | } else { |
877 | | // Case 2b2: Continue traversal with existing child |
878 | 0 | if let Some(child) = cur_node.find_child(k) { |
879 | 0 | let new_child = Node::insert_recurse( |
880 | 0 | child, |
881 | 0 | key, |
882 | 0 | value, |
883 | 0 | commit_version, |
884 | 0 | ts, |
885 | 0 | depth + shared_prefix_length, |
886 | 0 | replace, |
887 | | ); |
888 | 0 | let new_node = cur_node.replace_child(k, new_child); |
889 | 0 | return Arc::new(new_node); |
890 | 0 | } |
891 | | |
892 | | // Case 2b3: Create new child node |
893 | 0 | let new_twig = Node::new_twig( |
894 | 0 | key_prefix[shared_prefix_length..].into(), |
895 | 0 | key.as_slice().into(), |
896 | 0 | value, |
897 | 0 | commit_version, |
898 | 0 | ts, |
899 | | ); |
900 | 0 | let new_node = cur_node.add_child(k, new_twig); |
901 | 0 | Arc::new(new_node) |
902 | | } |
903 | | } |
904 | | |
905 | | // Case 2c: Current prefix is longer |
906 | | Ordering::Greater => { |
907 | | // Similar to the case above, but this time the current node's prefix is longer |
908 | | // than the remainder of the key, e.g. current node is "key123" and "key1" is |
909 | | // inserted. |
910 | | // Current node is also replaced by a new Node4, but this time its prefix is |
911 | | // adjusted and it becomes the Node4's child, while the new Twig node becomes |
912 | | // Node4's inner Twig. |
913 | 0 | let mut inner_twig = TwigNode::new(key_prefix.into(), key.clone()); |
914 | 0 | inner_twig.insert_mut(value, commit_version, ts); |
915 | 0 | let old_node_key = new_prefix.at(0); |
916 | 0 | let mut old_node = cur_node.clone_node(); |
917 | 0 | old_node.set_prefix(new_prefix); |
918 | | |
919 | 0 | let mut n4 = Node::new_node4(key_prefix.into()); |
920 | 0 | n4.set_inner_twig(inner_twig); |
921 | 0 | n4.add_child_mut(old_node_key, old_node); |
922 | 0 | Arc::new(n4) |
923 | | } |
924 | | } |
925 | 0 | } |
926 | | |
927 | 0 | pub(crate) fn insert_recurse_mut( |
928 | 0 | cur_node: &mut Node<P, V>, |
929 | 0 | key: &P, |
930 | 0 | value: V, |
931 | 0 | commit_version: u64, |
932 | 0 | ts: u64, |
933 | 0 | depth: usize, |
934 | 0 | replace: bool, |
935 | 0 | ) { |
936 | 0 | let (key_prefix, new_prefix, shared_prefix, is_prefix_match, shared_prefix_length) = |
937 | 0 | Self::common_insert_logic(cur_node.prefix(), key, depth); |
938 | | |
939 | | // Case 1: No prefix match - create a new Node4 with old node and new Twig as children |
940 | 0 | if !is_prefix_match { |
941 | 0 | let n4 = Node::new_node4(shared_prefix); |
942 | | |
943 | 0 | let k1 = cur_node.prefix().at(shared_prefix_length); |
944 | 0 | let k2 = key_prefix[shared_prefix_length]; |
945 | | |
946 | | // Must be set after the calculation of k1 above |
947 | 0 | cur_node.set_prefix(new_prefix); |
948 | | |
949 | 0 | let old_node = std::mem::replace(cur_node, n4); |
950 | | |
951 | 0 | let new_twig = Node::new_twig( |
952 | 0 | key_prefix[shared_prefix_length..].into(), |
953 | 0 | key.as_slice().into(), |
954 | 0 | value, |
955 | 0 | commit_version, |
956 | 0 | ts, |
957 | | ); |
958 | 0 | cur_node.add_child_mut(k1, old_node); |
959 | 0 | cur_node.add_child_mut(k2, new_twig); |
960 | | |
961 | 0 | return; |
962 | 0 | } |
963 | | |
964 | | // Case 2: Handle prefix match scenarios |
965 | 0 | let cur_prefix_len = cur_node.prefix().len(); |
966 | 0 | let key_prefix_len = key_prefix.len(); |
967 | | |
968 | 0 | match cur_prefix_len.cmp(&key_prefix_len) { |
969 | | // Case 2a: Exact prefix match |
970 | | Ordering::Equal => { |
971 | | // If the current node is a Twig node and the prefixes match up to the |
972 | | // end of both prefixes, update the existing value in the Twig node. |
973 | 0 | if let NodeType::Twig(ref mut twig) = &mut cur_node.node_type { |
974 | 0 | if replace { |
975 | 0 | // Only replace if the provided value is more recent than |
976 | 0 | // the existing ones. This is important because this method |
977 | 0 | // is used for loading the index in SurrealKV and thus must |
978 | 0 | // be able to handle segments left by an unfinished compaction |
979 | 0 | // where older versions can end up in more recent segments |
980 | 0 | // after the newer versions. |
981 | 0 | twig.replace_if_newer_mut(value, commit_version, ts); |
982 | 0 | } else { |
983 | 0 | twig.insert_mut(value, commit_version, ts); |
984 | 0 | } |
985 | | } else { |
986 | | // If the current node is an inner node, then either insert the new value |
987 | | // in its existing inner Twig node, or create new one. |
988 | 0 | match cur_node.get_inner_twig_mut() { |
989 | 0 | Some(twig) => { |
990 | 0 | if replace { |
991 | 0 | twig.replace_if_newer_mut(value, commit_version, ts); |
992 | 0 | } else { |
993 | 0 | twig.insert_mut(value, commit_version, ts); |
994 | 0 | } |
995 | | } |
996 | 0 | None => { |
997 | 0 | let mut new_twig = |
998 | 0 | TwigNode::new(cur_node.prefix().clone(), key.as_slice().into()); |
999 | 0 | new_twig.insert_mut(value, commit_version, ts); |
1000 | 0 | cur_node.set_inner_twig(new_twig); |
1001 | 0 | } |
1002 | | } |
1003 | | } |
1004 | | } |
1005 | | |
1006 | | // Case 2b: Current prefix is shorter and node is Twig |
1007 | | // e.g., current node is "key1" and "key123" is inserted |
1008 | | Ordering::Less => { |
1009 | 0 | let k = key_prefix[shared_prefix_length]; |
1010 | 0 | if cur_node.is_twig() { |
1011 | | // The current node is Twig and there is a prefix match and the current node's |
1012 | | // prefix is shorter than the remainder of the key, e.g. current node is "key1" |
1013 | | // and "key123" is inserted. |
1014 | | // Current Twig must be replaced by a Node4, made its inner Twig node, and a new |
1015 | | // Twig node created as a normal child node with a prefix being the reminder of |
1016 | | // the new key. |
1017 | 0 | let n4 = Node::new_node4(shared_prefix); |
1018 | 0 | let old_twig = std::mem::replace(cur_node, n4); |
1019 | 0 | match old_twig.node_type { |
1020 | 0 | NodeType::Twig(n) => cur_node.set_inner_twig(n), |
1021 | 0 | _ => panic!("must be Twig"), |
1022 | | } |
1023 | 0 | let new_twig = |
1024 | 0 | Node::new_twig(new_prefix, key.clone(), value, commit_version, ts); |
1025 | 0 | cur_node.add_child_mut(k, new_twig); |
1026 | | } else { |
1027 | | // Case 2b2: Continue traversal with existing child |
1028 | 0 | if let Some(child) = cur_node.find_child_mut(k) { |
1029 | 0 | Node::insert_recurse_mut( |
1030 | 0 | child, |
1031 | 0 | key, |
1032 | 0 | value, |
1033 | 0 | commit_version, |
1034 | 0 | ts, |
1035 | 0 | depth + shared_prefix_length, |
1036 | 0 | replace, |
1037 | | ); |
1038 | 0 | return; |
1039 | 0 | } |
1040 | | |
1041 | | // Case 2b3: Create new child node |
1042 | | // If no child exists for the key's character, create a new Twig node and add it as a child. |
1043 | 0 | let new_twig = Node::new_twig( |
1044 | 0 | key_prefix[shared_prefix_length..].into(), |
1045 | 0 | key.as_slice().into(), |
1046 | 0 | value, |
1047 | 0 | commit_version, |
1048 | 0 | ts, |
1049 | | ); |
1050 | 0 | cur_node.add_child_mut(k, new_twig); |
1051 | | } |
1052 | | } |
1053 | | |
1054 | | // Case 2c: Current prefix is longer |
1055 | | // e.g., current node is "key123" and "key1" is inserted |
1056 | 0 | Ordering::Greater => { |
1057 | 0 | // Similar to the case above, but this time the current node's prefix is longer |
1058 | 0 | // than the remainder of the key, e.g. current node is "key123" and "key1" is |
1059 | 0 | // inserted. |
1060 | 0 | // Current node is also replaced by a new Node4, but this time its prefix is |
1061 | 0 | // adjusted and it becomes the Node4's child, while the new Twig node becomes |
1062 | 0 | // Node4's inner Twig. |
1063 | 0 | let n4 = Node::new_node4(key_prefix.into()); |
1064 | 0 | let mut old_node = std::mem::replace(cur_node, n4); |
1065 | 0 | let mut inner_twig = TwigNode::new(key_prefix.into(), key.clone()); |
1066 | 0 | inner_twig.insert_mut(value, commit_version, ts); |
1067 | 0 | cur_node.set_inner_twig(inner_twig); |
1068 | 0 | let old_node_key = new_prefix.at(0); |
1069 | 0 | old_node.set_prefix(new_prefix); |
1070 | 0 | cur_node.add_child_mut(old_node_key, old_node); |
1071 | 0 | } |
1072 | | } |
1073 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::insert_recurse_mut Unexecuted instantiation: <vart::art::Node<_, _>>::insert_recurse_mut |
1074 | | |
1075 | 0 | fn navigate_to_node<'a>(cur_node: &'a Node<P, V>, key: &P) -> Option<&'a Node<P, V>> { |
1076 | 0 | let mut cur_node = cur_node; |
1077 | 0 | let mut depth = 0; |
1078 | | |
1079 | | loop { |
1080 | 0 | let key_prefix = key.prefix_after(depth); |
1081 | 0 | let prefix = cur_node.prefix(); |
1082 | 0 | let lcp = prefix.longest_common_prefix(key_prefix); |
1083 | | |
1084 | 0 | if lcp != prefix.len() { |
1085 | 0 | return None; |
1086 | 0 | } |
1087 | | |
1088 | 0 | if prefix.len() == key_prefix.len() { |
1089 | 0 | return Some(cur_node); |
1090 | 0 | } |
1091 | | |
1092 | 0 | let k = key.at(depth + prefix.len()); |
1093 | 0 | depth += prefix.len(); |
1094 | | |
1095 | 0 | match cur_node.find_child(k) { |
1096 | 0 | Some(child) => cur_node = child, |
1097 | 0 | None => return None, |
1098 | | } |
1099 | | } |
1100 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::navigate_to_node Unexecuted instantiation: <vart::art::Node<_, _>>::navigate_to_node |
1101 | | |
1102 | | /// Recursively searches for a key in the node and its children. |
1103 | 0 | pub(crate) fn get_recurse( |
1104 | 0 | cur_node: &Node<P, V>, |
1105 | 0 | key: &P, |
1106 | 0 | query_type: QueryType, |
1107 | 0 | ) -> Option<(V, u64, u64)> { |
1108 | 0 | let cur_node = Self::navigate_to_node(cur_node, key)?; |
1109 | 0 | let val = cur_node.get_leaf_by_query(query_type)?; |
1110 | 0 | Some((val.value.clone(), val.version, val.ts)) |
1111 | 0 | } Unexecuted instantiation: <vart::art::Node<vart::VariableSizeKey, alloc::string::String>>::get_recurse Unexecuted instantiation: <vart::art::Node<_, _>>::get_recurse |
1112 | | |
1113 | 0 | pub(crate) fn get_version_history( |
1114 | 0 | cur_node: &Node<P, V>, |
1115 | 0 | key: &P, |
1116 | 0 | ) -> Option<Vec<(V, u64, u64)>> { |
1117 | 0 | Self::navigate_to_node(cur_node, key).and_then(|cur_node| cur_node.get_all_versions()) |
1118 | 0 | } |
1119 | | |
1120 | | /// Returns an iterator that iterates over child nodes of the current node. |
1121 | | /// |
1122 | | /// This function provides an iterator that traverses through the child nodes of the current node, |
1123 | | /// returning tuples of keys and references to child nodes. |
1124 | | /// |
1125 | | /// # Returns |
1126 | | /// |
1127 | | /// Returns a boxed iterator that yields tuples containing keys and references to child nodes. |
1128 | | /// |
1129 | 0 | pub(crate) fn iter(&self) -> Box<dyn DoubleEndedIterator<Item = &Arc<Self>> + '_> { |
1130 | 0 | match &self.node_type { |
1131 | 0 | NodeType::Node4(n) => Box::new(n.iter()), |
1132 | 0 | NodeType::Node16(n) => Box::new(n.iter()), |
1133 | 0 | NodeType::Node48(n) => Box::new(n.iter()), |
1134 | 0 | NodeType::Node256(n) => Box::new(n.iter()), |
1135 | 0 | NodeType::Twig(_) => Box::new(std::iter::empty()), |
1136 | | } |
1137 | 0 | } |
1138 | | } |
1139 | | |
1140 | | /// A struct representing an Adaptive Radix Trie. |
1141 | | /// |
1142 | | /// The `Tree` struct encompasses the entire adaptive radix trie data structure. |
1143 | | /// It manages the root node of the tree. |
1144 | | /// |
1145 | | /// # Type Parameters |
1146 | | /// |
1147 | | /// - `P`: A type implementing the `KeyTrait` trait, defining the prefix traits for nodes. |
1148 | | /// - `V`: The type of value associated with nodes. |
1149 | | /// |
1150 | | /// # Fields |
1151 | | /// |
1152 | | /// - `root`: An optional shared reference (using `Rc`) to the root node of the tree. |
1153 | | /// |
1154 | | pub struct Tree<P: KeyTrait, V: Clone> { |
1155 | | /// An optional shared reference to the root node of the tree. |
1156 | | pub(crate) root: Option<Arc<Node<P, V>>>, |
1157 | | pub size: usize, |
1158 | | pub version: u64, |
1159 | | } |
1160 | | |
1161 | | // A type alias for a node reference. |
1162 | | type NodeArc<P, V> = Arc<Node<P, V>>; |
1163 | | |
1164 | | impl<P: KeyTrait, V: Clone> NodeType<P, V> { |
1165 | 0 | fn clone(&self) -> Self { |
1166 | 0 | match self { |
1167 | | // twig value not actually cloned |
1168 | 0 | NodeType::Twig(twig) => NodeType::Twig(twig.clone()), |
1169 | 0 | NodeType::Node4(n) => NodeType::Node4(n.clone()), |
1170 | 0 | NodeType::Node16(n) => NodeType::Node16(n.clone()), |
1171 | 0 | NodeType::Node48(n) => NodeType::Node48(n.clone()), |
1172 | 0 | NodeType::Node256(n) => NodeType::Node256(n.clone()), |
1173 | | } |
1174 | 0 | } |
1175 | | } |
1176 | | |
1177 | | // Default implementation for the Tree struct |
1178 | | impl<P: KeyTrait, V: Clone> Default for Tree<P, V> { |
1179 | 0 | fn default() -> Self { |
1180 | 0 | Tree::new() |
1181 | 0 | } |
1182 | | } |
1183 | | |
1184 | | impl<P: KeyTrait, V: Clone> Clone for Tree<P, V> { |
1185 | 0 | fn clone(&self) -> Self { |
1186 | 0 | Self { |
1187 | 0 | root: self.root.as_ref().cloned(), |
1188 | 0 | size: self.size, |
1189 | 0 | version: self.version, |
1190 | 0 | } |
1191 | 0 | } |
1192 | | } |
1193 | | |
1194 | | impl<P: KeyTrait, V: Clone> Tree<P, V> { |
1195 | 0 | pub fn new() -> Self { |
1196 | 0 | Tree { |
1197 | 0 | root: None, |
1198 | 0 | size: 0, |
1199 | 0 | version: 0, |
1200 | 0 | } |
1201 | 0 | } Unexecuted instantiation: <vart::art::Tree<vart::VariableSizeKey, alloc::string::String>>::new Unexecuted instantiation: <vart::art::Tree<_, _>>::new |
1202 | | |
1203 | 0 | fn update_version(&mut self, version: u64) { |
1204 | 0 | self.version = if version == 0 { |
1205 | 0 | self.version + 1 |
1206 | 0 | } else if version > self.version { |
1207 | 0 | version |
1208 | | } else { |
1209 | 0 | self.version |
1210 | | }; |
1211 | 0 | } Unexecuted instantiation: <vart::art::Tree<vart::VariableSizeKey, alloc::string::String>>::update_version Unexecuted instantiation: <vart::art::Tree<_, _>>::update_version |
1212 | | |
1213 | 0 | fn insert_common( |
1214 | 0 | &mut self, |
1215 | 0 | key: &P, |
1216 | 0 | value: V, |
1217 | 0 | version: u64, |
1218 | 0 | ts: u64, |
1219 | 0 | check_version: bool, |
1220 | 0 | replace: bool, |
1221 | 0 | ) -> Result<(), TrieError> { |
1222 | 0 | let new_root = match &self.root { |
1223 | | None => { |
1224 | 0 | let commit_version = if version == 0 { 1 } else { version }; |
1225 | 0 | Arc::new(Node::new_twig( |
1226 | 0 | key.as_slice().into(), |
1227 | 0 | key.as_slice().into(), |
1228 | 0 | value, |
1229 | 0 | commit_version, |
1230 | 0 | ts, |
1231 | | )) |
1232 | | } |
1233 | 0 | Some(root) => { |
1234 | 0 | let curr_version = self.version; |
1235 | 0 | let mut commit_version = version; |
1236 | 0 | if version == 0 { |
1237 | 0 | commit_version = curr_version + 1; |
1238 | 0 | } else if check_version && curr_version > version { |
1239 | 0 | return Err(TrieError::VersionIsOld); |
1240 | 0 | } |
1241 | 0 | Node::insert_recurse(root, key, value, commit_version, ts, 0, replace) |
1242 | | } |
1243 | | }; |
1244 | | |
1245 | 0 | self.root = Some(new_root); |
1246 | 0 | self.size += 1; |
1247 | 0 | self.update_version(version); |
1248 | | |
1249 | 0 | Ok(()) |
1250 | 0 | } |
1251 | | |
1252 | 0 | fn insert_common_mut( |
1253 | 0 | &mut self, |
1254 | 0 | key: &P, |
1255 | 0 | value: V, |
1256 | 0 | version: u64, |
1257 | 0 | ts: u64, |
1258 | 0 | check_version: bool, |
1259 | 0 | replace: bool, |
1260 | 0 | ) -> Result<(), TrieError> { |
1261 | 0 | if let Some(root_arc) = self.root.as_mut() { |
1262 | 0 | let curr_version = self.version; |
1263 | 0 | let mut commit_version = version; |
1264 | 0 | if version == 0 { |
1265 | 0 | commit_version = curr_version + 1; |
1266 | 0 | } else if check_version && curr_version > version { |
1267 | 0 | return Err(TrieError::VersionIsOld); |
1268 | 0 | } |
1269 | 0 | if let Some(root) = Arc::get_mut(root_arc) { |
1270 | 0 | Node::insert_recurse_mut(root, key, value, commit_version, ts, 0, replace) |
1271 | | } else { |
1272 | 0 | return Err(TrieError::RootIsNotUniquelyOwned); |
1273 | | } |
1274 | | } else { |
1275 | 0 | let commit_version = if version == 0 { 1 } else { version }; |
1276 | 0 | self.root = Some(Arc::new(Node::new_twig( |
1277 | 0 | key.as_slice().into(), |
1278 | 0 | key.as_slice().into(), |
1279 | 0 | value, |
1280 | 0 | commit_version, |
1281 | 0 | ts, |
1282 | 0 | ))); |
1283 | | } |
1284 | 0 | self.size += 1; |
1285 | 0 | self.update_version(version); |
1286 | | |
1287 | 0 | Ok(()) |
1288 | 0 | } Unexecuted instantiation: <vart::art::Tree<vart::VariableSizeKey, alloc::string::String>>::insert_common_mut Unexecuted instantiation: <vart::art::Tree<_, _>>::insert_common_mut |
1289 | | |
1290 | | /// Inserts a new key-value pair with the specified version into the Trie. |
1291 | | /// |
1292 | | /// This function inserts a new key-value pair into the Trie. If the key already exists, |
1293 | | /// the previous value associated with the key is returned. The `version`` is used to |
1294 | | /// ensure proper ordering of values for versioning. The `ts` parameter is used to |
1295 | | /// record the timestamp of the insertion. |
1296 | | /// |
1297 | | /// This method ensures that the `version` provided is equal to or greater than the |
1298 | | /// current version of the tree. If a strictly greater guarantee is required, then |
1299 | | /// the caller is responsible for enforcing it. |
1300 | | /// |
1301 | | /// # Arguments |
1302 | | /// |
1303 | | /// * `key`: A reference to the key to be inserted. |
1304 | | /// * `value`: The value to be associated with the key. |
1305 | | /// * `version`: The version number for the key-value pair. |
1306 | | /// * `ts`: The timestamp for the insertion, used for versioning. |
1307 | | /// |
1308 | | /// # Returns |
1309 | | /// |
1310 | | /// Returns `Ok(())` on success. |
1311 | | /// |
1312 | | /// # Errors |
1313 | | /// |
1314 | | /// Returns an error if the given version is older than the root's current version. |
1315 | 0 | pub fn insert(&mut self, key: &P, value: V, version: u64, ts: u64) -> Result<(), TrieError> { |
1316 | 0 | self.insert_common(key, value, version, ts, true, false) |
1317 | 0 | } |
1318 | | |
1319 | | /// Inserts or replaces a key-value pair in the trie. |
1320 | | /// |
1321 | | /// This function inserts a new key-value pair into the trie or replaces the existing value |
1322 | | /// if the key already exists. It ensures that the insertion is checked, meaning it will |
1323 | | /// validate the keys are inserted in increasing order of version numbers. |
1324 | | /// |
1325 | | /// # Parameters |
1326 | | /// - `key`: A reference to the key to be inserted or replaced. |
1327 | | /// - `value`: The value to be associated with the key. |
1328 | | /// - `version`: The version number for the key-value pair. |
1329 | | /// - `ts`: The timestamp for the key-value pair. |
1330 | | /// |
1331 | | /// # Returns |
1332 | | /// - `Result<(), TrieError>`: Returns `Ok(())` if the insertion or replacement is successful, |
1333 | | /// or a `TrieError` if an error occurs during the operation. |
1334 | 0 | pub fn insert_or_replace( |
1335 | 0 | &mut self, |
1336 | 0 | key: &P, |
1337 | 0 | value: V, |
1338 | 0 | version: u64, |
1339 | 0 | ts: u64, |
1340 | 0 | ) -> Result<(), TrieError> { |
1341 | 0 | self.insert_common(key, value, version, ts, true, true) |
1342 | 0 | } |
1343 | | |
1344 | | /// Inserts a key-value pair into the trie without checking for existing keys. |
1345 | | /// |
1346 | | /// This function inserts a new key-value pair into the trie without checking if the key |
1347 | | /// already exists. It is an unchecked insertion, meaning it will not check if the versions |
1348 | | /// are incremental during insertion. This can be faster but may lead to inconsistencies |
1349 | | /// if not used carefully. |
1350 | | /// |
1351 | | /// This function also avoids the Copy-on-Write overhead of the `Arc` type by using mutable |
1352 | | /// references to the nodes. This can be useful when the caller knows that the root node |
1353 | | /// is uniquely owned and can be mutated directly. |
1354 | | /// |
1355 | | /// # Parameters |
1356 | | /// - `key`: A reference to the key to be inserted. |
1357 | | /// - `value`: The value to be associated with the key. |
1358 | | /// - `version`: The version number for the key-value pair. |
1359 | | /// - `ts`: The timestamp for the key-value pair. |
1360 | | /// |
1361 | | /// # Returns |
1362 | | /// - `Result<(), TrieError>`: Returns `Ok(())` if the insertion is successful, |
1363 | | /// or a `TrieError` if an error occurs during the operation. |
1364 | 0 | pub fn insert_unchecked( |
1365 | 0 | &mut self, |
1366 | 0 | key: &P, |
1367 | 0 | value: V, |
1368 | 0 | version: u64, |
1369 | 0 | ts: u64, |
1370 | 0 | ) -> Result<(), TrieError> { |
1371 | 0 | self.insert_common_mut(key, value, version, ts, false, false) |
1372 | 0 | } Unexecuted instantiation: <vart::art::Tree<vart::VariableSizeKey, alloc::string::String>>::insert_unchecked Unexecuted instantiation: <vart::art::Tree<_, _>>::insert_unchecked |
1373 | | |
1374 | | /// Inserts or replaces a key-value pair in the trie without checking for existing keys. |
1375 | | /// |
1376 | | /// This function inserts a new key-value pair into the trie or replaces the existing value |
1377 | | /// if the key already exists. It is an unchecked insertion, meaning it will not check if the versions |
1378 | | /// are incremental during insertion. This can be faster but may lead to inconsistencies |
1379 | | /// if not used carefully. |
1380 | | /// |
1381 | | /// # Parameters |
1382 | | /// - `key`: A reference to the key to be inserted or replaced. |
1383 | | /// - `value`: The value to be associated with the key. |
1384 | | /// - `version`: The version number for the key-value pair. |
1385 | | /// - `ts`: The timestamp for the key-value pair. |
1386 | | /// |
1387 | | /// # Returns |
1388 | | /// - `Result<(), TrieError>`: Returns `Ok(())` if the insertion or replacement is successful, |
1389 | | /// or a `TrieError` if an error occurs during the operation. |
1390 | 0 | pub fn insert_or_replace_unchecked( |
1391 | 0 | &mut self, |
1392 | 0 | key: &P, |
1393 | 0 | value: V, |
1394 | 0 | version: u64, |
1395 | 0 | ts: u64, |
1396 | 0 | ) -> Result<(), TrieError> { |
1397 | 0 | self.insert_common_mut(key, value, version, ts, false, true) |
1398 | 0 | } |
1399 | | |
1400 | | /// Removes the key from the current node or one of its child nodes |
1401 | | /// while building an updated copy of the Tree on its way up the recursion. |
1402 | | /// |
1403 | | /// # Parameters |
1404 | | /// |
1405 | | /// - `cur_node`: A reference to the current node. |
1406 | | /// - `key`: The key to be removed. |
1407 | | /// - `depth`: The depth of the removal process. |
1408 | | /// |
1409 | | /// # Returns |
1410 | | /// |
1411 | | /// Returns a tuple containing the updated node (or `None`) and a flag |
1412 | | /// indicating if the key was removed. |
1413 | 0 | fn remove_recursive( |
1414 | 0 | cur_node: &Node<P, V>, |
1415 | 0 | key: &P, |
1416 | 0 | depth: usize, |
1417 | 0 | ) -> (Option<Arc<Node<P, V>>>, bool) { |
1418 | 0 | let key_prefix = key.prefix_after(depth); |
1419 | 0 | let prefix = cur_node.prefix(); |
1420 | 0 | let lcp = prefix.longest_common_prefix(key_prefix); |
1421 | | |
1422 | | // Current node's prefix does not match the remainder of the |
1423 | | // key. This means there's no key in the Tree, so recourse up |
1424 | | // with nothing. This will keep the original Tree root unaffected. |
1425 | 0 | if lcp != prefix.len() { |
1426 | 0 | return (None, false); |
1427 | 0 | } |
1428 | | |
1429 | | // Current node's prefix completely matches the remainder of the key. |
1430 | | // This must be the Twig node. It's copy-on-write removed by returning |
1431 | | // (None, true). This will signal the caller to remove the associated |
1432 | | // child link from the parent inner node. |
1433 | 0 | if prefix.len() == key_prefix.len() { |
1434 | 0 | if cur_node.is_twig() { |
1435 | 0 | return (None, true); |
1436 | 0 | } else if cur_node.get_inner_twig().is_some() { |
1437 | 0 | let mut node_without_leaf = cur_node.delete_inner_twig(); |
1438 | 0 | if node_without_leaf.num_children() == 1 { |
1439 | 0 | // If this inner node has only one child, then it must |
1440 | 0 | // be Node4. Its shrink() implementation is special in |
1441 | 0 | // that for a single child it will pull the child up |
1442 | 0 | // and replace itself with it. |
1443 | 0 | node_without_leaf.shrink(); |
1444 | 0 | } |
1445 | 0 | return (Some(Arc::new(node_without_leaf)), true); |
1446 | | } else { |
1447 | | // This is an inner node without a leaf, so no match. |
1448 | 0 | return (None, false); |
1449 | | } |
1450 | 0 | } |
1451 | | |
1452 | | // Current node's prefix matches the prefix of the remainder |
1453 | | // of the key. Continue the search down the Tree while building |
1454 | | // its copy. |
1455 | 0 | let new_depth = depth + prefix.len(); |
1456 | 0 | let k = key.at(new_depth); |
1457 | 0 | if let Some(child) = cur_node.find_child(k) { |
1458 | 0 | match Self::remove_recursive(child, key, new_depth) { |
1459 | 0 | (Some(new_child), true) => { |
1460 | 0 | let new_node = cur_node.replace_child(k, new_child); |
1461 | 0 | return (Some(Arc::new(new_node)), true); |
1462 | | } |
1463 | | (None, true) => { |
1464 | | // The key has been found, so either remove the corresponding |
1465 | | // child link from the current node if that's not its |
1466 | | // last child, or pull up its inner Twig node into this |
1467 | | // position in the tree, or simply return (None, true) |
1468 | | // if there's nothing to occupy this position. |
1469 | 0 | if cur_node.num_children() == 1 { |
1470 | 0 | if cur_node.get_inner_twig().is_some() { |
1471 | 0 | let cloned_twig = cur_node.node_type.clone_inner_twig(); |
1472 | 0 | return (cloned_twig, true); |
1473 | | } else { |
1474 | 0 | return (None, true); |
1475 | | } |
1476 | | } else { |
1477 | 0 | let new_node = cur_node.delete_child(k); |
1478 | 0 | return (Some(Arc::new(new_node)), true); |
1479 | | } |
1480 | | } |
1481 | 0 | _ => {} |
1482 | | } |
1483 | 0 | } |
1484 | | |
1485 | 0 | (None, false) |
1486 | 0 | } |
1487 | | |
1488 | | /// Removes a key with all the versions associated with it from the Trie. |
1489 | | /// |
1490 | | /// This function removes a key and all its associated versions from the Trie. |
1491 | | /// |
1492 | | /// # Arguments |
1493 | | /// |
1494 | | /// * `key`: A reference to the key to be removed. |
1495 | | /// |
1496 | | /// # Returns |
1497 | | /// |
1498 | | /// Returns `true` if the key was successfully removed, `false` otherwise. |
1499 | 0 | pub fn remove(&mut self, key: &P) -> bool { |
1500 | 0 | let root = match self.root.as_deref() { |
1501 | 0 | Some(root) => root, |
1502 | 0 | None => return false, |
1503 | | }; |
1504 | | |
1505 | 0 | let (new_root, is_deleted) = Tree::remove_recursive(root, key, 0); |
1506 | | |
1507 | | // Update the root and return the deletion status. |
1508 | 0 | if is_deleted { |
1509 | 0 | self.root = new_root; |
1510 | 0 | self.size -= 1; |
1511 | 0 | } |
1512 | 0 | is_deleted |
1513 | 0 | } |
1514 | | |
1515 | | /// Retrieves the value associated with the given key at a given version from the Trie. |
1516 | | /// |
1517 | | /// This function searches for the value associated with the specified key at the specified |
1518 | | /// version in the Trie. If the version is set to 0, it retrieves the latest version available |
1519 | | /// for the key. The function uses a recursive search to find the value. |
1520 | | /// |
1521 | | /// # Arguments |
1522 | | /// |
1523 | | /// * `key`: A reference to the key to be searched. |
1524 | | /// * `version`: The version number to be searched. If set to 0, the latest version is retrieved. |
1525 | | /// |
1526 | | /// # Returns |
1527 | | /// |
1528 | | /// Returns an `Option` containing a tuple `(V, u64, u64)` if the key and version are found: |
1529 | | /// - `V`: The value associated with the key. |
1530 | | /// - `u64`: The version number of the value. |
1531 | | /// - `u64`: The timestamp of the value. |
1532 | | /// |
1533 | | /// Returns `None` if the key or version is not found. |
1534 | 0 | pub fn get(&self, key: &P, version: u64) -> Option<(V, u64, u64)> { |
1535 | 0 | let root = self.root.as_ref()?; |
1536 | 0 | let mut commit_version = version; |
1537 | 0 | if commit_version == 0 { |
1538 | 0 | commit_version = self.version; |
1539 | 0 | } |
1540 | | |
1541 | 0 | Node::get_recurse(root, key, QueryType::LatestByVersion(commit_version)) |
1542 | 0 | } Unexecuted instantiation: <vart::art::Tree<vart::VariableSizeKey, alloc::string::String>>::get Unexecuted instantiation: <vart::art::Tree<_, _>>::get |
1543 | | |
1544 | | /// Retrieves the latest version inserted in the Trie. |
1545 | | /// |
1546 | | /// This function returns the latest version inserted in the Trie. This is used internally |
1547 | | /// for surrealkv for determining the transaction id. The version only moves forward in time |
1548 | | /// and does not get updated upon any removals. This behavior ensures that deletions do not |
1549 | | /// roll back version to read at an older snapshot, which is crucial for internal use in |
1550 | | /// SurrealKV for snapshot reads. |
1551 | | /// |
1552 | | /// # Returns |
1553 | | /// |
1554 | | /// Returns the version of the latest version of the Trie, or `0` if the Trie is empty. |
1555 | 0 | pub fn version(&self) -> u64 { |
1556 | 0 | self.version |
1557 | 0 | } |
1558 | | |
1559 | | /// Creates an iterator over the Trie's key-value pairs. |
1560 | | /// |
1561 | | /// This function creates and returns an iterator that can be used to traverse the key-value pairs |
1562 | | /// stored in the Trie. The iterator starts from the root of the Trie. |
1563 | | /// |
1564 | | /// # Returns |
1565 | | /// |
1566 | | /// Returns an `Iter` instance that iterates over the key-value pairs in the Trie. |
1567 | | /// |
1568 | 0 | pub fn iter(&self) -> Iter<P, V> { |
1569 | 0 | Iter::new(self.root.as_ref(), false) |
1570 | 0 | } |
1571 | | |
1572 | | /// Creates a versioned iterator over the Trie's key-value pairs. |
1573 | | /// |
1574 | | /// This function creates and returns an iterator that can be used to traverse all the versions |
1575 | | /// for all the key-value pairs stored in the Trie. The iterator starts from the root of the Trie. |
1576 | 0 | pub fn iter_with_versions(&self) -> Iter<P, V> { |
1577 | 0 | Iter::new(self.root.as_ref(), true) |
1578 | 0 | } |
1579 | | |
1580 | | /// Returns an iterator over a range of key-value pairs within the Trie. |
1581 | | /// |
1582 | | /// This function creates and returns an iterator that iterates over key-value pairs in the Trie, |
1583 | | /// starting from the provided `start_key` and following the specified `range` bounds. The iterator |
1584 | | /// iterates within the specified key range. |
1585 | | /// |
1586 | | /// # Arguments |
1587 | | /// |
1588 | | /// * `range` - A range that specifies the bounds for iterating over key-value pairs. |
1589 | | /// |
1590 | | /// # Returns |
1591 | | /// |
1592 | | /// Returns a `Range` iterator instance that iterates over the key-value pairs within the given range. |
1593 | | /// If the Trie is empty, an empty `Range` iterator is returned. |
1594 | | /// |
1595 | 0 | pub fn range<'a, R>(&'a self, range: R) -> impl DoubleEndedIterator<Item = IterItem<'a, V>> |
1596 | 0 | where |
1597 | 0 | R: RangeBounds<P> + 'a, |
1598 | | { |
1599 | | // If the Trie is empty, return an empty Range iterator |
1600 | 0 | if self.root.is_none() { |
1601 | 0 | return Range::empty(range); |
1602 | 0 | } |
1603 | | |
1604 | 0 | let root = self.root.as_ref(); |
1605 | 0 | Range::new(root, range) |
1606 | 0 | } |
1607 | | |
1608 | | /// Returns an iterator over the key-value pairs within the specified range, including all the |
1609 | | /// versions of the key. |
1610 | | /// |
1611 | | /// This function returns an iterator that yields key-value pairs along with their version |
1612 | | /// and timestamp within the specified range. If the Trie is empty, it returns an empty iterator. |
1613 | | /// |
1614 | | /// # Arguments |
1615 | | /// |
1616 | | /// * `range`: The range of keys to be iterated over. |
1617 | | /// |
1618 | | /// # Returns |
1619 | | /// |
1620 | | /// Returns an iterator over the key-value pairs, versions, and timestamps within the specified range. |
1621 | 0 | pub fn range_with_versions<'a, R>(&'a self, range: R) -> impl Iterator<Item = IterItem<'a, V>> |
1622 | 0 | where |
1623 | 0 | R: RangeBounds<P> + 'a, |
1624 | | { |
1625 | 0 | match &self.root { |
1626 | 0 | Some(root) => VersionRange::new(Some(root), range), |
1627 | 0 | None => VersionRange::empty(range), |
1628 | | } |
1629 | 0 | } |
1630 | | |
1631 | | /// Retrieves the value associated with the given key at the specified timestamp. |
1632 | | /// |
1633 | | /// This function searches for the value associated with the specified key at the given |
1634 | | /// timestamp in the Trie. It uses a recursive search to find the value. |
1635 | | /// |
1636 | | /// # Arguments |
1637 | | /// |
1638 | | /// * `key`: A reference to the key to be searched. |
1639 | | /// * `ts`: The timestamp to be searched. |
1640 | | /// |
1641 | | /// # Returns |
1642 | | /// |
1643 | | /// Returns an `Option` containing a tuple `(V, u64, u64)` if the key and timestamp are found: |
1644 | | /// - `V`: The value associated with the key. |
1645 | | /// - `u64`: The version number of the value. |
1646 | | /// - `u64`: The timestamp of the value. |
1647 | | /// |
1648 | | /// Returns `None` if the key or timestamp is not found. |
1649 | 0 | pub fn get_at_ts(&self, key: &P, ts: u64) -> Option<(V, u64, u64)> { |
1650 | 0 | let root = self.root.as_ref()?; |
1651 | 0 | Node::get_recurse(root, key, QueryType::LatestByTs(ts)) |
1652 | 0 | } |
1653 | | |
1654 | | /// Retrieves the version history of the given key. |
1655 | | /// |
1656 | | /// This function searches for all versions of the specified key in the Trie and returns |
1657 | | /// a vector of tuples containing the value, version number, and timestamp for each version. |
1658 | | /// |
1659 | | /// # Arguments |
1660 | | /// |
1661 | | /// * `key`: A reference to the key to be searched. |
1662 | | /// |
1663 | | /// # Returns |
1664 | | /// |
1665 | | /// Returns an `Option` containing a vector of tuples `(V, u64, u64)` if the key is found: |
1666 | | /// - `V`: The value associated with the key. |
1667 | | /// - `u64`: The version number of the value. |
1668 | | /// - `u64`: The timestamp of the value. |
1669 | | /// |
1670 | | /// Returns `None` if the key is not found. |
1671 | 0 | pub fn get_version_history(&self, key: &P) -> Option<Vec<(V, u64, u64)>> { |
1672 | 0 | let root = self.root.as_ref()?; |
1673 | 0 | Node::get_version_history(root, key) |
1674 | 0 | } |
1675 | | |
1676 | | /// Retrieves the value associated with the given key based on the specified query type. |
1677 | | /// |
1678 | | /// This function searches for the value associated with the specified key based on the |
1679 | | /// provided query type in the Trie. It uses a recursive search to find the value. |
1680 | | /// |
1681 | | /// # Arguments |
1682 | | /// |
1683 | | /// * `key`: A reference to the key to be searched. |
1684 | | /// * `query_type`: The type of query to be performed (e.g., latest by version, latest by timestamp). |
1685 | | /// |
1686 | | /// # Returns |
1687 | | /// |
1688 | | /// Returns an `Option` containing a tuple `(V, u64, u64)` if the key and query type are found: |
1689 | | /// - `V`: The value associated with the key. |
1690 | | /// - `u64`: The version number of the value. |
1691 | | /// - `u64`: The timestamp of the value. |
1692 | | /// |
1693 | | /// Returns `None` if the key or query type is not found. |
1694 | 0 | pub fn get_value_by_query(&self, key: &P, query_type: QueryType) -> Option<(V, u64, u64)> { |
1695 | 0 | let root = self.root.as_ref()?; |
1696 | 0 | Node::get_recurse(root, key, query_type) |
1697 | 0 | } |
1698 | | |
1699 | | /// Checks if the Trie is empty. |
1700 | | /// |
1701 | | /// This function checks if the Trie contains any key-value pairs. |
1702 | | /// |
1703 | | /// # Returns |
1704 | | /// |
1705 | | /// Returns `true` if the Trie is empty, `false` otherwise. |
1706 | 0 | pub fn is_empty(&self) -> bool { |
1707 | 0 | self.size == 0 |
1708 | 0 | } |
1709 | | |
1710 | 0 | pub fn scan_at_ts<'a, R>( |
1711 | 0 | &'a self, |
1712 | 0 | range: R, |
1713 | 0 | ts: u64, |
1714 | 0 | ) -> impl DoubleEndedIterator<Item = IterItem<'a, V>> + 'a |
1715 | 0 | where |
1716 | 0 | R: RangeBounds<P> + 'a, |
1717 | | { |
1718 | 0 | QueryIterator::new(self.root.as_ref(), range, QueryType::LatestByTs(ts)) |
1719 | 0 | } |
1720 | | |
1721 | | /// Retrieves the maximum version inside the Trie. |
1722 | | /// |
1723 | | /// This function returns the maximum version found inside the Trie by traversing |
1724 | | /// all the nodes. This version could be lesser than the current incremental version. |
1725 | 0 | pub fn max_version_in_trie(&self) -> u64 { |
1726 | 0 | self.iter() |
1727 | 0 | .map(|(_, _, version, _)| version) |
1728 | 0 | .max() |
1729 | 0 | .unwrap_or(0) |
1730 | 0 | } |
1731 | | } |
1732 | | |
1733 | | /* |
1734 | | Test cases for Adaptive Radix Tree |
1735 | | */ |
1736 | | |
1737 | | #[cfg(test)] |
1738 | | mod tests { |
1739 | | use super::Tree; |
1740 | | use crate::art::QueryType; |
1741 | | use crate::{FixedSizeKey, Key, VariableSizeKey}; |
1742 | | use rand::{seq::SliceRandom, thread_rng, Rng}; |
1743 | | use std::ops::RangeFull; |
1744 | | use std::str::FromStr; |
1745 | | |
1746 | | use rand::distributions::Alphanumeric; |
1747 | | use std::fs::File; |
1748 | | use std::io::{self, BufRead, BufReader}; |
1749 | | |
1750 | | fn read_words_from_file(file_path: &str) -> io::Result<Vec<String>> { |
1751 | | let file = File::open(file_path)?; |
1752 | | let reader = BufReader::new(file); |
1753 | | let words: Vec<String> = reader.lines().map_while(Result::ok).collect(); |
1754 | | Ok(words) |
1755 | | } |
1756 | | |
1757 | | #[test] |
1758 | | fn insert_search_delete_words() { |
1759 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::<VariableSizeKey, i32>::new(); |
1760 | | let file_path = "testdata/words.txt"; |
1761 | | |
1762 | | if let Ok(words) = read_words_from_file(file_path) { |
1763 | | // Insertion phase |
1764 | | for word in &words { |
1765 | | let key = &VariableSizeKey::from_str(word).unwrap(); |
1766 | | let _ = tree.insert(key, 1, 0, 0); |
1767 | | } |
1768 | | |
1769 | | // Search phase |
1770 | | for word in &words { |
1771 | | let key = VariableSizeKey::from_str(word).unwrap(); |
1772 | | let (val, _, _) = tree.get(&key, 0).unwrap(); |
1773 | | assert_eq!(val, 1); |
1774 | | } |
1775 | | |
1776 | | // Deletion phase |
1777 | | for word in &words { |
1778 | | let key = VariableSizeKey::from_str(word).unwrap(); |
1779 | | assert!(tree.remove(&key)); |
1780 | | } |
1781 | | } else if let Err(err) = read_words_from_file(file_path) { |
1782 | | eprintln!("Error reading file: {}", err); |
1783 | | } |
1784 | | } |
1785 | | |
1786 | | #[test] |
1787 | | fn insert_search_delete_words_randomized() { |
1788 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::<VariableSizeKey, i32>::new(); |
1789 | | let file_path = "testdata/words.txt"; |
1790 | | |
1791 | | let mut words = read_words_from_file(file_path).expect("error reading file"); |
1792 | | |
1793 | | // Shuffle the words |
1794 | | words.shuffle(&mut thread_rng()); |
1795 | | |
1796 | | // Insertion phase |
1797 | | for word in &words { |
1798 | | let key = &VariableSizeKey::from_str(word).unwrap(); |
1799 | | let _ = tree.insert(key, 1, 0, 0); |
1800 | | } |
1801 | | |
1802 | | // Search phase |
1803 | | for word in &words { |
1804 | | let key = VariableSizeKey::from_str(word).unwrap(); |
1805 | | let (val, _, _) = tree.get(&key, 0).unwrap(); |
1806 | | assert_eq!(val, 1); |
1807 | | } |
1808 | | |
1809 | | // Deletion phase |
1810 | | for word in &words { |
1811 | | let key = VariableSizeKey::from_str(word).unwrap(); |
1812 | | assert!(tree.remove(&key)); |
1813 | | } |
1814 | | } |
1815 | | |
1816 | | #[test] |
1817 | | fn insert_mut_search_delete_words_randomized() { |
1818 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::<VariableSizeKey, i32>::new(); |
1819 | | let file_path = "testdata/words.txt"; |
1820 | | |
1821 | | let mut words = read_words_from_file(file_path).expect("error reading file"); |
1822 | | |
1823 | | // Shuffle the words |
1824 | | words.shuffle(&mut thread_rng()); |
1825 | | |
1826 | | // Insertion phase |
1827 | | for word in &words { |
1828 | | let key = &VariableSizeKey::from_str(word).unwrap(); |
1829 | | let _ = tree.insert_unchecked(key, 1, 0, 0); |
1830 | | } |
1831 | | |
1832 | | // Search phase |
1833 | | for word in &words { |
1834 | | let key = VariableSizeKey::from_str(word).unwrap(); |
1835 | | let (val, _, _) = tree.get(&key, 0).unwrap(); |
1836 | | assert_eq!(val, 1); |
1837 | | } |
1838 | | |
1839 | | // Deletion phase |
1840 | | for word in &words { |
1841 | | let key = VariableSizeKey::from_str(word).unwrap(); |
1842 | | assert!(tree.remove(&key)); |
1843 | | } |
1844 | | } |
1845 | | |
1846 | | #[test] |
1847 | | fn remove_with_one_child_and_inner_twig() { |
1848 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
1849 | | let k1 = VariableSizeKey::from_slice(b"aam"); |
1850 | | let k2 = VariableSizeKey::from_slice(b"aa"); |
1851 | | let k3 = VariableSizeKey::from_slice(b"aal"); |
1852 | | |
1853 | | let _ = tree.insert(&k1, 1, 0, 0); |
1854 | | let _ = tree.insert(&k2, 2, 0, 0); |
1855 | | let _ = tree.insert(&k3, 3, 0, 0); |
1856 | | |
1857 | | assert_eq!(tree.get(&k1, 0).unwrap().0, 1); |
1858 | | assert_eq!(tree.get(&k2, 0).unwrap().0, 2); |
1859 | | assert_eq!(tree.get(&k3, 0).unwrap().0, 3); |
1860 | | |
1861 | | assert!(tree.remove(&k1)); |
1862 | | assert!(tree.remove(&k2)); |
1863 | | assert!(tree.remove(&k3)); |
1864 | | } |
1865 | | |
1866 | | #[test] |
1867 | | fn descending_keys() { |
1868 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
1869 | | let ccc = VariableSizeKey::from_slice(b"ccc"); |
1870 | | let cc = VariableSizeKey::from_slice(b"cc"); |
1871 | | let c = VariableSizeKey::from_slice(b"c"); |
1872 | | |
1873 | | let _ = tree.insert(&ccc, 1, 0, 0); |
1874 | | let _ = tree.insert(&cc, 2, 0, 0); |
1875 | | let _ = tree.insert(&c, 3, 0, 0); |
1876 | | |
1877 | | assert_eq!(tree.get(&ccc, 0).unwrap().0, 1); |
1878 | | assert_eq!(tree.get(&cc, 0).unwrap().0, 2); |
1879 | | assert_eq!(tree.get(&c, 0).unwrap().0, 3); |
1880 | | |
1881 | | assert!(tree.remove(&ccc)); |
1882 | | assert!(tree.remove(&cc)); |
1883 | | assert!(tree.remove(&c)); |
1884 | | } |
1885 | | |
1886 | | #[test] |
1887 | | fn string_insert_delete() { |
1888 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
1889 | | |
1890 | | // Insertion phase |
1891 | | let insert_words = [ |
1892 | | "a", "aa", "aal", "aalii", "abc", "abcd", "abcde", "xyz", "axyz", |
1893 | | ]; |
1894 | | |
1895 | | for word in &insert_words { |
1896 | | let _ = tree.insert(&VariableSizeKey::from_str(word).unwrap(), 1, 0, 0); |
1897 | | } |
1898 | | |
1899 | | // Deletion phase |
1900 | | for word in &insert_words { |
1901 | | assert!(tree.remove(&VariableSizeKey::from_str(word).unwrap())); |
1902 | | } |
1903 | | } |
1904 | | |
1905 | | #[test] |
1906 | | fn string_long() { |
1907 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
1908 | | |
1909 | | // Insertion phase |
1910 | | let words_to_insert = [ |
1911 | | ("amyelencephalia", 1), |
1912 | | ("amyelencephalic", 2), |
1913 | | ("amyelencephalous", 3), |
1914 | | ]; |
1915 | | |
1916 | | for (word, val) in &words_to_insert { |
1917 | | let _ = tree.insert(&VariableSizeKey::from_str(word).unwrap(), *val, 0, 0); |
1918 | | } |
1919 | | |
1920 | | // Verification phase |
1921 | | for (word, expected_val) in &words_to_insert { |
1922 | | let (val, _, _) = tree |
1923 | | .get(&VariableSizeKey::from_str(word).unwrap(), 0) |
1924 | | .unwrap(); |
1925 | | assert_eq!(val, *expected_val); |
1926 | | } |
1927 | | } |
1928 | | |
1929 | | #[test] |
1930 | | fn root_set_get() { |
1931 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
1932 | | |
1933 | | // Insertion phase |
1934 | | let key = VariableSizeKey::from_str("abc").unwrap(); |
1935 | | let value = 1; |
1936 | | let _ = tree.insert(&key, value, 0, 0); |
1937 | | |
1938 | | // Verification phase |
1939 | | let (val, _ts, _) = tree.get(&key, 0).unwrap(); |
1940 | | assert_eq!(val, value); |
1941 | | } |
1942 | | |
1943 | | #[test] |
1944 | | fn string_duplicate_insert() { |
1945 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
1946 | | |
1947 | | // First insertion |
1948 | | let key = VariableSizeKey::from_str("abc").unwrap(); |
1949 | | let value = 1; |
1950 | | tree.insert(&key, value, 0, 0).expect("Failed to insert"); |
1951 | | let (val, version, ts) = tree.get(&key, 0).unwrap(); |
1952 | | assert!(val == value); |
1953 | | assert!(version == 1); |
1954 | | assert!(ts == 0); |
1955 | | |
1956 | | // Second insertion (duplicate) |
1957 | | let value = 2; |
1958 | | tree.insert(&key, value, 0, 0).expect("Failed to insert"); |
1959 | | let (val, version, ts) = tree.get(&key, 0).unwrap(); |
1960 | | assert!(val == value); |
1961 | | assert!(version == 2); |
1962 | | assert!(ts == 0); |
1963 | | } |
1964 | | |
1965 | | // Inserting a single value into the tree and removing it should result in a nil tree root. |
1966 | | #[test] |
1967 | | fn insert_and_remove_single_key() { |
1968 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
1969 | | |
1970 | | // Insertion |
1971 | | let key = VariableSizeKey::from_str("test").unwrap(); |
1972 | | let value = 1; |
1973 | | let _ = tree.insert(&key, value, 0, 0); |
1974 | | |
1975 | | // Removal |
1976 | | assert!(tree.remove(&key)); |
1977 | | |
1978 | | // Verification |
1979 | | assert!(tree.get(&key, 0).is_none()); |
1980 | | } |
1981 | | |
1982 | | #[test] |
1983 | | fn inserting_keys_with_common_prefix() { |
1984 | | let key1 = VariableSizeKey::from_str("foo").unwrap(); |
1985 | | let key2 = VariableSizeKey::from_str("foo2").unwrap(); |
1986 | | |
1987 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
1988 | | |
1989 | | // Insertion |
1990 | | tree.insert(&key1, 1, 0, 0).unwrap(); |
1991 | | tree.insert(&key2, 1, 0, 0).unwrap(); |
1992 | | |
1993 | | // Removal |
1994 | | assert!(tree.remove(&key1)); |
1995 | | |
1996 | | // Root verification |
1997 | | if let Some(root) = &tree.root { |
1998 | | assert_eq!(root.node_type_name(), "Twig"); |
1999 | | } else { |
2000 | | panic!("Tree root is None"); |
2001 | | } |
2002 | | } |
2003 | | |
2004 | | // Inserting Two values into the tree and removing one of them |
2005 | | // should result in a tree root of type twig |
2006 | | #[test] |
2007 | | fn insert2_and_remove1_and_root_should_be_node1() { |
2008 | | let key1 = VariableSizeKey::from_str("test1").unwrap(); |
2009 | | let key2 = VariableSizeKey::from_str("test2").unwrap(); |
2010 | | |
2011 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2012 | | |
2013 | | // Insertion |
2014 | | tree.insert(&key1, 1, 0, 0).unwrap(); |
2015 | | tree.insert(&key2, 1, 0, 0).unwrap(); |
2016 | | |
2017 | | // Removal |
2018 | | assert!(tree.remove(&key1)); |
2019 | | |
2020 | | // Root verification |
2021 | | if let Some(root) = &tree.root { |
2022 | | assert_eq!(root.node_type_name(), "Twig"); |
2023 | | } else { |
2024 | | panic!("Tree root is None"); |
2025 | | } |
2026 | | } |
2027 | | |
2028 | | // Inserting Two values into a tree and deleting them both |
2029 | | // should result in a nil tree root |
2030 | | // This tests the expansion of the root into a NODE4 and |
2031 | | // successfully collapsing into a twig and then nil upon successive removals |
2032 | | #[test] |
2033 | | fn insert2_and_remove2_and_root_should_be_nil() { |
2034 | | let key1 = &VariableSizeKey::from_str("test1").unwrap(); |
2035 | | let key2 = &VariableSizeKey::from_str("test2").unwrap(); |
2036 | | |
2037 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2038 | | tree.insert(key1, 1, 0, 0).unwrap(); |
2039 | | tree.insert(key2, 1, 0, 0).unwrap(); |
2040 | | |
2041 | | assert!(tree.remove(key1)); |
2042 | | assert!(tree.remove(key2)); |
2043 | | |
2044 | | assert!(tree.root.is_none()); |
2045 | | } |
2046 | | |
2047 | | // Inserting Five values into a tree and deleting one of them |
2048 | | // should result in a tree root of type NODE4 |
2049 | | // This tests the expansion of the root into a NODE16 and |
2050 | | // successfully collapsing into a NODE4 upon successive removals |
2051 | | #[test] |
2052 | | fn insert5_and_remove1_and_root_should_be_node4() { |
2053 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2054 | | |
2055 | | // Insertion |
2056 | | for i in 0..5u32 { |
2057 | | let key = VariableSizeKey::from_slice(&i.to_be_bytes()); |
2058 | | tree.insert(&key, 1, 0, 0).unwrap(); |
2059 | | } |
2060 | | |
2061 | | // Removal |
2062 | | let key_to_remove = VariableSizeKey::from_slice(&1u32.to_be_bytes()); |
2063 | | assert!(tree.remove(&key_to_remove)); |
2064 | | |
2065 | | // Root verification |
2066 | | if let Some(root) = &tree.root { |
2067 | | assert!(root.is_inner()); |
2068 | | assert_eq!(root.node_type_name(), "Node4"); |
2069 | | } else { |
2070 | | panic!("Tree root is None"); |
2071 | | } |
2072 | | } |
2073 | | |
2074 | | // Inserting Five values into a tree and deleting all of them |
2075 | | // should result in a tree root of type nil |
2076 | | // This tests the expansion of the root into a NODE16 and |
2077 | | // successfully collapsing into a NODE4, twig, then nil |
2078 | | #[test] |
2079 | | fn insert5_and_remove5_and_root_should_be_nil() { |
2080 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2081 | | |
2082 | | for i in 0..5u32 { |
2083 | | let key = &VariableSizeKey::from_slice(&i.to_be_bytes()); |
2084 | | tree.insert(key, 1, 0, 0).unwrap(); |
2085 | | } |
2086 | | |
2087 | | for i in 0..5u32 { |
2088 | | let key = &VariableSizeKey::from_slice(&i.to_be_bytes()); |
2089 | | tree.remove(key); |
2090 | | } |
2091 | | |
2092 | | assert!(tree.root.is_none()); |
2093 | | } |
2094 | | |
2095 | | // Inserting 17 values into a tree and deleting one of them should |
2096 | | // result in a tree root of type NODE16 |
2097 | | // This tests the expansion of the root into a NODE48, and |
2098 | | // successfully collapsing into a NODE16 |
2099 | | #[test] |
2100 | | fn insert17_and_remove1_and_root_should_be_node16() { |
2101 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2102 | | |
2103 | | // Insertion |
2104 | | for i in 0..17u32 { |
2105 | | let key = VariableSizeKey::from_slice(&i.to_be_bytes()); |
2106 | | tree.insert(&key, 1, 0, 0).unwrap(); |
2107 | | } |
2108 | | |
2109 | | // Removal |
2110 | | let key_to_remove = VariableSizeKey::from_slice(&2u32.to_be_bytes()); |
2111 | | assert!(tree.remove(&key_to_remove)); |
2112 | | |
2113 | | // Root verification |
2114 | | if let Some(root) = &tree.root { |
2115 | | assert!(root.is_inner()); |
2116 | | assert_eq!(root.node_type_name(), "Node16"); |
2117 | | } else { |
2118 | | panic!("Tree root is None"); |
2119 | | } |
2120 | | } |
2121 | | |
2122 | | #[test] |
2123 | | fn insert17_and_root_should_be_node48() { |
2124 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2125 | | |
2126 | | // Insertion |
2127 | | for i in 0..17u32 { |
2128 | | let key = VariableSizeKey::from_slice(&i.to_be_bytes()); |
2129 | | tree.insert(&key, 1, 0, 0).unwrap(); |
2130 | | } |
2131 | | |
2132 | | // Root verification |
2133 | | if let Some(root) = &tree.root { |
2134 | | assert!(root.is_inner()); |
2135 | | assert_eq!(root.node_type_name(), "Node48"); |
2136 | | } else { |
2137 | | panic!("Tree root is None"); |
2138 | | } |
2139 | | } |
2140 | | |
2141 | | // Inserting 17 values into a tree and removing them all should |
2142 | | // result in a tree of root type nil |
2143 | | // This tests the expansion of the root into a NODE48, and |
2144 | | // successfully collapsing into a NODE16, NODE4, twig, and then nil |
2145 | | #[test] |
2146 | | fn insert17_and_remove17_and_root_should_be_nil() { |
2147 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2148 | | |
2149 | | for i in 0..17u32 { |
2150 | | let key = VariableSizeKey::from_slice(&i.to_be_bytes()); |
2151 | | tree.insert(&key, 1, 0, 0).unwrap(); |
2152 | | } |
2153 | | |
2154 | | for i in 0..17u32 { |
2155 | | let key = VariableSizeKey::from_slice(&i.to_be_bytes()); |
2156 | | tree.remove(&key); |
2157 | | } |
2158 | | |
2159 | | assert!(tree.root.is_none()); |
2160 | | } |
2161 | | |
2162 | | // Inserting 49 values into a tree and removing one of them should |
2163 | | // result in a tree root of type NODE48 |
2164 | | // This tests the expansion of the root into a NODE256, and |
2165 | | // successfully collapasing into a NODE48 |
2166 | | #[test] |
2167 | | fn insert49_and_remove1_and_root_should_be_node48() { |
2168 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2169 | | |
2170 | | // Insertion |
2171 | | for i in 0..49u32 { |
2172 | | let key = VariableSizeKey::from_slice(&i.to_be_bytes()); |
2173 | | tree.insert(&key, 1, 0, 0).unwrap(); |
2174 | | } |
2175 | | |
2176 | | // Removal |
2177 | | let key_to_remove = VariableSizeKey::from_slice(&2u32.to_be_bytes()); |
2178 | | assert!(tree.remove(&key_to_remove)); |
2179 | | |
2180 | | // Root verification |
2181 | | if let Some(root) = &tree.root { |
2182 | | assert!(root.is_inner()); |
2183 | | assert_eq!(root.node_type_name(), "Node48"); |
2184 | | } else { |
2185 | | panic!("Tree root is None"); |
2186 | | } |
2187 | | } |
2188 | | |
2189 | | #[test] |
2190 | | fn insert49_and_root_should_be_node248() { |
2191 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2192 | | |
2193 | | // Insertion |
2194 | | for i in 0..49u32 { |
2195 | | let key = VariableSizeKey::from_slice(&i.to_be_bytes()); |
2196 | | tree.insert(&key, 1, 0, 0).unwrap(); |
2197 | | } |
2198 | | |
2199 | | // Root verification |
2200 | | if let Some(root) = &tree.root { |
2201 | | assert!(root.is_inner()); |
2202 | | assert_eq!(root.node_type_name(), "Node256"); |
2203 | | } else { |
2204 | | panic!("Tree root is None"); |
2205 | | } |
2206 | | } |
2207 | | |
2208 | | // Inserting 49 values into a tree and removing all of them should |
2209 | | // result in a nil tree root |
2210 | | // This tests the expansion of the root into a NODE256, and |
2211 | | // successfully collapsing into a Node48, Node16, Node4, twig, and finally nil |
2212 | | #[test] |
2213 | | fn insert49_and_remove49_and_root_should_be_nil() { |
2214 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2215 | | |
2216 | | for i in 0..49u32 { |
2217 | | let key = &VariableSizeKey::from_slice(&i.to_be_bytes()); |
2218 | | tree.insert(key, 1, 0, 0).unwrap(); |
2219 | | } |
2220 | | |
2221 | | for i in 0..49u32 { |
2222 | | let key = VariableSizeKey::from_slice(&i.to_be_bytes()); |
2223 | | assert!(tree.remove(&key)); |
2224 | | } |
2225 | | |
2226 | | assert!(tree.root.is_none()); |
2227 | | } |
2228 | | |
2229 | | #[derive(Debug, Clone, PartialEq)] |
2230 | | struct Kvt { |
2231 | | k: Vec<u8>, // Key |
2232 | | version: u64, // version |
2233 | | } |
2234 | | |
2235 | | #[test] |
2236 | | fn timed_insertion() { |
2237 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::<VariableSizeKey, i32>::new(); |
2238 | | |
2239 | | let kvts = vec![ |
2240 | | Kvt { |
2241 | | k: b"key1_0".to_vec(), |
2242 | | version: 0, |
2243 | | }, |
2244 | | Kvt { |
2245 | | k: b"key2_0".to_vec(), |
2246 | | version: 0, |
2247 | | }, |
2248 | | Kvt { |
2249 | | k: b"key3_0".to_vec(), |
2250 | | version: 0, |
2251 | | }, |
2252 | | Kvt { |
2253 | | k: b"key4_0".to_vec(), |
2254 | | version: 0, |
2255 | | }, |
2256 | | Kvt { |
2257 | | k: b"key5_0".to_vec(), |
2258 | | version: 0, |
2259 | | }, |
2260 | | Kvt { |
2261 | | k: b"key6_0".to_vec(), |
2262 | | version: 0, |
2263 | | }, |
2264 | | ]; |
2265 | | |
2266 | | // Insertion |
2267 | | for (idx, kvt) in kvts.iter().enumerate() { |
2268 | | let ts = if kvt.version == 0 { |
2269 | | idx as u64 + 1 |
2270 | | } else { |
2271 | | kvt.version |
2272 | | }; |
2273 | | assert!(tree |
2274 | | .insert(&VariableSizeKey::from(kvt.k.clone()), 1, ts, 0) |
2275 | | .is_ok()); |
2276 | | } |
2277 | | |
2278 | | // Verification |
2279 | | let mut curr_version = 1; |
2280 | | for kvt in &kvts { |
2281 | | let key = VariableSizeKey::from(kvt.k.clone()); |
2282 | | let (val, version, _ts) = tree.get(&key, 0).unwrap(); |
2283 | | assert_eq!(val, 1); |
2284 | | |
2285 | | if kvt.version == 0 { |
2286 | | assert_eq!(curr_version, version); |
2287 | | } else { |
2288 | | assert_eq!(kvt.version, version); |
2289 | | } |
2290 | | |
2291 | | curr_version += 1; |
2292 | | } |
2293 | | |
2294 | | // Root's version should match the greatest inserted version |
2295 | | assert_eq!(kvts.len() as u64, tree.version()); |
2296 | | } |
2297 | | |
2298 | | #[test] |
2299 | | fn timed_insertion_update_same_key() { |
2300 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::<VariableSizeKey, i32>::new(); |
2301 | | |
2302 | | let key1 = &VariableSizeKey::from_str("key_1").unwrap(); |
2303 | | |
2304 | | // insert key1 with version 0 |
2305 | | assert!(tree.insert(key1, 1, 0, 1).is_ok()); |
2306 | | // update key1 with version 0 |
2307 | | assert!(tree.insert(key1, 1, 0, 3).is_ok()); |
2308 | | |
2309 | | // get key1 should return version 2 as the same key was inserted and updated |
2310 | | let (val, version, ts) = tree.get(key1, 0).unwrap(); |
2311 | | assert_eq!(val, 1); |
2312 | | assert_eq!(version, 2); |
2313 | | assert_eq!(ts, 3); |
2314 | | |
2315 | | // update key1 with older version should fail |
2316 | | assert!(tree.insert(key1, 1, 1, 0).is_err()); |
2317 | | assert_eq!(tree.version(), 2); |
2318 | | |
2319 | | // update key1 with newer version should pass |
2320 | | assert!(tree.insert(key1, 1, 8, 5).is_ok()); |
2321 | | let (val, version, ts) = tree.get(key1, 0).unwrap(); |
2322 | | assert_eq!(val, 1); |
2323 | | assert_eq!(version, 8); |
2324 | | assert_eq!(ts, 5); |
2325 | | |
2326 | | assert_eq!(tree.version(), 8); |
2327 | | } |
2328 | | |
2329 | | #[test] |
2330 | | fn timed_insertion_update_non_increasing_version() { |
2331 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::<VariableSizeKey, i32>::new(); |
2332 | | |
2333 | | let key1 = VariableSizeKey::from_str("key_1").unwrap(); |
2334 | | let key2 = VariableSizeKey::from_str("key_2").unwrap(); |
2335 | | |
2336 | | // Initial insertion |
2337 | | assert!(tree.insert(&key1, 1, 10, 0).is_ok()); |
2338 | | let initial_version_key1 = tree.version(); |
2339 | | |
2340 | | // Attempt update with non-increasing version |
2341 | | assert!(tree.insert(&key1, 1, 2, 0).is_err()); |
2342 | | assert_eq!(initial_version_key1, tree.version()); |
2343 | | let (val, version, _) = tree.get(&key1, 0).unwrap(); |
2344 | | assert_eq!(val, 1); |
2345 | | assert_eq!(version, 10); |
2346 | | |
2347 | | // Insert another key |
2348 | | assert!(tree.insert(&key2, 1, 15, 0).is_ok()); |
2349 | | let initial_version_key2 = tree.version(); |
2350 | | |
2351 | | // Attempt update with non-increasing version for the second key |
2352 | | assert!(tree.insert(&key2, 1, 11, 0).is_err()); |
2353 | | assert_eq!(initial_version_key2, tree.version()); |
2354 | | let (val, version, _ts) = tree.get(&key2, 0).unwrap(); |
2355 | | assert_eq!(val, 1); |
2356 | | assert_eq!(version, 15); |
2357 | | |
2358 | | // Check if the max version of the tree is the max of the two inserted versions |
2359 | | assert_eq!(tree.version(), 15); |
2360 | | } |
2361 | | |
2362 | | #[test] |
2363 | | fn timed_deletion_check_root_ts() { |
2364 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::<VariableSizeKey, i32>::new(); |
2365 | | let key1 = VariableSizeKey::from_str("key_1").unwrap(); |
2366 | | let key2 = VariableSizeKey::from_str("key_2").unwrap(); |
2367 | | |
2368 | | // Initial insertions |
2369 | | assert!(tree.insert(&key1, 1, 0, 0).is_ok()); |
2370 | | assert!(tree.insert(&key2, 1, 0, 0).is_ok()); |
2371 | | assert_eq!(tree.version(), 2); |
2372 | | |
2373 | | // Deletions |
2374 | | assert!(tree.remove(&key1)); |
2375 | | assert!(tree.remove(&key2)); |
2376 | | |
2377 | | // tree version should still be 2 |
2378 | | assert_eq!(tree.version(), 2); |
2379 | | |
2380 | | // max version in the tree should be 0 post deletions |
2381 | | assert_eq!(tree.max_version_in_trie(), 0); |
2382 | | } |
2383 | | |
2384 | | fn from_be_bytes_key(k: &[u8]) -> u64 { |
2385 | | let padded_k = if k.len() < 8 { |
2386 | | let mut new_k = vec![0; 8]; |
2387 | | new_k[8 - k.len()..].copy_from_slice(k); |
2388 | | new_k |
2389 | | } else { |
2390 | | k.to_vec() |
2391 | | }; |
2392 | | |
2393 | | let k_slice = &padded_k[..8]; |
2394 | | u64::from_be_bytes(k_slice.try_into().unwrap()) |
2395 | | } |
2396 | | |
2397 | | #[test] |
2398 | | fn iter_seq_u16() { |
2399 | | let mut tree = Tree::<FixedSizeKey<16>, u16>::new(); |
2400 | | |
2401 | | // Insertion |
2402 | | for i in 0..u16::MAX { |
2403 | | let key: FixedSizeKey<16> = i.into(); |
2404 | | tree.insert(&key, i, 0, i as u64).unwrap(); |
2405 | | } |
2406 | | |
2407 | | // Iteration and verification |
2408 | | let mut len = 0usize; |
2409 | | let mut expected = 0u16; |
2410 | | |
2411 | | let tree_iter = tree.iter(); |
2412 | | for tree_entry in tree_iter { |
2413 | | let k = from_be_bytes_key(tree_entry.0); |
2414 | | assert_eq!(expected as u64, k); |
2415 | | let ts = tree_entry.3; |
2416 | | assert_eq!(expected as u64, ts); |
2417 | | expected = expected.wrapping_add(1); |
2418 | | len += 1; |
2419 | | } |
2420 | | |
2421 | | // Final assertion |
2422 | | assert_eq!(len, u16::MAX as usize); |
2423 | | } |
2424 | | |
2425 | | #[test] |
2426 | | fn iter_seq_u8() { |
2427 | | let mut tree: Tree<FixedSizeKey<32>, u8> = Tree::<FixedSizeKey<32>, u8>::new(); |
2428 | | |
2429 | | // Insertion |
2430 | | for i in 0..u8::MAX { |
2431 | | let key: FixedSizeKey<32> = i.into(); |
2432 | | tree.insert(&key, i, 0, 0).unwrap(); |
2433 | | } |
2434 | | |
2435 | | // Iteration and verification |
2436 | | let mut len = 0usize; |
2437 | | let mut expected = 0u8; |
2438 | | |
2439 | | let tree_iter = tree.iter(); |
2440 | | for tree_entry in tree_iter { |
2441 | | let k = from_be_bytes_key(tree_entry.0); |
2442 | | assert_eq!(expected as u64, k); |
2443 | | expected = expected.wrapping_add(1); |
2444 | | len += 1; |
2445 | | } |
2446 | | |
2447 | | // Final assertion |
2448 | | assert_eq!(len, u8::MAX as usize); |
2449 | | } |
2450 | | |
2451 | | #[test] |
2452 | | fn range_seq_u8() { |
2453 | | let mut tree: Tree<FixedSizeKey<8>, u8> = Tree::<FixedSizeKey<8>, u8>::new(); |
2454 | | |
2455 | | let max = u8::MAX; |
2456 | | // Insertion |
2457 | | for i in 0..=max { |
2458 | | let key: FixedSizeKey<8> = i.into(); |
2459 | | tree.insert(&key, i, 0, 0).unwrap(); |
2460 | | } |
2461 | | |
2462 | | // Test inclusive range |
2463 | | let start_key: FixedSizeKey<8> = 5u8.into(); |
2464 | | let end_key: FixedSizeKey<8> = max.into(); |
2465 | | let mut len = 0usize; |
2466 | | for _ in tree.range(start_key..=end_key) { |
2467 | | len += 1; |
2468 | | } |
2469 | | assert_eq!(len, max as usize - 4); |
2470 | | |
2471 | | // Test exclusive range |
2472 | | let start_key: FixedSizeKey<8> = 5u8.into(); |
2473 | | let end_key: FixedSizeKey<8> = max.into(); |
2474 | | let mut len = 0usize; |
2475 | | for _ in tree.range(start_key..end_key) { |
2476 | | len += 1; |
2477 | | } |
2478 | | assert_eq!(len, max as usize - 5); |
2479 | | |
2480 | | // Test range with different start and end keys |
2481 | | let start_key: FixedSizeKey<8> = 3u8.into(); |
2482 | | let end_key: FixedSizeKey<8> = 7u8.into(); |
2483 | | let mut len = 0usize; |
2484 | | for _ in tree.range(start_key..=end_key) { |
2485 | | len += 1; |
2486 | | } |
2487 | | assert_eq!(len, 5); |
2488 | | |
2489 | | // Test range with all keys |
2490 | | let start_key: FixedSizeKey<8> = 0u8.into(); |
2491 | | let end_key: FixedSizeKey<8> = max.into(); |
2492 | | let mut len = 0usize; |
2493 | | for _ in tree.range(start_key..=end_key) { |
2494 | | len += 1; |
2495 | | } |
2496 | | assert_eq!(len, 256); |
2497 | | } |
2498 | | |
2499 | | #[test] |
2500 | | fn range_seq_u16() { |
2501 | | let mut tree: Tree<FixedSizeKey<16>, u16> = Tree::<FixedSizeKey<16>, u16>::new(); |
2502 | | |
2503 | | let max = u16::MAX; |
2504 | | // Insertion |
2505 | | for i in 0..=max { |
2506 | | let key: FixedSizeKey<16> = i.into(); |
2507 | | tree.insert(&key, i, 0, 0).unwrap(); |
2508 | | } |
2509 | | |
2510 | | let mut len = 0usize; |
2511 | | let start_key: FixedSizeKey<16> = 0u8.into(); |
2512 | | let end_key: FixedSizeKey<16> = max.into(); |
2513 | | |
2514 | | for _ in tree.range(start_key..=end_key) { |
2515 | | len += 1; |
2516 | | } |
2517 | | assert_eq!(len, max as usize + 1); |
2518 | | } |
2519 | | |
2520 | | #[test] |
2521 | | fn same_key_with_versions() { |
2522 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2523 | | |
2524 | | // Insertions |
2525 | | let key1 = VariableSizeKey::from_str("abc").unwrap(); |
2526 | | let key2 = VariableSizeKey::from_str("efg").unwrap(); |
2527 | | tree.insert(&key1, 1, 0, 0).unwrap(); |
2528 | | tree.insert(&key1, 2, 10, 0).unwrap(); |
2529 | | tree.insert(&key2, 3, 11, 0).unwrap(); |
2530 | | |
2531 | | // Versioned retrievals and assertions |
2532 | | let (val, _, _) = tree.get(&key1, 1).unwrap(); |
2533 | | assert_eq!(val, 1); |
2534 | | let (val, _, _) = tree.get(&key1, 10).unwrap(); |
2535 | | assert_eq!(val, 2); |
2536 | | let (val, _, _) = tree.get(&key2, 11).unwrap(); |
2537 | | assert_eq!(val, 3); |
2538 | | |
2539 | | // Iteration and verification |
2540 | | let mut len = 0; |
2541 | | let tree_iter = tree.iter(); |
2542 | | for _ in tree_iter { |
2543 | | len += 1; |
2544 | | } |
2545 | | assert_eq!(len, 2); |
2546 | | } |
2547 | | |
2548 | | #[test] |
2549 | | fn insert_and_remove() { |
2550 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2551 | | let version = 0; |
2552 | | |
2553 | | // Keys to set |
2554 | | let set_keys = vec![ |
2555 | | [107, 101, 121, 48, 48, 0], |
2556 | | [107, 101, 121, 48, 49, 0], |
2557 | | [107, 101, 121, 48, 50, 0], |
2558 | | [107, 101, 121, 48, 51, 0], |
2559 | | [107, 101, 121, 48, 52, 0], |
2560 | | [107, 101, 121, 48, 53, 0], |
2561 | | [107, 101, 121, 48, 54, 0], |
2562 | | [107, 101, 121, 48, 55, 0], |
2563 | | [107, 101, 121, 48, 56, 0], |
2564 | | [107, 101, 121, 48, 57, 0], |
2565 | | [107, 101, 121, 49, 48, 0], |
2566 | | [107, 101, 121, 49, 49, 0], |
2567 | | [107, 101, 121, 49, 50, 0], |
2568 | | [107, 101, 121, 49, 51, 0], |
2569 | | [107, 101, 121, 49, 52, 0], |
2570 | | [107, 101, 121, 49, 53, 0], |
2571 | | [107, 101, 121, 49, 54, 0], |
2572 | | [107, 101, 121, 49, 55, 0], |
2573 | | [107, 101, 121, 49, 56, 0], |
2574 | | [107, 101, 121, 49, 57, 0], |
2575 | | [107, 101, 121, 50, 48, 0], |
2576 | | [107, 101, 121, 50, 49, 0], |
2577 | | [107, 101, 121, 50, 50, 0], |
2578 | | [107, 101, 121, 50, 51, 0], |
2579 | | [107, 101, 121, 50, 52, 0], |
2580 | | [107, 101, 121, 50, 53, 0], |
2581 | | ]; |
2582 | | |
2583 | | // Insert keys |
2584 | | for key_data in &set_keys { |
2585 | | let key = VariableSizeKey { |
2586 | | data: key_data.to_vec(), |
2587 | | }; |
2588 | | tree.insert(&key, 1, version, 0).unwrap(); |
2589 | | } |
2590 | | |
2591 | | // Delete one key at a time and check remaining keys |
2592 | | for (index, key_data_to_delete) in set_keys.iter().enumerate() { |
2593 | | let key_to_delete = VariableSizeKey { |
2594 | | data: key_data_to_delete.to_vec(), |
2595 | | }; |
2596 | | tree.remove(&key_to_delete); |
2597 | | |
2598 | | // Check remaining keys are still present |
2599 | | for (remaining_index, remaining_key_data) in set_keys.iter().enumerate() { |
2600 | | if remaining_index <= index { |
2601 | | // Check that the deleted key is no longer present |
2602 | | assert!( |
2603 | | tree.get(&key_to_delete, version).is_none(), |
2604 | | "Key {:?} should not exist after deletion", |
2605 | | key_data_to_delete |
2606 | | ); |
2607 | | // This key has been deleted; skip |
2608 | | continue; |
2609 | | } |
2610 | | let remaining_key = VariableSizeKey { |
2611 | | data: remaining_key_data.to_vec(), |
2612 | | }; |
2613 | | assert!( |
2614 | | tree.get(&remaining_key, version).is_some(), |
2615 | | "Key {:?} should exist", |
2616 | | remaining_key_data |
2617 | | ); |
2618 | | } |
2619 | | } |
2620 | | } |
2621 | | |
2622 | | fn generate_sequential_keys(count: usize) -> Vec<Vec<u8>> { |
2623 | | (0..count) |
2624 | | .map(|i| { |
2625 | | let mut key = i.to_le_bytes().to_vec(); |
2626 | | key.push(0); // Ensure each key ends with 0 |
2627 | | key |
2628 | | }) |
2629 | | .collect() |
2630 | | } |
2631 | | |
2632 | | fn generate_random_keys(count: usize) -> Vec<Vec<u8>> { |
2633 | | let mut rng = thread_rng(); |
2634 | | (0..count) |
2635 | | .map(|_| { |
2636 | | let mut key: Vec<u8> = (0..5).map(|_| rng.gen()).collect(); // Generate a key of 5 random bytes |
2637 | | key.push(0); // Ensure each key ends with 0 |
2638 | | key |
2639 | | }) |
2640 | | .collect() |
2641 | | } |
2642 | | |
2643 | | fn insert_remove_and_verify_keys(set_keys: Vec<Vec<u8>>) { |
2644 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2645 | | let version = 0; |
2646 | | |
2647 | | // Insert keys |
2648 | | for key_data in &set_keys { |
2649 | | let key = VariableSizeKey { |
2650 | | data: key_data.to_vec(), |
2651 | | }; |
2652 | | tree.insert(&key, 1, version, 0).unwrap(); |
2653 | | } |
2654 | | |
2655 | | // Delete one key at a time and check remaining keys |
2656 | | for (index, key_data_to_delete) in set_keys.iter().enumerate() { |
2657 | | let key_to_delete = VariableSizeKey { |
2658 | | data: key_data_to_delete.to_vec(), |
2659 | | }; |
2660 | | tree.remove(&key_to_delete); |
2661 | | |
2662 | | // Check remaining keys are still present |
2663 | | for (remaining_index, remaining_key_data) in set_keys.iter().enumerate() { |
2664 | | if remaining_index <= index { |
2665 | | // Check that the deleted key is no longer present |
2666 | | assert!( |
2667 | | tree.get(&key_to_delete, version).is_none(), |
2668 | | "Key {:?} should not exist after deletion", |
2669 | | key_data_to_delete |
2670 | | ); |
2671 | | // This key has been deleted; skip |
2672 | | continue; |
2673 | | } |
2674 | | let remaining_key = VariableSizeKey { |
2675 | | data: remaining_key_data.to_vec(), |
2676 | | }; |
2677 | | assert!( |
2678 | | tree.get(&remaining_key, version).is_some(), |
2679 | | "Key {:?} should exist", |
2680 | | remaining_key_data |
2681 | | ); |
2682 | | } |
2683 | | } |
2684 | | } |
2685 | | |
2686 | | #[test] |
2687 | | fn test_insert_remove_and_verify_keys_large_sequential() { |
2688 | | insert_remove_and_verify_keys(generate_sequential_keys(1000)); // Generate 1000 sequential keys |
2689 | | } |
2690 | | |
2691 | | #[test] |
2692 | | fn test_insert_remove_and_verify_keys_large_random() { |
2693 | | insert_remove_and_verify_keys(generate_random_keys(1000)); // Generate 1000 random keys |
2694 | | } |
2695 | | |
2696 | | #[test] |
2697 | | fn remove_non_existent_key() { |
2698 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2699 | | let key = VariableSizeKey::from_str("nonexistent").unwrap(); |
2700 | | let is_removed = tree.remove(&key); |
2701 | | assert!(!is_removed); |
2702 | | } |
2703 | | |
2704 | | #[test] |
2705 | | fn remove_key_from_empty_tree() { |
2706 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2707 | | let key = VariableSizeKey::from_str("test").unwrap(); |
2708 | | let is_removed = tree.remove(&key); |
2709 | | assert!(!is_removed); |
2710 | | } |
2711 | | |
2712 | | #[test] |
2713 | | fn sequential_removals() { |
2714 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2715 | | let keys = vec!["first", "second", "third"] |
2716 | | .into_iter() |
2717 | | .map(|k| VariableSizeKey::from_str(k).unwrap()) |
2718 | | .collect::<Vec<_>>(); |
2719 | | |
2720 | | // Insert keys |
2721 | | for key in &keys { |
2722 | | let _ = tree.insert(key, 1, 0, 0); |
2723 | | } |
2724 | | |
2725 | | // Remove keys sequentially |
2726 | | for key in &keys { |
2727 | | assert!(tree.remove(key)); |
2728 | | } |
2729 | | |
2730 | | // Verify all keys are removed |
2731 | | for key in keys { |
2732 | | assert!(tree.get(&key, 0).is_none()); |
2733 | | } |
2734 | | } |
2735 | | |
2736 | | #[test] |
2737 | | fn remove_until_empty() { |
2738 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2739 | | let keys = vec!["key1", "key2", "key3"] |
2740 | | .into_iter() |
2741 | | .map(|k| VariableSizeKey::from_str(k).unwrap()) |
2742 | | .collect::<Vec<_>>(); |
2743 | | |
2744 | | // Insert keys |
2745 | | for key in &keys { |
2746 | | let _ = tree.insert(key, 1, 0, 0); |
2747 | | } |
2748 | | |
2749 | | // Remove all keys |
2750 | | for key in &keys { |
2751 | | let is_removed = tree.remove(key); |
2752 | | assert!(is_removed); |
2753 | | } |
2754 | | } |
2755 | | |
2756 | | #[test] |
2757 | | fn remove_with_subsequent_inserts() { |
2758 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2759 | | let key1 = VariableSizeKey::from_str("key1").unwrap(); |
2760 | | let key2 = VariableSizeKey::from_str("key2").unwrap(); |
2761 | | |
2762 | | // Initial insert |
2763 | | let _ = tree.insert(&key1, 1, 0, 0); |
2764 | | // Remove |
2765 | | assert!(tree.remove(&key1)); |
2766 | | // Insert another key |
2767 | | let _ = tree.insert(&key2, 2, 0, 0); |
2768 | | |
2769 | | // Verify |
2770 | | assert!(tree.get(&key1, 0).is_none()); |
2771 | | assert_eq!(tree.get(&key2, 0).unwrap().0, 2); |
2772 | | } |
2773 | | |
2774 | | #[test] |
2775 | | fn insert_with_random_versions_and_verify_count() { |
2776 | | use rand::seq::SliceRandom; |
2777 | | use rand::Rng; |
2778 | | use std::collections::HashMap; |
2779 | | |
2780 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2781 | | let num_keys = 1000; // Large number of keys |
2782 | | let mut rng = rand::thread_rng(); |
2783 | | let mut expected_entries = 0; |
2784 | | |
2785 | | // Generate an array of increasing versions and shuffle it |
2786 | | let mut versions: Vec<usize> = (1..=num_keys).collect(); |
2787 | | versions.shuffle(&mut rng); |
2788 | | |
2789 | | // HashMap to store key-version mapping |
2790 | | let mut key_version_map = HashMap::new(); |
2791 | | |
2792 | | for (i, &version) in versions.iter().enumerate().take(num_keys) { |
2793 | | let id = format!("key{}", i + 1); |
2794 | | let key = VariableSizeKey::from_str(&id).unwrap(); |
2795 | | if tree |
2796 | | .insert_unchecked(&key, rng.gen::<i32>(), version as u64, 0) |
2797 | | .is_ok() |
2798 | | { |
2799 | | expected_entries += 1; |
2800 | | key_version_map.insert(id, version); |
2801 | | } |
2802 | | } |
2803 | | |
2804 | | // Verification |
2805 | | for (key, version) in key_version_map.iter() { |
2806 | | let key = VariableSizeKey::from_str(key).unwrap(); |
2807 | | assert!( |
2808 | | tree.get(&key, *version as u64).is_some(), |
2809 | | "The key {:?} at version {} should be present in the tree.", |
2810 | | key, |
2811 | | version |
2812 | | ); |
2813 | | } |
2814 | | |
2815 | | // Iteration and verification |
2816 | | let mut actual_entries = 0; |
2817 | | let tree_iter = tree.iter(); |
2818 | | for _ in tree_iter { |
2819 | | actual_entries += 1; |
2820 | | } |
2821 | | |
2822 | | assert_eq!( |
2823 | | actual_entries, expected_entries, |
2824 | | "The number of entries in the tree does not match the expected number of insertions." |
2825 | | ); |
2826 | | |
2827 | | assert_eq!(tree.version(), num_keys as u64); |
2828 | | } |
2829 | | |
2830 | | #[test] |
2831 | | fn insert_keys_in_decreasing_order_and_verify_count() { |
2832 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2833 | | let num_keys = 1000; |
2834 | | |
2835 | | for i in (0..num_keys).rev() { |
2836 | | let key = VariableSizeKey::from_str(&format!("key{}", i)).unwrap(); |
2837 | | tree.insert_unchecked(&key, i as i32, i, 0).unwrap(); |
2838 | | } |
2839 | | |
2840 | | // Verify total entries |
2841 | | let total_entries = tree.iter().count() as u64; |
2842 | | assert_eq!( |
2843 | | total_entries, num_keys, |
2844 | | "The total entries should be equal to the number of inserted keys." |
2845 | | ); |
2846 | | |
2847 | | assert_eq!(tree.version(), { num_keys }); |
2848 | | } |
2849 | | |
2850 | | #[test] |
2851 | | fn insert_same_key_different_versions_without_version_check_and_verify() { |
2852 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2853 | | let key = VariableSizeKey::from_str("key1").unwrap(); |
2854 | | |
2855 | | // Insert the same key with two different versions |
2856 | | tree.insert_unchecked(&key, 2, 2, 0).unwrap(); // Second version |
2857 | | tree.insert_unchecked(&key, 1, 1, 0).unwrap(); // First version |
2858 | | |
2859 | | // Verify the order during iteration |
2860 | | let mut iter = tree.iter(); |
2861 | | let (_, value, version, _) = iter.next().unwrap(); |
2862 | | assert_eq!(value, &2); |
2863 | | assert_eq!(version, 2); |
2864 | | |
2865 | | // Verify get at version 0 gives the latest version |
2866 | | let (value, version, _) = tree.get(&key, 0).unwrap(); |
2867 | | assert_eq!(value, 2); |
2868 | | assert_eq!(version, 2); |
2869 | | |
2870 | | assert_eq!(tree.version(), 2); |
2871 | | } |
2872 | | |
2873 | | #[test] |
2874 | | fn insert_multiple_keys_different_versions_and_verify() { |
2875 | | let mut tree = Tree::<VariableSizeKey, u64>::new(); |
2876 | | let num_keys = 1000; // Large number of keys for the test |
2877 | | |
2878 | | // Insert two versions for each key |
2879 | | for i in 0..num_keys { |
2880 | | let key = VariableSizeKey::from_str(&format!("key{}", i)).unwrap(); |
2881 | | tree.insert_unchecked(&key, i as u64 + 1000, 2, 0).unwrap(); // Second version |
2882 | | tree.insert_unchecked(&key, i as u64, 1, 0).unwrap(); // First version |
2883 | | } |
2884 | | |
2885 | | // Verify get at version 0 gives the latest version for each key |
2886 | | for i in 0..num_keys { |
2887 | | let key = VariableSizeKey::from_str(&format!("key{}", i)).unwrap(); |
2888 | | let (value, version, _) = tree.get(&key, 0).unwrap(); |
2889 | | assert_eq!( |
2890 | | value, |
2891 | | i as u64 + 1000, |
2892 | | "get at version 0 should return the latest version value." |
2893 | | ); |
2894 | | assert_eq!( |
2895 | | version, 2, |
2896 | | "get at version 0 should return the latest version number." |
2897 | | ); |
2898 | | } |
2899 | | } |
2900 | | |
2901 | | #[test] |
2902 | | fn test_range_scan_order_with_random_keys() { |
2903 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2904 | | |
2905 | | // Define keys in random order |
2906 | | let insert_words = ["test3", "test1", "test5", "test4", "test2", "test11"]; |
2907 | | |
2908 | | // Insert keys into the tree |
2909 | | for word in &insert_words { |
2910 | | tree.insert(&VariableSizeKey::from_str(word).unwrap(), 1, 1, 1) |
2911 | | .unwrap() |
2912 | | } |
2913 | | |
2914 | | // Define a range that encompasses all keys |
2915 | | let range = VariableSizeKey::from_slice("test1".as_bytes()) |
2916 | | ..=VariableSizeKey::from_slice("test5".as_bytes()); |
2917 | | |
2918 | | // Collect results of the range scan |
2919 | | let results: Vec<_> = tree.range(range).collect(); |
2920 | | assert_eq!(results.len(), insert_words.len()); |
2921 | | |
2922 | | // Expected order |
2923 | | let expected_order = ["test1", "test11", "test2", "test3", "test4", "test5"]; |
2924 | | |
2925 | | // Assert that results are in expected order |
2926 | | for (i, result) in results.iter().enumerate() { |
2927 | | let result_str = std::str::from_utf8(result.0).expect("Invalid UTF-8"); |
2928 | | assert_eq!(result_str, expected_order[i]); |
2929 | | } |
2930 | | } |
2931 | | |
2932 | | #[test] |
2933 | | fn test_add_keys_and_then_delete_keys_which_dont_exist() { |
2934 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2935 | | |
2936 | | // Insert 75 keys |
2937 | | for i in 1..=75 { |
2938 | | let key = VariableSizeKey::from_str(&format!("key{}", i)).unwrap(); |
2939 | | tree.insert(&key, i, i as u64, 0).unwrap(); |
2940 | | } |
2941 | | |
2942 | | // Attempt to delete 25 keys (76 to 100), which do not exist |
2943 | | for i in 76..=100 { |
2944 | | let key = VariableSizeKey::from_str(&format!("key{}", i)).unwrap(); |
2945 | | // Since these keys do not exist, remove should return an Err or false depending on implementation |
2946 | | assert!(!tree.remove(&key)); |
2947 | | } |
2948 | | |
2949 | | // Verify versions of a few keys |
2950 | | // For example, check the version of key1 and key75 |
2951 | | let key1 = VariableSizeKey::from_str("key1").unwrap(); |
2952 | | let key75 = VariableSizeKey::from_str("key75").unwrap(); |
2953 | | |
2954 | | assert_eq!(tree.get(&key1, 0).unwrap().1, 1); // Check version of key1 |
2955 | | assert_eq!(tree.get(&key75, 0).unwrap().1, 75); // Check version of key75 |
2956 | | } |
2957 | | |
2958 | | #[test] |
2959 | | fn test_nonexistent_key_removal_does_not_empty_tree() { |
2960 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2961 | | |
2962 | | for i in 1..=1 { |
2963 | | let key = VariableSizeKey::from_str(&format!("key{}", i)).unwrap(); |
2964 | | let _ = tree.insert(&key, i, i as u64, 0); |
2965 | | } |
2966 | | |
2967 | | for i in 2..=2 { |
2968 | | let key = VariableSizeKey::from_str(&format!("key{}", i)).unwrap(); |
2969 | | // Since these keys do not exist, remove should return an Err or false depending on implementation |
2970 | | assert!(!tree.remove(&key)); |
2971 | | } |
2972 | | |
2973 | | let key1 = VariableSizeKey::from_str("key1").unwrap(); |
2974 | | |
2975 | | assert_eq!(tree.get(&key1, 0).unwrap().1, 1); // Check version of key1 |
2976 | | } |
2977 | | |
2978 | | #[test] |
2979 | | fn test_tree_empty_after_removing_single_key() { |
2980 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2981 | | |
2982 | | // Insert a single key |
2983 | | let key = VariableSizeKey::from_str("key1").unwrap(); |
2984 | | tree.insert(&key, 1, 1, 0).unwrap(); |
2985 | | |
2986 | | // Remove the inserted key |
2987 | | tree.remove(&key); |
2988 | | |
2989 | | // Verify the tree is empty |
2990 | | assert!(tree.root.is_none()); |
2991 | | } |
2992 | | |
2993 | | #[test] |
2994 | | fn verify_iter() { |
2995 | | let mut tree = Tree::<VariableSizeKey, i32>::new(); |
2996 | | let mut rng = rand::thread_rng(); |
2997 | | let mut inserted_data = Vec::new(); |
2998 | | |
2999 | | // Generate and insert random keys with versions |
3000 | | for version in 1u64..=100 { |
3001 | | let random_key: String = (0..10).map(|_| rng.sample(Alphanumeric) as char).collect(); |
3002 | | let key = VariableSizeKey::from_str(&random_key).unwrap(); |
3003 | | let value = rng.gen_range(1..100); |
3004 | | let ts = rng.gen_range(1..100); |
3005 | | tree.insert(&key, value, version, ts).unwrap(); |
3006 | | inserted_data.push((key.to_slice().to_vec(), value, version, ts)); |
3007 | | } |
3008 | | |
3009 | | // Iteration and verification |
3010 | | let mut count = 0; |
3011 | | let tree_iter = tree.iter(); |
3012 | | for (key, value, version, ts) in tree_iter { |
3013 | | assert!(inserted_data.contains(&(key.to_vec(), *value, version, ts))); |
3014 | | count += 1; |
3015 | | } |
3016 | | |
3017 | | // Ensure all inserted items are iterated over |
3018 | | assert_eq!(inserted_data.len(), count); |
3019 | | } |
3020 | | |
3021 | | #[test] |
3022 | | fn test_get_all_versions() { |
3023 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3024 | | |
3025 | | // Scenario 1: Insert multiple values for the same key with different timestamps |
3026 | | let key1 = VariableSizeKey::from_str("test_key1").unwrap(); |
3027 | | let value1_1 = 10; |
3028 | | let value1_2 = 20; |
3029 | | let ts1_1 = 100; |
3030 | | let ts1_2 = 200; |
3031 | | tree.insert(&key1, value1_1, 0, ts1_1).unwrap(); |
3032 | | tree.insert(&key1, value1_2, 0, ts1_2).unwrap(); |
3033 | | |
3034 | | let history1 = tree.get_version_history(&key1).unwrap(); |
3035 | | assert_eq!(history1.len(), 2); |
3036 | | |
3037 | | let (retrieved_value1_1, v1_1, t1_1) = history1[0]; |
3038 | | assert_eq!(retrieved_value1_1, value1_1); |
3039 | | assert_eq!(v1_1, 1); |
3040 | | assert_eq!(t1_1, ts1_1); |
3041 | | |
3042 | | let (retrieved_value1_2, v1_2, t1_2) = history1[1]; |
3043 | | assert_eq!(retrieved_value1_2, value1_2); |
3044 | | assert_eq!(v1_2, 2); |
3045 | | assert_eq!(t1_2, ts1_2); |
3046 | | |
3047 | | // Scenario 2: Insert values for different keys |
3048 | | let key2 = VariableSizeKey::from_str("test_key2").unwrap(); |
3049 | | let value2 = 30; |
3050 | | let ts2 = 300; |
3051 | | tree.insert(&key2, value2, 0, ts2).unwrap(); |
3052 | | |
3053 | | let history2 = tree.get_version_history(&key2).unwrap(); |
3054 | | assert_eq!(history2.len(), 1); |
3055 | | |
3056 | | let (retrieved_value2, v2, t2) = history2[0]; |
3057 | | assert_eq!(retrieved_value2, value2); |
3058 | | assert_eq!(v2, 3); |
3059 | | assert_eq!(t2, ts2); |
3060 | | |
3061 | | // Scenario 3: Ensure no history for a non-existent key |
3062 | | let key3 = VariableSizeKey::from_str("non_existent_key").unwrap(); |
3063 | | assert!(tree.get_version_history(&key3).is_none()); |
3064 | | } |
3065 | | |
3066 | | #[test] |
3067 | | fn test_retrieving_value_at_future_timestamp() { |
3068 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3069 | | let key = VariableSizeKey::from_str("test_key").unwrap(); |
3070 | | let value = 10; |
3071 | | let ts_insert = 100; |
3072 | | let ts_future = 200; |
3073 | | tree.insert(&key, value, 0, ts_insert).unwrap(); |
3074 | | |
3075 | | let (retrieved_value, version, ts) = tree.get_at_ts(&key, ts_future).unwrap(); |
3076 | | assert_eq!(retrieved_value, value); |
3077 | | assert_eq!(version, 1); |
3078 | | assert_eq!(ts, ts_insert); |
3079 | | } |
3080 | | |
3081 | | #[test] |
3082 | | fn test_inserting_and_retrieving_with_same_timestamp() { |
3083 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3084 | | let key = VariableSizeKey::from_str("test_key").unwrap(); |
3085 | | let value1 = 10; |
3086 | | let value2 = 20; |
3087 | | let ts = 100; |
3088 | | tree.insert_unchecked(&key, value1, 1, ts).unwrap(); |
3089 | | tree.insert_unchecked(&key, value2, 1, ts).unwrap(); |
3090 | | |
3091 | | let (retrieved_value, version, t) = tree.get_at_ts(&key, ts).unwrap(); |
3092 | | assert_eq!(retrieved_value, value2); |
3093 | | assert_eq!(version, 1); |
3094 | | assert_eq!(t, ts); |
3095 | | } |
3096 | | |
3097 | | #[test] |
3098 | | fn test_get_at_ts_successful_retrieval() { |
3099 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::<VariableSizeKey, i32>::new(); |
3100 | | let key = VariableSizeKey::from_str("test_key").unwrap(); |
3101 | | let value = 10; |
3102 | | let version = 1; |
3103 | | let ts = 100; |
3104 | | tree.insert(&key, value, version, ts).unwrap(); |
3105 | | |
3106 | | let (retrieved_value, retrieved_version, retrieved_ts) = tree.get_at_ts(&key, ts).unwrap(); |
3107 | | assert_eq!(retrieved_value, value); |
3108 | | assert_eq!(retrieved_version, version); |
3109 | | assert_eq!(retrieved_ts, ts); |
3110 | | } |
3111 | | |
3112 | | #[test] |
3113 | | fn test_get_at_ts_key_not_found() { |
3114 | | let tree: Tree<VariableSizeKey, i32> = Tree::<VariableSizeKey, i32>::new(); |
3115 | | let key = VariableSizeKey::from_str("nonexistent_key").unwrap(); |
3116 | | let result = tree.get_at_ts(&key, 100); |
3117 | | assert!(result.is_none()); |
3118 | | } |
3119 | | |
3120 | | #[test] |
3121 | | fn test_get_at_ts_timestamp_before_insertion() { |
3122 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::<VariableSizeKey, i32>::new(); |
3123 | | let key = VariableSizeKey::from_str("test_key").unwrap(); |
3124 | | let value = 10; |
3125 | | let version = 1; |
3126 | | let ts = 100; |
3127 | | tree.insert(&key, value, version, ts).unwrap(); |
3128 | | |
3129 | | let result = tree.get_at_ts(&key, ts - 1); |
3130 | | assert!(result.is_none()); |
3131 | | } |
3132 | | |
3133 | | #[test] |
3134 | | fn test_get_at_ts_multiple_versions() { |
3135 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::<VariableSizeKey, i32>::new(); |
3136 | | let key = VariableSizeKey::from_str("test_key").unwrap(); |
3137 | | let value1 = 10; |
3138 | | let value2 = 11; |
3139 | | let version1 = 1; |
3140 | | let version2 = 2; |
3141 | | let ts1 = 100; |
3142 | | let ts2 = 200; |
3143 | | tree.insert(&key, value1, version1, ts1).unwrap(); |
3144 | | tree.insert(&key, value2, version2, ts2).unwrap(); |
3145 | | |
3146 | | let (retrieved_value, retrieved_version, retrieved_ts) = tree.get_at_ts(&key, ts2).unwrap(); |
3147 | | assert_eq!(retrieved_value, value2); |
3148 | | assert_eq!(retrieved_version, version2); |
3149 | | assert_eq!(retrieved_ts, ts2); |
3150 | | } |
3151 | | |
3152 | | #[test] |
3153 | | fn test_retrieving_value_at_timestamp_between_two_inserts() { |
3154 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3155 | | let key = VariableSizeKey::from_str("test_key").unwrap(); |
3156 | | let value1 = 10; |
3157 | | let value2 = 20; |
3158 | | let version1 = 1; |
3159 | | let version2 = 2; |
3160 | | let ts1 = 100; |
3161 | | let ts2 = 200; |
3162 | | let ts_query = 150; |
3163 | | tree.insert(&key, value1, version1, ts1).unwrap(); |
3164 | | tree.insert(&key, value2, version2, ts2).unwrap(); |
3165 | | |
3166 | | let (retrieved_value, retrieved_version, retrieved_ts) = |
3167 | | tree.get_at_ts(&key, ts_query).unwrap(); |
3168 | | assert_eq!(retrieved_value, value1); |
3169 | | assert_eq!(retrieved_version, version1); |
3170 | | assert_eq!(retrieved_ts, ts1); |
3171 | | } |
3172 | | |
3173 | | #[test] |
3174 | | fn test_inserting_values_with_decreasing_timestamps() { |
3175 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3176 | | let key = VariableSizeKey::from_str("test_key").unwrap(); |
3177 | | let value1 = 10; |
3178 | | let value2 = 20; |
3179 | | let ts1 = 200; |
3180 | | let ts2 = 100; |
3181 | | tree.insert(&key, value1, 1, ts1).unwrap(); |
3182 | | tree.insert(&key, value2, 2, ts2).unwrap(); |
3183 | | |
3184 | | let (retrieved_value_early, _, _) = tree.get_at_ts(&key, ts2).unwrap(); |
3185 | | let (retrieved_value_late, _, _) = tree.get_at_ts(&key, ts1).unwrap(); |
3186 | | assert_eq!(retrieved_value_early, value2); |
3187 | | assert_eq!(retrieved_value_late, value1); |
3188 | | } |
3189 | | |
3190 | | #[test] |
3191 | | fn test_retrieving_value_after_deleting_it() { |
3192 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3193 | | let key = VariableSizeKey::from_str("test_key").unwrap(); |
3194 | | let value = 10; |
3195 | | let ts_insert = 100; |
3196 | | let ts_query = 150; |
3197 | | tree.insert(&key, value, 1, ts_insert).unwrap(); |
3198 | | tree.remove(&key); |
3199 | | |
3200 | | let result = tree.get_at_ts(&key, ts_query); |
3201 | | assert!(result.is_none()); |
3202 | | } |
3203 | | |
3204 | | #[test] |
3205 | | fn test_latest_by_version() { |
3206 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3207 | | let key = VariableSizeKey::from_str("test_key").unwrap(); |
3208 | | tree.insert_unchecked(&key, 10, 1, 100).unwrap(); |
3209 | | tree.insert_unchecked(&key, 20, 2, 200).unwrap(); |
3210 | | tree.insert_unchecked(&key, 30, 3, 300).unwrap(); |
3211 | | |
3212 | | let query_type = QueryType::LatestByVersion(3); |
3213 | | let result = tree.get_value_by_query(&key, query_type).unwrap(); |
3214 | | assert_eq!(result, (30, 3, 300)); |
3215 | | assert_eq!(tree.version(), 3); |
3216 | | } |
3217 | | |
3218 | | #[test] |
3219 | | fn test_latest_by_ts() { |
3220 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3221 | | let key = VariableSizeKey::from_str("test_key").unwrap(); |
3222 | | tree.insert_unchecked(&key, 10, 1, 100).unwrap(); |
3223 | | tree.insert_unchecked(&key, 20, 2, 200).unwrap(); |
3224 | | tree.insert_unchecked(&key, 30, 3, 300).unwrap(); |
3225 | | |
3226 | | let query_type = QueryType::LatestByTs(300); |
3227 | | let result = tree.get_value_by_query(&key, query_type).unwrap(); |
3228 | | assert_eq!(result, (30, 3, 300)); |
3229 | | assert_eq!(tree.version(), 3); |
3230 | | } |
3231 | | |
3232 | | #[test] |
3233 | | fn test_last_less_than_ts() { |
3234 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3235 | | let key = VariableSizeKey::from_str("test_key").unwrap(); |
3236 | | tree.insert_unchecked(&key, 10, 1, 100).unwrap(); |
3237 | | tree.insert_unchecked(&key, 20, 2, 150).unwrap(); |
3238 | | tree.insert_unchecked(&key, 30, 3, 200).unwrap(); |
3239 | | |
3240 | | let query_type = QueryType::LastLessThanTs(150); |
3241 | | let result = tree.get_value_by_query(&key, query_type).unwrap(); |
3242 | | assert_eq!(result, (10, 1, 100)); |
3243 | | assert_eq!(tree.version(), 3); |
3244 | | } |
3245 | | |
3246 | | #[test] |
3247 | | fn test_last_less_or_equal_ts() { |
3248 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3249 | | let key = VariableSizeKey::from_str("test_key").unwrap(); |
3250 | | tree.insert_unchecked(&key, 10, 1, 100).unwrap(); |
3251 | | tree.insert_unchecked(&key, 20, 2, 150).unwrap(); |
3252 | | tree.insert_unchecked(&key, 30, 3, 200).unwrap(); |
3253 | | |
3254 | | let query_type = QueryType::LastLessOrEqualTs(150); |
3255 | | let result = tree.get_value_by_query(&key, query_type).unwrap(); |
3256 | | assert_eq!(result, (20, 2, 150)); |
3257 | | assert_eq!(tree.version(), 3); |
3258 | | } |
3259 | | |
3260 | | #[test] |
3261 | | fn test_first_greater_than_ts() { |
3262 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3263 | | let key = VariableSizeKey::from_str("test_key").unwrap(); |
3264 | | tree.insert_unchecked(&key, 10, 1, 100).unwrap(); |
3265 | | tree.insert_unchecked(&key, 20, 2, 150).unwrap(); |
3266 | | tree.insert_unchecked(&key, 30, 3, 200).unwrap(); |
3267 | | |
3268 | | let query_type = QueryType::FirstGreaterThanTs(150); |
3269 | | let result = tree.get_value_by_query(&key, query_type).unwrap(); |
3270 | | assert_eq!(result, (30, 3, 200)); |
3271 | | assert_eq!(tree.version(), 3); |
3272 | | } |
3273 | | |
3274 | | #[test] |
3275 | | fn test_first_greater_or_equal_ts() { |
3276 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3277 | | let key = VariableSizeKey::from_str("test_key").unwrap(); |
3278 | | tree.insert_unchecked(&key, 10, 1, 100).unwrap(); |
3279 | | tree.insert_unchecked(&key, 20, 2, 150).unwrap(); |
3280 | | tree.insert_unchecked(&key, 30, 3, 200).unwrap(); |
3281 | | |
3282 | | let query_type = QueryType::FirstGreaterOrEqualTs(150); |
3283 | | let result = tree.get_value_by_query(&key, query_type).unwrap(); |
3284 | | assert_eq!(result, (20, 2, 150)); |
3285 | | assert_eq!(tree.version(), 3); |
3286 | | } |
3287 | | |
3288 | | #[test] |
3289 | | fn test_insert_or_replace() { |
3290 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3291 | | let key = VariableSizeKey::from_str("key").unwrap(); |
3292 | | |
3293 | | tree.insert_or_replace(&key, 1, 10, 100).unwrap(); |
3294 | | tree.insert_or_replace(&key, 2, 20, 200).unwrap(); |
3295 | | |
3296 | | let history = tree.get_version_history(&key).unwrap(); |
3297 | | assert_eq!(history.len(), 1); |
3298 | | assert_eq!(history[0], (2, 20, 200)); |
3299 | | } |
3300 | | |
3301 | | #[test] |
3302 | | fn test_insert_or_replace_unchecked() { |
3303 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3304 | | let key = VariableSizeKey::from_str("key").unwrap(); |
3305 | | |
3306 | | // Scenario 1: the second value is more recent than the first one. |
3307 | | tree.insert_or_replace_unchecked(&key, 1, 10, 100).unwrap(); |
3308 | | tree.insert_or_replace_unchecked(&key, 2, 20, 200).unwrap(); |
3309 | | |
3310 | | let history = tree.get_version_history(&key).unwrap(); |
3311 | | assert_eq!(history.len(), 1); |
3312 | | assert_eq!(history[0], (2, 20, 200)); |
3313 | | |
3314 | | // Scenario 2: the new value has the smaller version and hence |
3315 | | // is older than the one already in the tree. Discard the new |
3316 | | // value. |
3317 | | tree.insert_or_replace_unchecked(&key, 1, 1, 1).unwrap(); |
3318 | | |
3319 | | let history = tree.get_version_history(&key).unwrap(); |
3320 | | assert_eq!(history.len(), 1); |
3321 | | assert_eq!(history[0], (2, 20, 200)); |
3322 | | } |
3323 | | |
3324 | | #[test] |
3325 | | fn scan_empty_range() { |
3326 | | let tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3327 | | let result: Vec<_> = tree.scan_at_ts(RangeFull {}, 0).collect(); |
3328 | | assert!(result.is_empty()); |
3329 | | } |
3330 | | |
3331 | | #[test] |
3332 | | fn scan_range_includes_some_keys() { |
3333 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3334 | | let keys = ["key_1", "key_2", "key_3"]; |
3335 | | for key in keys.iter() { |
3336 | | tree.insert(&VariableSizeKey::from_str(key).unwrap(), 1, 0, 0) |
3337 | | .unwrap(); |
3338 | | } |
3339 | | let range = VariableSizeKey::from_slice("key_1".as_bytes()) |
3340 | | ..=VariableSizeKey::from_slice("key_2".as_bytes()); |
3341 | | let values: Vec<_> = tree.scan_at_ts(range, 0).collect(); |
3342 | | assert_eq!(values.len(), 2); |
3343 | | } |
3344 | | |
3345 | | #[test] |
3346 | | fn scan_range_includes_all_keys() { |
3347 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3348 | | let keys = ["key_1", "key_2", "key_3"]; |
3349 | | for key in keys.iter() { |
3350 | | tree.insert(&VariableSizeKey::from_str(key).unwrap(), 1, 0, 0) |
3351 | | .unwrap(); |
3352 | | } |
3353 | | let values: Vec<_> = tree.scan_at_ts(RangeFull {}, 0).collect(); |
3354 | | assert_eq!(values.len(), keys.len()); |
3355 | | } |
3356 | | |
3357 | | #[test] |
3358 | | fn scan_range_includes_no_keys() { |
3359 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3360 | | let keys = ["key_1", "key_2", "key_3"]; |
3361 | | for key in keys.iter() { |
3362 | | tree.insert(&VariableSizeKey::from_str(key).unwrap(), 1, 0, 0) |
3363 | | .unwrap(); |
3364 | | } |
3365 | | let range = VariableSizeKey::from_slice("key_4".as_bytes()) |
3366 | | ..VariableSizeKey::from_slice("key_5".as_bytes()); |
3367 | | let values: Vec<_> = tree.scan_at_ts(range, 0).collect(); |
3368 | | assert!(values.is_empty()); |
3369 | | } |
3370 | | |
3371 | | #[test] |
3372 | | fn scan_at_different_timestamps() { |
3373 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3374 | | let keys = ["key_1", "key_2", "key_3"]; |
3375 | | for (i, key) in keys.iter().enumerate() { |
3376 | | tree.insert( |
3377 | | &VariableSizeKey::from_str(key).unwrap(), |
3378 | | i as i32, |
3379 | | 0, |
3380 | | i as u64, |
3381 | | ) |
3382 | | .unwrap(); |
3383 | | } |
3384 | | for (i, _) in keys.iter().enumerate() { |
3385 | | let values: Vec<_> = tree.scan_at_ts(RangeFull {}, i as u64).collect(); |
3386 | | assert_eq!(values.len(), i + 1); |
3387 | | } |
3388 | | } |
3389 | | |
3390 | | #[test] |
3391 | | fn large_number_of_inserts() { |
3392 | | let mut tree: Tree<VariableSizeKey, u64> = Tree::new(); |
3393 | | let num_keys = 10000u64; // Large number of keys |
3394 | | for i in 0..num_keys { |
3395 | | let key = format!("key_{}", i); |
3396 | | // Insert with increasing values and timestamps |
3397 | | tree.insert(&VariableSizeKey::from_str(&key).unwrap(), i, 0, i) |
3398 | | .unwrap(); |
3399 | | } |
3400 | | |
3401 | | let values: Vec<_> = tree.scan_at_ts(RangeFull {}, num_keys).collect(); |
3402 | | assert_eq!(values.len(), num_keys as usize); // Expect all keys to be visible |
3403 | | } |
3404 | | |
3405 | | #[test] |
3406 | | fn scan_at_various_timestamps() { |
3407 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3408 | | let keys = ["key_1", "key_2", "key_3"]; |
3409 | | for (i, key) in keys.iter().enumerate() { |
3410 | | // Insert with non-sequential timestamps to test out-of-order handling |
3411 | | let timestamp = ((i + 1) * 2) as u64; |
3412 | | tree.insert( |
3413 | | &VariableSizeKey::from_str(key).unwrap(), |
3414 | | i as i32, |
3415 | | 0, |
3416 | | timestamp, |
3417 | | ) |
3418 | | .unwrap(); |
3419 | | } |
3420 | | |
3421 | | // Scan at a timestamp before any insertions |
3422 | | let result_before: Vec<_> = tree.scan_at_ts(RangeFull {}, 0).collect(); |
3423 | | assert!(result_before.is_empty()); |
3424 | | |
3425 | | // Scan between insertions |
3426 | | let result_mid: Vec<_> = tree.scan_at_ts(RangeFull {}, 4).collect(); |
3427 | | assert_eq!(result_mid.len(), 2); // Expect first two keys to be visible |
3428 | | |
3429 | | // Scan after all insertions |
3430 | | let result_after: Vec<_> = tree.scan_at_ts(RangeFull {}, 7).collect(); |
3431 | | assert_eq!(result_after.len(), keys.len()); // Expect all keys to be visible |
3432 | | } |
3433 | | |
3434 | | #[test] |
3435 | | fn scan_with_single_item() { |
3436 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::new(); |
3437 | | // Insert a single item into the tree |
3438 | | tree.insert(&VariableSizeKey::from_str("key_1").unwrap(), 42, 0, 0) |
3439 | | .unwrap(); |
3440 | | |
3441 | | let values: Vec<_> = tree.scan_at_ts(RangeFull {}, 0).collect(); |
3442 | | assert_eq!(values.len(), 1); |
3443 | | assert_eq!(values[0].1, &42); |
3444 | | } |
3445 | | |
3446 | | #[test] |
3447 | | fn snapshot_isolation() { |
3448 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::<VariableSizeKey, i32>::new(); |
3449 | | let key_1 = VariableSizeKey::from_str("key_1").unwrap(); |
3450 | | let key_2 = VariableSizeKey::from_str("key_2").unwrap(); |
3451 | | let key_3_snap1 = VariableSizeKey::from_str("key_3_snap1").unwrap(); |
3452 | | let key_3_snap2 = VariableSizeKey::from_str("key_3_snap2").unwrap(); |
3453 | | |
3454 | | assert!(tree.insert(&key_1, 1, 0, 0).is_ok()); |
3455 | | |
3456 | | // Keys inserted before snapshot creation should be visible |
3457 | | let mut snap1 = tree.clone(); |
3458 | | assert_eq!(snap1.get(&key_1, 0).unwrap(), (1, 1, 0)); |
3459 | | |
3460 | | let mut snap2 = tree.clone(); |
3461 | | assert_eq!(snap2.get(&key_1, 0).unwrap(), (1, 1, 0)); |
3462 | | |
3463 | | // Keys inserted after snapshot creation should not be visible to other snapshots |
3464 | | assert!(tree.insert(&key_2, 1, 0, 0).is_ok()); |
3465 | | assert!(snap1.get(&key_2, 0).is_none()); |
3466 | | assert!(snap2.get(&key_2, 0).is_none()); |
3467 | | |
3468 | | // Keys inserted after snapshot creation should be visible to the snapshot that inserted them |
3469 | | snap1.insert(&key_3_snap1, 2, 0, 0).unwrap(); |
3470 | | assert_eq!(snap1.get(&key_3_snap1, 0).unwrap(), (2, 2, 0)); |
3471 | | |
3472 | | snap2.insert(&key_3_snap2, 3, 0, 0).unwrap(); |
3473 | | assert_eq!(snap2.get(&key_3_snap2, 0).unwrap(), (3, 2, 0)); |
3474 | | |
3475 | | // Keys inserted after snapshot creation should not be visible to other snapshots |
3476 | | assert!(snap1.get(&key_3_snap2, 0).is_none()); |
3477 | | assert!(snap2.get(&key_3_snap1, 0).is_none()); |
3478 | | } |
3479 | | |
3480 | | #[test] |
3481 | | fn insert_with_prefix_match() { |
3482 | | let key1 = VariableSizeKey::from_slice(b"key1"); |
3483 | | let key17 = VariableSizeKey::from_slice(b"key17"); |
3484 | | |
3485 | | // Ascending order |
3486 | | { |
3487 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::<VariableSizeKey, i32>::new(); |
3488 | | tree.insert(&key1, 1, 1, 1).unwrap(); |
3489 | | tree.insert(&key17, 17, 17, 17).unwrap(); |
3490 | | |
3491 | | assert_eq!(tree.get(&key1, 1).unwrap(), (1, 1, 1)); |
3492 | | assert_eq!(tree.get(&key17, 17).unwrap(), (17, 17, 17)); |
3493 | | |
3494 | | assert!(tree.remove(&key1)); |
3495 | | assert!(tree.remove(&key17)); |
3496 | | } |
3497 | | |
3498 | | // Descending order |
3499 | | { |
3500 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::<VariableSizeKey, i32>::new(); |
3501 | | tree.insert(&key17, 17, 1, 1).unwrap(); |
3502 | | tree.insert(&key1, 1, 2, 2).unwrap(); |
3503 | | |
3504 | | assert_eq!(tree.get(&key17, 1).unwrap(), (17, 1, 1)); |
3505 | | assert_eq!(tree.get(&key1, 2).unwrap(), (1, 2, 2)); |
3506 | | |
3507 | | assert!(tree.remove(&key17)); |
3508 | | assert!(tree.remove(&key1)); |
3509 | | } |
3510 | | } |
3511 | | |
3512 | | #[test] |
3513 | | fn insert_mut_with_prefix_match() { |
3514 | | let key1 = VariableSizeKey::from_slice(b"key1"); |
3515 | | let key17 = VariableSizeKey::from_slice(b"key17"); |
3516 | | |
3517 | | // Ascending order |
3518 | | { |
3519 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::<VariableSizeKey, i32>::new(); |
3520 | | tree.insert_unchecked(&key1, 1, 1, 1).unwrap(); |
3521 | | tree.insert_unchecked(&key17, 17, 17, 17).unwrap(); |
3522 | | |
3523 | | assert_eq!(tree.get(&key1, 1).unwrap(), (1, 1, 1)); |
3524 | | assert_eq!(tree.get(&key17, 17).unwrap(), (17, 17, 17)); |
3525 | | |
3526 | | assert!(tree.remove(&key1)); |
3527 | | assert!(tree.remove(&key17)); |
3528 | | } |
3529 | | |
3530 | | // Descending order |
3531 | | { |
3532 | | let mut tree: Tree<VariableSizeKey, i32> = Tree::<VariableSizeKey, i32>::new(); |
3533 | | tree.insert_unchecked(&key17, 17, 1, 1).unwrap(); |
3534 | | tree.insert_unchecked(&key1, 1, 2, 2).unwrap(); |
3535 | | |
3536 | | assert_eq!(tree.get(&key17, 1).unwrap(), (17, 1, 1)); |
3537 | | assert_eq!(tree.get(&key1, 2).unwrap(), (1, 2, 2)); |
3538 | | |
3539 | | assert!(tree.remove(&key17)); |
3540 | | assert!(tree.remove(&key1)); |
3541 | | } |
3542 | | } |
3543 | | |
3544 | | #[test] |
3545 | | fn test_scan_at_ts_double_ended_iterator() { |
3546 | | let mut tree: Tree<FixedSizeKey<16>, String> = Tree::new(); |
3547 | | |
3548 | | let key1: FixedSizeKey<16> = 1u16.into(); |
3549 | | let key2: FixedSizeKey<16> = 2u16.into(); |
3550 | | let key3: FixedSizeKey<16> = 3u16.into(); |
3551 | | |
3552 | | // Insert keys at different timestamps |
3553 | | let _ = tree.insert_unchecked(&key1, "value1_ts100".to_string(), 1, 100); |
3554 | | let _ = tree.insert_unchecked(&key1, "value1_ts200".to_string(), 2, 200); |
3555 | | let _ = tree.insert_unchecked(&key2, "value2_ts150".to_string(), 1, 150); |
3556 | | let _ = tree.insert_unchecked(&key2, "value2_ts250".to_string(), 2, 250); |
3557 | | let _ = tree.insert_unchecked(&key3, "value3_ts300".to_string(), 1, 300); |
3558 | | |
3559 | | // Test scan_at_ts at timestamp 175 (should get key1@ts100, key2@ts150) |
3560 | | let scan_iter = tree.scan_at_ts(key1.clone()..=key3.clone(), 175); |
3561 | | let forward_results: Vec<_> = scan_iter.collect(); |
3562 | | |
3563 | | let expected_forward = [(key1.as_slice(), "value1_ts100", 1, 100), |
3564 | | (key2.as_slice(), "value2_ts150", 1, 150)]; |
3565 | | |
3566 | | assert_eq!(forward_results.len(), expected_forward.len()); |
3567 | | for (i, (actual, expected)) in forward_results |
3568 | | .iter() |
3569 | | .zip(expected_forward.iter()) |
3570 | | .enumerate() |
3571 | | { |
3572 | | assert_eq!(actual.0, expected.0, "Key mismatch at index {}", i); |
3573 | | assert_eq!(actual.1, expected.1, "Value mismatch at index {}", i); |
3574 | | assert_eq!(actual.2, expected.2, "Version mismatch at index {}", i); |
3575 | | assert_eq!(actual.3, expected.3, "Timestamp mismatch at index {}", i); |
3576 | | } |
3577 | | |
3578 | | // Test backward iteration |
3579 | | let scan_iter = tree.scan_at_ts(key1.clone()..=key3.clone(), 175); |
3580 | | let backward_results: Vec<_> = scan_iter.rev().collect(); |
3581 | | |
3582 | | let expected_backward = [(key2.as_slice(), "value2_ts150", 1, 150), |
3583 | | (key1.as_slice(), "value1_ts100", 1, 100)]; |
3584 | | |
3585 | | assert_eq!(backward_results.len(), expected_backward.len()); |
3586 | | for (i, (actual, expected)) in backward_results |
3587 | | .iter() |
3588 | | .zip(expected_backward.iter()) |
3589 | | .enumerate() |
3590 | | { |
3591 | | assert_eq!( |
3592 | | actual.0, expected.0, |
3593 | | "Key mismatch at index {} in backward iteration", |
3594 | | i |
3595 | | ); |
3596 | | assert_eq!( |
3597 | | actual.1, expected.1, |
3598 | | "Value mismatch at index {} in backward iteration", |
3599 | | i |
3600 | | ); |
3601 | | assert_eq!( |
3602 | | actual.2, expected.2, |
3603 | | "Version mismatch at index {} in backward iteration", |
3604 | | i |
3605 | | ); |
3606 | | assert_eq!( |
3607 | | actual.3, expected.3, |
3608 | | "Timestamp mismatch at index {} in backward iteration", |
3609 | | i |
3610 | | ); |
3611 | | } |
3612 | | |
3613 | | // Test that forward and backward results are exact reverses |
3614 | | let mut forward_reversed = forward_results.clone(); |
3615 | | forward_reversed.reverse(); |
3616 | | assert_eq!( |
3617 | | backward_results, forward_reversed, |
3618 | | "Backward iteration should be exact reverse of forward" |
3619 | | ); |
3620 | | } |
3621 | | |
3622 | | #[test] |
3623 | | fn test_scan_at_ts_single_element_double_ended() { |
3624 | | let mut tree: Tree<FixedSizeKey<16>, String> = Tree::new(); |
3625 | | let key: FixedSizeKey<16> = 5u16.into(); |
3626 | | tree.insert(&key, "value".to_string(), 1, 100).unwrap(); |
3627 | | |
3628 | | // Test forward iteration |
3629 | | let scan_iter = tree.scan_at_ts(key.clone()..=key.clone(), 150); |
3630 | | let forward: Vec<_> = scan_iter.collect(); |
3631 | | |
3632 | | // Test backward iteration |
3633 | | let scan_iter = tree.scan_at_ts(key.clone()..=key.clone(), 150); |
3634 | | let backward: Vec<_> = scan_iter.rev().collect(); |
3635 | | |
3636 | | assert_eq!(forward.len(), 1); |
3637 | | assert_eq!(backward.len(), 1); |
3638 | | assert_eq!(forward, backward); // Single element should be same both ways |
3639 | | |
3640 | | // Test with timestamp before insertion |
3641 | | let scan_iter = tree.scan_at_ts(key.clone()..=key.clone(), 50); |
3642 | | let before_ts: Vec<_> = scan_iter.collect(); |
3643 | | assert!(before_ts.is_empty()); |
3644 | | |
3645 | | // Test backward iteration with timestamp before insertion |
3646 | | let scan_iter = tree.scan_at_ts(key.clone()..=key.clone(), 50); |
3647 | | let before_ts_backward: Vec<_> = scan_iter.rev().collect(); |
3648 | | assert!(before_ts_backward.is_empty()); |
3649 | | } |
3650 | | |
3651 | | #[test] |
3652 | | fn test_scan_at_ts_mixed_iteration() { |
3653 | | let mut tree: Tree<FixedSizeKey<16>, String> = Tree::new(); |
3654 | | let keys: Vec<FixedSizeKey<16>> = (1..=10).map(|i| (i as u16).into()).collect(); |
3655 | | |
3656 | | // Insert keys with different timestamps |
3657 | | for (i, key) in keys.iter().enumerate() { |
3658 | | tree.insert(key, format!("value_{}", i), 1, (i * 10) as u64) |
3659 | | .unwrap(); |
3660 | | } |
3661 | | |
3662 | | let start_key: FixedSizeKey<16> = 3u16.into(); |
3663 | | let end_key: FixedSizeKey<16> = 8u16.into(); |
3664 | | let scan_iter = tree.scan_at_ts(start_key..=end_key, 50); // Should get keys 3,4,5 |
3665 | | |
3666 | | let mut iter = scan_iter; |
3667 | | let mut seen_values = std::collections::HashSet::new(); |
3668 | | let mut forward_results = Vec::new(); |
3669 | | let mut backward_results = Vec::new(); |
3670 | | |
3671 | | // Mix forward and backward iteration |
3672 | | use rand::Rng; |
3673 | | let mut rng = rand::thread_rng(); |
3674 | | |
3675 | | while seen_values.len() < 3 { |
3676 | | // We expect 3 keys (3,4,5) |
3677 | | if rng.gen_bool(0.5) { |
3678 | | // Forward iteration |
3679 | | if let Some((_, v, _, _)) = iter.next() { |
3680 | | if seen_values.insert(v.clone()) { |
3681 | | forward_results.push(v); |
3682 | | } |
3683 | | } |
3684 | | } else { |
3685 | | // Backward iteration |
3686 | | if let Some((_, v, _, _)) = iter.next_back() { |
3687 | | if seen_values.insert(v.clone()) { |
3688 | | backward_results.push(v); |
3689 | | } |
3690 | | } |
3691 | | } |
3692 | | } |
3693 | | |
3694 | | // Verify we got all expected values |
3695 | | assert_eq!(seen_values.len(), 3); |
3696 | | |
3697 | | // Verify forward and backward results combined contain all expected values |
3698 | | let mut all_results = forward_results.clone(); |
3699 | | all_results.extend(backward_results); |
3700 | | assert_eq!(all_results.len(), 3); |
3701 | | } |
3702 | | |
3703 | | #[test] |
3704 | | fn test_scan_at_ts_timestamp_edge_cases() { |
3705 | | let mut tree: Tree<FixedSizeKey<16>, String> = Tree::new(); |
3706 | | let key1: FixedSizeKey<16> = 1u16.into(); |
3707 | | let key2: FixedSizeKey<16> = 2u16.into(); |
3708 | | let key3: FixedSizeKey<16> = 3u16.into(); |
3709 | | |
3710 | | // Insert keys at specific timestamps |
3711 | | tree.insert(&key1, "value1_ts100".to_string(), 1, 100) |
3712 | | .unwrap(); |
3713 | | tree.insert(&key2, "value2_ts200".to_string(), 1, 200) |
3714 | | .unwrap(); |
3715 | | tree.insert(&key3, "value3_ts300".to_string(), 1, 300) |
3716 | | .unwrap(); |
3717 | | |
3718 | | // Test scanning before any entries exist |
3719 | | let scan_iter = tree.scan_at_ts(key1.clone()..=key3.clone(), 50); |
3720 | | let before_any: Vec<_> = scan_iter.collect(); |
3721 | | assert!(before_any.is_empty()); |
3722 | | |
3723 | | // Test scanning at exact timestamp of first entry |
3724 | | let scan_iter = tree.scan_at_ts(key1.clone()..=key3.clone(), 100); |
3725 | | let at_first: Vec<_> = scan_iter.collect(); |
3726 | | assert_eq!(at_first.len(), 1); |
3727 | | assert_eq!(at_first[0].1, "value1_ts100"); |
3728 | | |
3729 | | // Test scanning between entries |
3730 | | let scan_iter = tree.scan_at_ts(key1.clone()..=key3.clone(), 150); |
3731 | | let between: Vec<_> = scan_iter.collect(); |
3732 | | assert_eq!(between.len(), 1); |
3733 | | assert_eq!(between[0].1, "value1_ts100"); |
3734 | | |
3735 | | // Test scanning at exact timestamp of last entry |
3736 | | let scan_iter = tree.scan_at_ts(key1.clone()..=key3.clone(), 300); |
3737 | | let at_last: Vec<_> = scan_iter.collect(); |
3738 | | assert_eq!(at_last.len(), 3); |
3739 | | |
3740 | | // Test scanning after all entries exist |
3741 | | let scan_iter = tree.scan_at_ts(key1.clone()..=key3.clone(), 400); |
3742 | | let after_all: Vec<_> = scan_iter.collect(); |
3743 | | assert_eq!(after_all.len(), 3); |
3744 | | |
3745 | | // Test backward iteration at different timestamps |
3746 | | let scan_iter = tree.scan_at_ts(key1.clone()..=key3.clone(), 150); |
3747 | | let backward_between: Vec<_> = scan_iter.rev().collect(); |
3748 | | assert_eq!(backward_between.len(), 1); |
3749 | | assert_eq!(backward_between[0].1, "value1_ts100"); |
3750 | | } |
3751 | | |
3752 | | #[test] |
3753 | | fn test_scan_at_ts_range_boundaries_double_ended() { |
3754 | | let mut tree: Tree<FixedSizeKey<16>, String> = Tree::new(); |
3755 | | let keys: Vec<FixedSizeKey<16>> = (1..=5).map(|i| (i as u16).into()).collect(); |
3756 | | |
3757 | | // Insert keys |
3758 | | for (i, key) in keys.iter().enumerate() { |
3759 | | tree.insert(key, format!("value_{}", i + 1), 1, 100) |
3760 | | .unwrap(); |
3761 | | } |
3762 | | |
3763 | | let test_cases = vec![ |
3764 | | // Empty range (no keys in range) |
3765 | | (6u16, 7u16, 0), |
3766 | | // Single element range |
3767 | | (3u16, 3u16, 1), |
3768 | | // Full range |
3769 | | (1u16, 5u16, 5), |
3770 | | // Partial range at start |
3771 | | (1u16, 3u16, 3), |
3772 | | // Partial range at end |
3773 | | (3u16, 5u16, 3), |
3774 | | // Range with only one boundary included |
3775 | | (2u16, 4u16, 3), |
3776 | | ]; |
3777 | | |
3778 | | for (start, end, expected_count) in test_cases { |
3779 | | let start_key: FixedSizeKey<16> = start.into(); |
3780 | | let end_key: FixedSizeKey<16> = end.into(); |
3781 | | |
3782 | | // Test forward iteration |
3783 | | let scan_iter = tree.scan_at_ts(start_key.clone()..=end_key.clone(), 150); |
3784 | | let forward: Vec<_> = scan_iter.collect(); |
3785 | | |
3786 | | // Test backward iteration |
3787 | | let scan_iter = tree.scan_at_ts(start_key.clone()..=end_key.clone(), 150); |
3788 | | let backward: Vec<_> = scan_iter.rev().collect(); |
3789 | | |
3790 | | assert_eq!( |
3791 | | forward.len(), |
3792 | | expected_count, |
3793 | | "Forward iteration failed for range {}..={}", |
3794 | | start, |
3795 | | end |
3796 | | ); |
3797 | | assert_eq!( |
3798 | | backward.len(), |
3799 | | expected_count, |
3800 | | "Backward iteration failed for range {}..={}", |
3801 | | start, |
3802 | | end |
3803 | | ); |
3804 | | |
3805 | | // Verify they are exact reverses |
3806 | | let mut forward_reversed = forward.clone(); |
3807 | | forward_reversed.reverse(); |
3808 | | assert_eq!( |
3809 | | backward, forward_reversed, |
3810 | | "Forward and backward results don't match for range {}..={}", |
3811 | | start, end |
3812 | | ); |
3813 | | } |
3814 | | } |
3815 | | |
3816 | | #[test] |
3817 | | fn test_scan_at_ts_large_dataset_double_ended() { |
3818 | | let mut tree: Tree<FixedSizeKey<16>, String> = Tree::new(); |
3819 | | let total_items = 1000u16; |
3820 | | |
3821 | | // Insert many keys with different timestamps |
3822 | | for i in 1..=total_items { |
3823 | | let key: FixedSizeKey<16> = i.into(); |
3824 | | let timestamp = (i * 10) as u64; |
3825 | | tree.insert(&key, format!("value_{}", i), 1, timestamp) |
3826 | | .unwrap(); |
3827 | | } |
3828 | | |
3829 | | // Test with a subset range |
3830 | | let start_key: FixedSizeKey<16> = 250u16.into(); |
3831 | | let end_key: FixedSizeKey<16> = 750u16.into(); |
3832 | | let query_timestamp = 5000u64; // Should include keys 1-500 |
3833 | | |
3834 | | let scan_iter = tree.scan_at_ts(start_key.clone()..=end_key.clone(), query_timestamp); |
3835 | | let forward: Vec<_> = scan_iter.collect(); |
3836 | | |
3837 | | let scan_iter = tree.scan_at_ts(start_key.clone()..=end_key.clone(), query_timestamp); |
3838 | | let backward: Vec<_> = scan_iter.rev().collect(); |
3839 | | |
3840 | | // Should get keys 250-500 (251 keys total) |
3841 | | let expected_count = 251; |
3842 | | assert_eq!(forward.len(), expected_count); |
3843 | | assert_eq!(backward.len(), expected_count); |
3844 | | |
3845 | | // Verify they are exact reverses |
3846 | | let mut forward_reversed = forward.clone(); |
3847 | | forward_reversed.reverse(); |
3848 | | assert_eq!(backward, forward_reversed); |
3849 | | |
3850 | | // Verify all results are within the expected range |
3851 | | for (key_slice, _, _, _) in &forward { |
3852 | | let key_value = u16::from_be_bytes([key_slice[0], key_slice[1]]); |
3853 | | assert!((250..=500).contains(&key_value)); |
3854 | | } |
3855 | | |
3856 | | // Test with different timestamp ranges |
3857 | | let early_timestamp = 1000u64; // Should include keys 1-100 |
3858 | | let scan_iter = tree.scan_at_ts(start_key.clone()..=end_key.clone(), early_timestamp); |
3859 | | let early_results: Vec<_> = scan_iter.collect(); |
3860 | | assert_eq!(early_results.len(), 0); // No keys in range 250-750 have timestamp <= 1000 |
3861 | | |
3862 | | let late_timestamp = 10000u64; // Should include all keys in range |
3863 | | let scan_iter = tree.scan_at_ts(start_key..=end_key, late_timestamp); |
3864 | | let late_results: Vec<_> = scan_iter.collect(); |
3865 | | assert_eq!(late_results.len(), 501); // All keys 250-750 inclusive |
3866 | | } |
3867 | | } |