23 use std::ops::Deref; |
23 use std::ops::Deref; |
24 use std::ops::Index; |
24 use std::ops::Index; |
25 |
25 |
26 #[derive(Debug, PartialEq)] |
26 #[derive(Debug, PartialEq)] |
27 pub enum NodeMapError { |
27 pub enum NodeMapError { |
|
28 /// A `NodePrefix` matches several [`Revision`]s. |
28 MultipleResults, |
29 MultipleResults, |
29 /// A `Revision` stored in the nodemap could not be found in the index |
30 /// A `Revision` stored in the nodemap could not be found in the index |
30 RevisionNotInIndex(Revision), |
31 RevisionNotInIndex(Revision), |
31 } |
32 } |
32 |
33 |
82 /// |
83 /// |
83 /// From a binary node prefix, if it is matched in the node map, this |
84 /// From a binary node prefix, if it is matched in the node map, this |
84 /// returns the number of hexadecimal digits that would had sufficed |
85 /// returns the number of hexadecimal digits that would had sufficed |
85 /// to find the revision uniquely. |
86 /// to find the revision uniquely. |
86 /// |
87 /// |
87 /// Returns `None` if no `Revision` could be found for the prefix. |
88 /// Returns `None` if no [`Revision`] could be found for the prefix. |
88 /// |
89 /// |
89 /// If several Revisions match the given prefix, a |
90 /// If several Revisions match the given prefix, a |
90 /// [MultipleResults](NodeMapError) error is returned. |
91 /// [MultipleResults](NodeMapError) error is returned. |
91 fn unique_prefix_len_bin( |
92 fn unique_prefix_len_bin( |
92 &self, |
93 &self, |
165 /// ith potential edge from the block, representing the ith hexadecimal digit |
166 /// ith potential edge from the block, representing the ith hexadecimal digit |
166 /// (nybble) `i` is either: |
167 /// (nybble) `i` is either: |
167 /// |
168 /// |
168 /// - absent (value -1) |
169 /// - absent (value -1) |
169 /// - another `Block` in the same indexable container (value ≥ 0) |
170 /// - another `Block` in the same indexable container (value ≥ 0) |
170 /// - a `Revision` leaf (value ≤ -2) |
171 /// - a [`Revision`] leaf (value ≤ -2) |
171 /// |
172 /// |
172 /// Endianness has to be fixed for consistency on shared storage across |
173 /// Endianness has to be fixed for consistency on shared storage across |
173 /// different architectures. |
174 /// different architectures. |
174 /// |
175 /// |
175 /// A key difference with the C `nodetree` is that we need to be |
176 /// A key difference with the C `nodetree` is that we need to be |
176 /// able to represent the [`Block`] at index 0, hence -1 is the empty marker |
177 /// able to represent the [`Block`] at index 0, hence -1 is the empty marker |
177 /// rather than 0 and the `Revision` range upper limit of -2 instead of -1. |
178 /// rather than 0 and the [`Revision`] range upper limit of -2 instead of -1. |
178 /// |
179 /// |
179 /// Another related difference is that `NULL_REVISION` (-1) is not |
180 /// Another related difference is that `NULL_REVISION` (-1) is not |
180 /// represented at all, because we want an immutable empty nodetree |
181 /// represented at all, because we want an immutable empty nodetree |
181 /// to be valid. |
182 /// to be valid. |
182 |
183 |
321 amount: usize, |
322 amount: usize, |
322 ) -> Self { |
323 ) -> Self { |
323 NodeTree::new(Box::new(NodeTreeBytes::new(bytes, amount))) |
324 NodeTree::new(Box::new(NodeTreeBytes::new(bytes, amount))) |
324 } |
325 } |
325 |
326 |
326 /// Retrieve added `Block` and the original immutable data |
327 /// Retrieve added [`Block`]s and the original immutable data |
327 pub fn into_readonly_and_added( |
328 pub fn into_readonly_and_added( |
328 self, |
329 self, |
329 ) -> (Box<dyn Deref<Target = [Block]> + Send>, Vec<Block>) { |
330 ) -> (Box<dyn Deref<Target = [Block]> + Send>, Vec<Block>) { |
330 let mut vec = self.growable; |
331 let mut vec = self.growable; |
331 let readonly = self.readonly; |
332 let readonly = self.readonly; |
333 vec.push(self.root); |
334 vec.push(self.root); |
334 } |
335 } |
335 (readonly, vec) |
336 (readonly, vec) |
336 } |
337 } |
337 |
338 |
338 /// Retrieve added `Blocks` as bytes, ready to be written to persistent |
339 /// Retrieve added [`Block]s as bytes, ready to be written to persistent |
339 /// storage |
340 /// storage |
340 pub fn into_readonly_and_added_bytes( |
341 pub fn into_readonly_and_added_bytes( |
341 self, |
342 self, |
342 ) -> (Box<dyn Deref<Target = [Block]> + Send>, Vec<u8>) { |
343 ) -> (Box<dyn Deref<Target = [Block]> + Send>, Vec<u8>) { |
343 let (readonly, vec) = self.into_readonly_and_added(); |
344 let (readonly, vec) = self.into_readonly_and_added(); |
379 |
380 |
380 /// Main working method for `NodeTree` searches |
381 /// Main working method for `NodeTree` searches |
381 /// |
382 /// |
382 /// The first returned value is the result of analysing `NodeTree` data |
383 /// The first returned value is the result of analysing `NodeTree` data |
383 /// *alone*: whereas `None` guarantees that the given prefix is absent |
384 /// *alone*: whereas `None` guarantees that the given prefix is absent |
384 /// from the `NodeTree` data (but still could match `NULL_NODE`), with |
385 /// from the [`NodeTree`] data (but still could match [`NULL_NODE`]), with |
385 /// `Some(rev)`, it is to be understood that `rev` is the unique `Revision` |
386 /// `Some(rev)`, it is to be understood that `rev` is the unique |
386 /// that could match the prefix. Actually, all that can be inferred from |
387 /// [`Revision`] that could match the prefix. Actually, all that can |
|
388 /// be inferred from |
387 /// the `NodeTree` data is that `rev` is the revision with the longest |
389 /// the `NodeTree` data is that `rev` is the revision with the longest |
388 /// common node prefix with the given prefix. |
390 /// common node prefix with the given prefix. |
389 /// |
391 /// |
390 /// The second returned value is the size of the smallest subprefix |
392 /// The second returned value is the size of the smallest subprefix |
391 /// of `prefix` that would give the same result, i.e. not the |
393 /// of `prefix` that would give the same result, i.e. not the |
392 /// `MultipleResults` error variant (again, using only the data of the |
394 /// [MultipleResults](NodeMapError) error variant (again, using only the |
393 /// `NodeTree`). |
395 /// data of the [`NodeTree`]). |
394 fn lookup( |
396 fn lookup( |
395 &self, |
397 &self, |
396 prefix: NodePrefix, |
398 prefix: NodePrefix, |
397 ) -> Result<(Option<Revision>, usize), NodeMapError> { |
399 ) -> Result<(Option<Revision>, usize), NodeMapError> { |
398 for (i, visit_item) in self.visit(prefix).enumerate() { |
400 for (i, visit_item) in self.visit(prefix).enumerate() { |