##// END OF EJS Templates
rust-nodemap: special case for prefixes of NULL_NODE...
Georges Racinet -
r44871:00d251d3 default
parent child Browse files
Show More
@@ -13,7 +13,8 b''
13 //! is used in a more abstract context.
13 //! is used in a more abstract context.
14
14
15 use super::{
15 use super::{
16 Node, NodeError, NodePrefix, NodePrefixRef, Revision, RevlogIndex,
16 node::NULL_NODE, Node, NodeError, NodePrefix, NodePrefixRef, Revision,
17 RevlogIndex, NULL_REVISION,
17 };
18 };
18
19
19 use std::fmt;
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 impl NodeTree {
299 impl NodeTree {
274 /// Initiate a NodeTree from an immutable slice-like of `Block`
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 /// Main working method for `NodeTree` searches
389 /// Main working method for `NodeTree` searches
364 ///
365 /// This partial implementation lacks special cases for NULL_REVISION
366 fn lookup<'p>(
390 fn lookup<'p>(
367 &self,
391 &self,
368 prefix: NodePrefixRef<'p>,
392 prefix: NodePrefixRef<'p>,
@@ -613,9 +637,7 b' impl NodeMap for NodeTree {'
613 idx: &impl RevlogIndex,
637 idx: &impl RevlogIndex,
614 prefix: NodePrefixRef<'a>,
638 prefix: NodePrefixRef<'a>,
615 ) -> Result<Option<Revision>, NodeMapError> {
639 ) -> Result<Option<Revision>, NodeMapError> {
616 self.lookup(prefix.clone()).and_then(|opt| {
640 validate_candidate(idx, prefix.clone(), self.lookup(prefix)?)
617 opt.map_or(Ok(None), |rev| has_prefix_or_none(idx, prefix, rev))
618 })
619 }
641 }
620 }
642 }
621
643
@@ -748,8 +770,9 b' mod tests {'
748
770
749 assert_eq!(nt.find_hex(&idx, "0"), Err(MultipleResults));
771 assert_eq!(nt.find_hex(&idx, "0"), Err(MultipleResults));
750 assert_eq!(nt.find_hex(&idx, "01"), Ok(Some(9)));
772 assert_eq!(nt.find_hex(&idx, "01"), Ok(Some(9)));
751 assert_eq!(nt.find_hex(&idx, "00"), Ok(Some(0)));
773 assert_eq!(nt.find_hex(&idx, "00"), Err(MultipleResults));
752 assert_eq!(nt.find_hex(&idx, "00a"), Ok(Some(0)));
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 #[test]
778 #[test]
@@ -768,7 +791,8 b' mod tests {'
768 };
791 };
769 assert_eq!(nt.find_hex(&idx, "10")?, Some(1));
792 assert_eq!(nt.find_hex(&idx, "10")?, Some(1));
770 assert_eq!(nt.find_hex(&idx, "c")?, Some(2));
793 assert_eq!(nt.find_hex(&idx, "c")?, Some(2));
771 assert_eq!(nt.find_hex(&idx, "00")?, Some(0));
794 assert_eq!(nt.find_hex(&idx, "00"), Err(MultipleResults));
795 assert_eq!(nt.find_hex(&idx, "000")?, Some(NULL_REVISION));
772 assert_eq!(nt.find_hex(&idx, "01")?, Some(9));
796 assert_eq!(nt.find_hex(&idx, "01")?, Some(9));
773 Ok(())
797 Ok(())
774 }
798 }
General Comments 0
You need to be logged in to leave comments. Login now