rust/hg-core/src/revlog/mod.rs
changeset 52177 1da6995835b4
parent 52171 7be39c5110c9
child 52181 3d797007905d
equal deleted inserted replaced
52176:72bc29f01570 52177:1da6995835b4
   361         if let Some(nodemap) = &self.nodemap {
   361         if let Some(nodemap) = &self.nodemap {
   362             nodemap
   362             nodemap
   363                 .find_bin(self.index(), node)?
   363                 .find_bin(self.index(), node)?
   364                 .ok_or(RevlogError::InvalidRevision(format!("{:x}", node)))
   364                 .ok_or(RevlogError::InvalidRevision(format!("{:x}", node)))
   365         } else {
   365         } else {
   366             self.rev_from_node_no_persistent_nodemap(node)
   366             self.index().rev_from_node_no_persistent_nodemap(node)
   367         }
   367         }
   368     }
       
   369 
       
   370     /// Same as `rev_from_node`, without using a persistent nodemap
       
   371     ///
       
   372     /// This is used as fallback when a persistent nodemap is not present.
       
   373     /// This happens when the persistent-nodemap experimental feature is not
       
   374     /// enabled, or for small revlogs.
       
   375     fn rev_from_node_no_persistent_nodemap(
       
   376         &self,
       
   377         node: NodePrefix,
       
   378     ) -> Result<Revision, RevlogError> {
       
   379         // Linear scan of the revlog
       
   380         // TODO: consider building a non-persistent nodemap in memory to
       
   381         // optimize these cases.
       
   382         let mut found_by_prefix = None;
       
   383         for rev in (-1..self.len() as BaseRevision).rev() {
       
   384             let rev = Revision(rev as BaseRevision);
       
   385             let candidate_node = if rev == Revision(-1) {
       
   386                 NULL_NODE
       
   387             } else {
       
   388                 let index_entry =
       
   389                     self.index().get_entry(rev).ok_or_else(|| {
       
   390                         HgError::corrupted(
       
   391                             "revlog references a revision not in the index",
       
   392                         )
       
   393                     })?;
       
   394                 *index_entry.hash()
       
   395             };
       
   396             if node == candidate_node {
       
   397                 return Ok(rev);
       
   398             }
       
   399             if node.is_prefix_of(&candidate_node) {
       
   400                 if found_by_prefix.is_some() {
       
   401                     return Err(RevlogError::AmbiguousPrefix);
       
   402                 }
       
   403                 found_by_prefix = Some(rev)
       
   404             }
       
   405         }
       
   406         found_by_prefix
       
   407             .ok_or(RevlogError::InvalidRevision(format!("{:x}", node)))
       
   408     }
   368     }
   409 
   369 
   410     /// Returns whether the given revision exists in this revlog.
   370     /// Returns whether the given revision exists in this revlog.
   411     pub fn has_rev(&self, rev: UncheckedRevision) -> bool {
   371     pub fn has_rev(&self, rev: UncheckedRevision) -> bool {
   412         self.index().check_revision(rev).is_some()
   372         self.index().check_revision(rev).is_some()