Mercurial > public > mercurial-scm > hg-stable
diff rust/hg-core/src/revlog/mod.rs @ 50998:12c308c55e53
branching: merge stable into default
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Wed, 11 Oct 2023 02:02:46 +0200 |
parents | 4c5f6e95df84 eccf7dc7c91e |
children | 532e74ad3ff6 |
line wrap: on
line diff
--- a/rust/hg-core/src/revlog/mod.rs Wed Jan 25 15:34:27 2023 +0100 +++ b/rust/hg-core/src/revlog/mod.rs Wed Oct 11 02:02:46 2023 +0200 @@ -236,6 +236,16 @@ data_path: Option<&Path>, use_nodemap: bool, ) -> Result<Self, HgError> { + Self::open_gen(store_vfs, index_path, data_path, use_nodemap, None) + } + + fn open_gen( + store_vfs: &Vfs, + index_path: impl AsRef<Path>, + data_path: Option<&Path>, + use_nodemap: bool, + nodemap_for_test: Option<nodemap::NodeTree>, + ) -> Result<Self, HgError> { let index_path = index_path.as_ref(); let index = { match store_vfs.mmap_open_opt(&index_path)? { @@ -273,6 +283,8 @@ ) }; + let nodemap = nodemap_for_test.or(nodemap); + Ok(Revlog { index, data_bytes, @@ -306,23 +318,13 @@ &self, node: NodePrefix, ) -> Result<Revision, RevlogError> { - let looked_up = if let Some(nodemap) = &self.nodemap { + if let Some(nodemap) = &self.nodemap { nodemap .find_bin(&self.index, node)? .ok_or(RevlogError::InvalidRevision) } else { self.rev_from_node_no_persistent_nodemap(node) - }; - - if node.is_prefix_of(&NULL_NODE) { - return match looked_up { - Ok(_) => Err(RevlogError::AmbiguousPrefix), - Err(RevlogError::InvalidRevision) => Ok(NULL_REVISION), - res => res, - }; - }; - - looked_up + } } /// Same as `rev_from_node`, without using a persistent nodemap @@ -338,17 +340,23 @@ // TODO: consider building a non-persistent nodemap in memory to // optimize these cases. let mut found_by_prefix = None; - for rev in (0..self.len()).rev() { + for rev in (-1..self.len() as BaseRevision).rev() { let rev = Revision(rev as BaseRevision); - let index_entry = self.index.get_entry(rev).ok_or_else(|| { - HgError::corrupted( - "revlog references a revision not in the index", - ) - })?; - if node == *index_entry.hash() { + let candidate_node = if rev == Revision(-1) { + NULL_NODE + } else { + let index_entry = + self.index.get_entry(rev).ok_or_else(|| { + HgError::corrupted( + "revlog references a revision not in the index", + ) + })?; + *index_entry.hash() + }; + if node == candidate_node { return Ok(rev); } - if node.is_prefix_of(index_entry.hash()) { + if node.is_prefix_of(&candidate_node) { if found_by_prefix.is_some() { return Err(RevlogError::AmbiguousPrefix); } @@ -913,7 +921,13 @@ .flatten() .collect_vec(); std::fs::write(temp.path().join("foo.i"), contents).unwrap(); - let revlog = Revlog::open(&vfs, "foo.i", None, false).unwrap(); + + let mut idx = nodemap::tests::TestNtIndex::new(); + idx.insert_node(Revision(0), node0).unwrap(); + idx.insert_node(Revision(1), node1).unwrap(); + + let revlog = + Revlog::open_gen(&vfs, "foo.i", None, true, Some(idx.nt)).unwrap(); // accessing the data shows the corruption revlog.get_entry(0.into()).unwrap().data().unwrap_err();