changeset 48194:1000db4a71f1

dirstate-v2: Store unsigned integers inside DirstateEntry The negative marker values are not used anymore. Differential Revision: https://phab.mercurial-scm.org/D11634
author Simon Sapin <simon.sapin@octobus.net>
date Mon, 11 Oct 2021 18:37:21 +0200
parents 320de901896a
children 4d5a13253d34
files rust/hg-core/src/dirstate/entry.rs rust/hg-core/src/dirstate_tree/on_disk.rs rust/hg-cpython/src/dirstate/item.rs
diffstat 3 files changed, 36 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/rust/hg-core/src/dirstate/entry.rs	Tue Oct 12 16:38:13 2021 +0200
+++ b/rust/hg-core/src/dirstate/entry.rs	Mon Oct 11 18:37:21 2021 +0200
@@ -18,8 +18,8 @@
 #[derive(Debug, PartialEq, Copy, Clone)]
 pub struct DirstateEntry {
     pub(crate) flags: Flags,
-    mode_size: Option<(i32, i32)>,
-    mtime: Option<i32>,
+    mode_size: Option<(u32, u32)>,
+    mtime: Option<u32>,
 }
 
 bitflags! {
@@ -153,9 +153,17 @@
         wdir_tracked: bool,
         p1_tracked: bool,
         p2_info: bool,
-        mode_size: Option<(i32, i32)>,
-        mtime: Option<i32>,
+        mode_size: Option<(u32, u32)>,
+        mtime: Option<u32>,
     ) -> Self {
+        if let Some((mode, size)) = mode_size {
+            // TODO: return an error for out of range values?
+            assert!(mode & !RANGE_MASK_31BIT == 0);
+            assert!(size & !RANGE_MASK_31BIT == 0);
+        }
+        if let Some(mtime) = mtime {
+            assert!(mtime & !RANGE_MASK_31BIT == 0);
+        }
         let mut flags = Flags::empty();
         flags.set(Flags::WDIR_TRACKED, wdir_tracked);
         flags.set(Flags::P1_TRACKED, p1_tracked);
@@ -189,12 +197,19 @@
                         mtime: None,
                     }
                 } else if mtime == MTIME_UNSET {
+                    // TODO: return an error for negative values?
+                    let mode = u32::try_from(mode).unwrap();
+                    let size = u32::try_from(size).unwrap();
                     Self {
                         flags: Flags::WDIR_TRACKED | Flags::P1_TRACKED,
                         mode_size: Some((mode, size)),
                         mtime: None,
                     }
                 } else {
+                    // TODO: return an error for negative values?
+                    let mode = u32::try_from(mode).unwrap();
+                    let size = u32::try_from(size).unwrap();
+                    let mtime = u32::try_from(mtime).unwrap();
                     Self {
                         flags: Flags::WDIR_TRACKED | Flags::P1_TRACKED,
                         mode_size: Some((mode, size)),
@@ -282,7 +297,7 @@
     /// Returns `(wdir_tracked, p1_tracked, p2_info, mode_size, mtime)`
     pub(crate) fn v2_data(
         &self,
-    ) -> (bool, bool, bool, Option<(i32, i32)>, Option<i32>) {
+    ) -> (bool, bool, bool, Option<(u32, u32)>, Option<u32>) {
         if !self.any_tracked() {
             // TODO: return an Option instead?
             panic!("Accessing v1_state of an untracked DirstateEntry")
@@ -316,7 +331,7 @@
 
     fn v1_mode(&self) -> i32 {
         if let Some((mode, _size)) = self.mode_size {
-            mode
+            i32::try_from(mode).unwrap()
         } else {
             0
         }
@@ -338,7 +353,7 @@
         } else if self.added() {
             SIZE_NON_NORMAL
         } else if let Some((_mode, size)) = self.mode_size {
-            size
+            i32::try_from(size).unwrap()
         } else {
             SIZE_NON_NORMAL
         }
@@ -355,8 +370,10 @@
             MTIME_UNSET
         } else if !self.flags.contains(Flags::P1_TRACKED) {
             MTIME_UNSET
+        } else if let Some(mtime) = self.mtime {
+            i32::try_from(mtime).unwrap()
         } else {
-            self.mtime.unwrap_or(MTIME_UNSET)
+            MTIME_UNSET
         }
     }
 
@@ -392,7 +409,9 @@
         self.mtime = None
     }
 
-    pub fn set_clean(&mut self, mode: i32, size: i32, mtime: i32) {
+    pub fn set_clean(&mut self, mode: u32, size: u32, mtime: u32) {
+        let size = size & RANGE_MASK_31BIT;
+        let mtime = mtime & RANGE_MASK_31BIT;
         self.flags.insert(Flags::WDIR_TRACKED | Flags::P1_TRACKED);
         self.mode_size = Some((mode, size));
         self.mtime = Some(mtime);
--- a/rust/hg-core/src/dirstate_tree/on_disk.rs	Tue Oct 12 16:38:13 2021 +0200
+++ b/rust/hg-core/src/dirstate_tree/on_disk.rs	Mon Oct 11 18:37:21 2021 +0200
@@ -11,7 +11,7 @@
 use crate::DirstateError;
 use crate::DirstateParents;
 use bitflags::bitflags;
-use bytes_cast::unaligned::{I32Be, U16Be, U32Be};
+use bytes_cast::unaligned::{U16Be, U32Be};
 use bytes_cast::BytesCast;
 use format_bytes::format_bytes;
 use std::borrow::Cow;
@@ -113,9 +113,9 @@
 #[derive(BytesCast, Copy, Clone, Debug)]
 #[repr(C)]
 struct Entry {
-    mode: I32Be,
-    size: I32Be,
-    mtime: I32Be,
+    mode: U32Be,
+    size: U32Be,
+    mtime: U32Be,
 }
 
 /// Duration since the Unix epoch
--- a/rust/hg-cpython/src/dirstate/item.rs	Tue Oct 12 16:38:13 2021 +0200
+++ b/rust/hg-cpython/src/dirstate/item.rs	Mon Oct 11 18:37:21 2021 +0200
@@ -21,7 +21,7 @@
         p2_info: bool = false,
         has_meaningful_data: bool = true,
         has_meaningful_mtime: bool = true,
-        parentfiledata: Option<(i32, i32, i32)> = None,
+        parentfiledata: Option<(u32, u32, u32)> = None,
 
     ) -> PyResult<DirstateItem> {
         let mut mode_size_opt = None;
@@ -145,9 +145,9 @@
 
     def set_clean(
         &self,
-        mode: i32,
-        size: i32,
-        mtime: i32,
+        mode: u32,
+        size: u32,
+        mtime: u32,
     ) -> PyResult<PyNone> {
         self.update(py, |entry| entry.set_clean(mode, size, mtime));
         Ok(PyNone)