Show More
@@ -13,7 +13,8 b'' | |||
|
13 | 13 | //! is used in a more abstract context. |
|
14 | 14 | |
|
15 | 15 | use super::{ |
|
16 |
Node, NodeError, NodePrefix, NodePrefixRef, Revision, |
|
|
16 | node::NULL_NODE, Node, NodeError, NodePrefix, NodePrefixRef, Revision, | |
|
17 | RevlogIndex, NULL_REVISION, | |
|
17 | 18 | }; |
|
18 | 19 | |
|
19 | 20 | use std::fmt; |
@@ -270,6 +271,31 b' fn has_prefix_or_none(' | |||
|
270 | 271 | }) |
|
271 | 272 | } |
|
272 | 273 | |
|
274 | /// validate that the candidate's node starts indeed with given prefix, | |
|
275 | /// and treat ambiguities related to `NULL_REVISION`. | |
|
276 | /// | |
|
277 | /// From the data in the NodeTree, one can only conclude that some | |
|
278 | /// revision is the only one for a *subprefix* of the one being looked up. | |
|
279 | fn validate_candidate( | |
|
280 | idx: &impl RevlogIndex, | |
|
281 | prefix: NodePrefixRef, | |
|
282 | rev: Option<Revision>, | |
|
283 | ) -> Result<Option<Revision>, NodeMapError> { | |
|
284 | if prefix.is_prefix_of(&NULL_NODE) { | |
|
285 | // NULL_REVISION always matches a prefix made only of zeros | |
|
286 | // and any other *valid* result is an ambiguity | |
|
287 | match rev { | |
|
288 | None => Ok(Some(NULL_REVISION)), | |
|
289 | Some(r) => match has_prefix_or_none(idx, prefix, r)? { | |
|
290 | None => Ok(Some(NULL_REVISION)), | |
|
291 | _ => Err(NodeMapError::MultipleResults), | |
|
292 | }, | |
|
293 | } | |
|
294 | } else { | |
|
295 | rev.map_or(Ok(None), |r| has_prefix_or_none(idx, prefix, r)) | |
|
296 | } | |
|
297 | } | |
|
298 | ||
|
273 | 299 | impl NodeTree { |
|
274 | 300 | /// Initiate a NodeTree from an immutable slice-like of `Block` |
|
275 | 301 | /// |
@@ -361,8 +387,6 b' impl NodeTree {' | |||
|
361 | 387 | } |
|
362 | 388 | |
|
363 | 389 | /// Main working method for `NodeTree` searches |
|
364 | /// | |
|
365 | /// This partial implementation lacks special cases for NULL_REVISION | |
|
366 | 390 | fn lookup<'p>( |
|
367 | 391 | &self, |
|
368 | 392 | prefix: NodePrefixRef<'p>, |
@@ -613,9 +637,7 b' impl NodeMap for NodeTree {' | |||
|
613 | 637 | idx: &impl RevlogIndex, |
|
614 | 638 | prefix: NodePrefixRef<'a>, |
|
615 | 639 | ) -> Result<Option<Revision>, NodeMapError> { |
|
616 | self.lookup(prefix.clone()).and_then(|opt| { | |
|
617 | opt.map_or(Ok(None), |rev| has_prefix_or_none(idx, prefix, rev)) | |
|
618 | }) | |
|
640 | validate_candidate(idx, prefix.clone(), self.lookup(prefix)?) | |
|
619 | 641 | } |
|
620 | 642 | } |
|
621 | 643 | |
@@ -748,8 +770,9 b' mod tests {' | |||
|
748 | 770 | |
|
749 | 771 | assert_eq!(nt.find_hex(&idx, "0"), Err(MultipleResults)); |
|
750 | 772 | assert_eq!(nt.find_hex(&idx, "01"), Ok(Some(9))); |
|
751 |
assert_eq!(nt.find_hex(&idx, "00"), |
|
|
773 | assert_eq!(nt.find_hex(&idx, "00"), Err(MultipleResults)); | |
|
752 | 774 | assert_eq!(nt.find_hex(&idx, "00a"), Ok(Some(0))); |
|
775 | assert_eq!(nt.find_hex(&idx, "000"), Ok(Some(NULL_REVISION))); | |
|
753 | 776 | } |
|
754 | 777 | |
|
755 | 778 | #[test] |
@@ -768,7 +791,8 b' mod tests {' | |||
|
768 | 791 | }; |
|
769 | 792 | assert_eq!(nt.find_hex(&idx, "10")?, Some(1)); |
|
770 | 793 | assert_eq!(nt.find_hex(&idx, "c")?, Some(2)); |
|
771 |
assert_eq!(nt.find_hex(&idx, "00") |
|
|
794 | assert_eq!(nt.find_hex(&idx, "00"), Err(MultipleResults)); | |
|
795 | assert_eq!(nt.find_hex(&idx, "000")?, Some(NULL_REVISION)); | |
|
772 | 796 | assert_eq!(nt.find_hex(&idx, "01")?, Some(9)); |
|
773 | 797 | Ok(()) |
|
774 | 798 | } |
General Comments 0
You need to be logged in to leave comments.
Login now