diff rust/hg-core/src/revlog/revlog.rs @ 48575:e91aa800ae5b

rhg: desambiguate status without decompressing filelog if possible When status is unsure based on `stat()` and the dirstate if a file is clean or modified, we need to compare it against the filelog. This comparison can skip looking at contents if the lengths differ. This changeset optimize this further to deduce what we can about the length if the filelog without decompressing it or resolving deltas. Differential Revision: https://phab.mercurial-scm.org/D11965
author Simon Sapin <simon.sapin@octobus.net>
date Fri, 07 Jan 2022 14:40:21 +0100
parents faa243f345cc
children cc92ad0e8185 5d205e476057
line wrap: on
line diff
--- a/rust/hg-core/src/revlog/revlog.rs	Thu Jan 06 12:46:10 2022 +0100
+++ b/rust/hg-core/src/revlog/revlog.rs	Fri Jan 07 14:40:21 2022 +0100
@@ -20,6 +20,18 @@
 use crate::revlog::Revision;
 use crate::{Node, NULL_REVISION};
 
+const REVISION_FLAG_CENSORED: u16 = 1 << 15;
+const REVISION_FLAG_ELLIPSIS: u16 = 1 << 14;
+const REVISION_FLAG_EXTSTORED: u16 = 1 << 13;
+const REVISION_FLAG_HASCOPIESINFO: u16 = 1 << 12;
+
+// Keep this in sync with REVIDX_KNOWN_FLAGS in
+// mercurial/revlogutils/flagutil.py
+const REVIDX_KNOWN_FLAGS: u16 = REVISION_FLAG_CENSORED
+    | REVISION_FLAG_ELLIPSIS
+    | REVISION_FLAG_EXTSTORED
+    | REVISION_FLAG_HASCOPIESINFO;
+
 #[derive(derive_more::From)]
 pub enum RevlogError {
     InvalidRevision,
@@ -282,6 +294,7 @@
             },
             p1: index_entry.p1(),
             p2: index_entry.p2(),
+            flags: index_entry.flags(),
             hash: *index_entry.hash(),
         };
         Ok(entry)
@@ -309,6 +322,7 @@
     base_rev_or_base_of_delta_chain: Option<Revision>,
     p1: Revision,
     p2: Revision,
+    flags: u16,
     hash: Node,
 }
 
@@ -321,6 +335,20 @@
         u32::try_from(self.uncompressed_len).ok()
     }
 
+    pub fn has_p1(&self) -> bool {
+        self.p1 != NULL_REVISION
+    }
+
+    pub fn is_cencored(&self) -> bool {
+        (self.flags & REVISION_FLAG_CENSORED) != 0
+    }
+
+    pub fn has_length_affecting_flag_processor(&self) -> bool {
+        // Relevant Python code: revlog.size()
+        // note: ELLIPSIS is known to not change the content
+        (self.flags & (REVIDX_KNOWN_FLAGS ^ REVISION_FLAG_ELLIPSIS)) != 0
+    }
+
     /// The data for this entry, after resolving deltas if any.
     pub fn data(&self) -> Result<Cow<'a, [u8]>, HgError> {
         let mut entry = self.clone();