rust-revlog: move non-persistent-nodemap rev lookup to the index
It only uses index features and does not need to be on the revlog. A later
patch will make use of this function from a different context.
--- a/rust/hg-core/src/revlog/index.rs Mon Jul 29 20:39:34 2024 +0200
+++ b/rust/hg-core/src/revlog/index.rs Wed Jul 31 15:02:55 2024 +0200
@@ -7,7 +7,7 @@
use byteorder::{BigEndian, ByteOrder};
use bytes_cast::{unaligned, BytesCast};
-use super::REVIDX_KNOWN_FLAGS;
+use super::{NodePrefix, REVIDX_KNOWN_FLAGS};
use crate::errors::HgError;
use crate::node::{NODE_BYTES_LENGTH, NULL_NODE, STORED_NODE_ID_BYTES};
use crate::revlog::node::Node;
@@ -417,6 +417,45 @@
}
}
+ /// Same as `rev_from_node`, without using a persistent nodemap
+ ///
+ /// This is used as fallback when a persistent nodemap is not present.
+ /// This happens when the persistent-nodemap experimental feature is not
+ /// enabled, or for small revlogs.
+ pub fn rev_from_node_no_persistent_nodemap(
+ &self,
+ node: NodePrefix,
+ ) -> Result<Revision, RevlogError> {
+ // Linear scan of the revlog
+ // TODO: consider building a non-persistent nodemap in memory to
+ // optimize these cases.
+ let mut found_by_prefix = None;
+ for rev in (-1..self.len() as BaseRevision).rev() {
+ let rev = Revision(rev as BaseRevision);
+ let candidate_node = if rev == Revision(-1) {
+ NULL_NODE
+ } else {
+ let index_entry = self.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(&candidate_node) {
+ if found_by_prefix.is_some() {
+ return Err(RevlogError::AmbiguousPrefix);
+ }
+ found_by_prefix = Some(rev)
+ }
+ }
+ found_by_prefix
+ .ok_or_else(|| RevlogError::InvalidRevision(format!("{:x}", node)))
+ }
+
pub fn get_offsets(&self) -> RwLockReadGuard<Option<Vec<usize>>> {
assert!(self.is_inline());
{
--- a/rust/hg-core/src/revlog/mod.rs Mon Jul 29 20:39:34 2024 +0200
+++ b/rust/hg-core/src/revlog/mod.rs Wed Jul 31 15:02:55 2024 +0200
@@ -363,50 +363,10 @@
.find_bin(self.index(), node)?
.ok_or(RevlogError::InvalidRevision(format!("{:x}", node)))
} else {
- self.rev_from_node_no_persistent_nodemap(node)
+ self.index().rev_from_node_no_persistent_nodemap(node)
}
}
- /// Same as `rev_from_node`, without using a persistent nodemap
- ///
- /// This is used as fallback when a persistent nodemap is not present.
- /// This happens when the persistent-nodemap experimental feature is not
- /// enabled, or for small revlogs.
- fn rev_from_node_no_persistent_nodemap(
- &self,
- node: NodePrefix,
- ) -> Result<Revision, RevlogError> {
- // Linear scan of the revlog
- // TODO: consider building a non-persistent nodemap in memory to
- // optimize these cases.
- let mut found_by_prefix = None;
- for rev in (-1..self.len() as BaseRevision).rev() {
- let rev = Revision(rev as BaseRevision);
- 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(&candidate_node) {
- if found_by_prefix.is_some() {
- return Err(RevlogError::AmbiguousPrefix);
- }
- found_by_prefix = Some(rev)
- }
- }
- found_by_prefix
- .ok_or(RevlogError::InvalidRevision(format!("{:x}", node)))
- }
-
/// Returns whether the given revision exists in this revlog.
pub fn has_rev(&self, rev: UncheckedRevision) -> bool {
self.index().check_revision(rev).is_some()