rust: Add a Timestamp struct instead of abusing Duration
authorSimon Sapin <simon.sapin@octobus.net>
Mon, 12 Apr 2021 14:43:45 +0200
changeset 47101 5d62243c7732
parent 47100 caa3031c9ed5
child 47102 d6c94ca40863
rust: Add a Timestamp struct instead of abusing Duration `SystemTime` would be the standard library type semantically appropriate instead of `Duration`. But since the value is coming from Python as a plain integer and used in dirstate packing code as an integer, let’s make a type that contains a single integer instead of using one with sub-second precision. Differential Revision: https://phab.mercurial-scm.org/D10485
rust/hg-core/src/dirstate/dirstate_map.rs
rust/hg-core/src/dirstate/parsers.rs
rust/hg-core/src/dirstate_tree/dirstate_map.rs
rust/hg-core/src/dirstate_tree/dispatch.rs
rust/hg-core/src/lib.rs
rust/hg-cpython/src/dirstate/dirstate_map.rs
rust/hg-cpython/src/parsers.rs
--- a/rust/hg-core/src/dirstate/dirstate_map.rs	Tue Apr 06 21:07:12 2021 +0200
+++ b/rust/hg-core/src/dirstate/dirstate_map.rs	Mon Apr 12 14:43:45 2021 +0200
@@ -5,6 +5,7 @@
 // This software may be used and distributed according to the terms of the
 // GNU General Public License version 2 or any later version.
 
+use crate::dirstate::parsers::Timestamp;
 use crate::errors::HgError;
 use crate::revlog::node::NULL_NODE;
 use crate::{
@@ -22,7 +23,6 @@
 use std::convert::TryInto;
 use std::iter::FromIterator;
 use std::ops::Deref;
-use std::time::Duration;
 
 pub type FileFoldMap = FastHashMap<HgPathBuf, HgPathBuf>;
 
@@ -389,7 +389,7 @@
     pub fn pack(
         &mut self,
         parents: DirstateParents,
-        now: Duration,
+        now: Timestamp,
     ) -> Result<Vec<u8>, DirstateError> {
         let packed =
             pack_dirstate(&mut self.state_map, &self.copy_map, parents, now)?;
--- a/rust/hg-core/src/dirstate/parsers.rs	Tue Apr 06 21:07:12 2021 +0200
+++ b/rust/hg-core/src/dirstate/parsers.rs	Mon Apr 12 14:43:45 2021 +0200
@@ -13,7 +13,6 @@
 use bytes_cast::BytesCast;
 use micro_timer::timed;
 use std::convert::{TryFrom, TryInto};
-use std::time::Duration;
 
 /// Parents are stored in the dirstate as byte hashes.
 pub const PARENT_SIZE: usize = 20;
@@ -83,15 +82,17 @@
     Ok(parents)
 }
 
-/// `now` is the duration in seconds since the Unix epoch
+/// Seconds since the Unix epoch
+pub struct Timestamp(pub u64);
+
 pub fn pack_dirstate(
     state_map: &mut StateMap,
     copy_map: &CopyMap,
     parents: DirstateParents,
-    now: Duration,
+    now: Timestamp,
 ) -> Result<Vec<u8>, HgError> {
     // TODO move away from i32 before 2038.
-    let now: i32 = now.as_secs().try_into().expect("time overflow");
+    let now: i32 = now.0.try_into().expect("time overflow");
 
     let expected_size: usize = state_map
         .iter()
@@ -171,7 +172,7 @@
             p1: b"12345678910111213141".into(),
             p2: b"00000000000000000000".into(),
         };
-        let now = Duration::new(15000000, 0);
+        let now = Timestamp(15000000);
         let expected = b"1234567891011121314100000000000000000000".to_vec();
 
         assert_eq!(
@@ -202,7 +203,7 @@
             p1: b"12345678910111213141".into(),
             p2: b"00000000000000000000".into(),
         };
-        let now = Duration::new(15000000, 0);
+        let now = Timestamp(15000000);
         let expected = [
             49, 50, 51, 52, 53, 54, 55, 56, 57, 49, 48, 49, 49, 49, 50, 49,
             51, 49, 52, 49, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
@@ -242,7 +243,7 @@
             p1: b"12345678910111213141".into(),
             p2: b"00000000000000000000".into(),
         };
-        let now = Duration::new(15000000, 0);
+        let now = Timestamp(15000000);
         let expected = [
             49, 50, 51, 52, 53, 54, 55, 56, 57, 49, 48, 49, 49, 49, 50, 49,
             51, 49, 52, 49, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
@@ -282,7 +283,7 @@
             p1: b"12345678910111213141".into(),
             p2: b"00000000000000000000".into(),
         };
-        let now = Duration::new(15000000, 0);
+        let now = Timestamp(15000000);
         let result =
             pack_dirstate(&mut state_map, &copymap, parents.clone(), now)
                 .unwrap();
@@ -360,7 +361,7 @@
             p1: b"12345678910111213141".into(),
             p2: b"00000000000000000000".into(),
         };
-        let now = Duration::new(15000000, 0);
+        let now = Timestamp(15000000);
         let result =
             pack_dirstate(&mut state_map, &copymap, parents.clone(), now)
                 .unwrap();
@@ -406,7 +407,7 @@
             p1: b"12345678910111213141".into(),
             p2: b"00000000000000000000".into(),
         };
-        let now = Duration::new(15000000, 0);
+        let now = Timestamp(15000000);
         let result =
             pack_dirstate(&mut state_map, &copymap, parents.clone(), now)
                 .unwrap();
--- a/rust/hg-core/src/dirstate_tree/dirstate_map.rs	Tue Apr 06 21:07:12 2021 +0200
+++ b/rust/hg-core/src/dirstate_tree/dirstate_map.rs	Mon Apr 12 14:43:45 2021 +0200
@@ -1,10 +1,10 @@
 use std::collections::BTreeMap;
 use std::path::PathBuf;
-use std::time::Duration;
 
 use super::path_with_basename::WithBasename;
 use crate::dirstate::parsers::parse_dirstate_entries;
 use crate::dirstate::parsers::parse_dirstate_parents;
+use crate::dirstate::parsers::Timestamp;
 
 use crate::matchers::Matcher;
 use crate::revlog::node::NULL_NODE;
@@ -328,7 +328,7 @@
     fn pack(
         &mut self,
         _parents: DirstateParents,
-        _now: Duration,
+        _now: Timestamp,
     ) -> Result<Vec<u8>, DirstateError> {
         let _ = self.iter_node_data_mut();
         todo!()
--- a/rust/hg-core/src/dirstate_tree/dispatch.rs	Tue Apr 06 21:07:12 2021 +0200
+++ b/rust/hg-core/src/dirstate_tree/dispatch.rs	Mon Apr 12 14:43:45 2021 +0200
@@ -1,6 +1,6 @@
 use std::path::PathBuf;
-use std::time::Duration;
 
+use crate::dirstate::parsers::Timestamp;
 use crate::matchers::Matcher;
 use crate::utils::hg_path::{HgPath, HgPathBuf};
 use crate::CopyMapIter;
@@ -90,7 +90,7 @@
     fn pack(
         &mut self,
         parents: DirstateParents,
-        now: Duration,
+        now: Timestamp,
     ) -> Result<Vec<u8>, DirstateError>;
 
     fn build_file_fold_map(&mut self) -> &FastHashMap<HgPathBuf, HgPathBuf>;
@@ -254,7 +254,7 @@
     fn pack(
         &mut self,
         parents: DirstateParents,
-        now: Duration,
+        now: Timestamp,
     ) -> Result<Vec<u8>, DirstateError> {
         self.pack(parents, now)
     }
--- a/rust/hg-core/src/lib.rs	Tue Apr 06 21:07:12 2021 +0200
+++ b/rust/hg-core/src/lib.rs	Mon Apr 12 14:43:45 2021 +0200
@@ -8,7 +8,7 @@
 pub mod dagops;
 pub mod errors;
 pub use ancestors::{AncestorsIterator, LazyAncestors, MissingAncestors};
-mod dirstate;
+pub mod dirstate;
 pub mod dirstate_tree;
 pub mod discovery;
 pub mod requirements;
--- a/rust/hg-cpython/src/dirstate/dirstate_map.rs	Tue Apr 06 21:07:12 2021 +0200
+++ b/rust/hg-cpython/src/dirstate/dirstate_map.rs	Mon Apr 12 14:43:45 2021 +0200
@@ -10,7 +10,6 @@
 
 use std::cell::{Ref, RefCell};
 use std::convert::TryInto;
-use std::time::Duration;
 
 use cpython::{
     exc, ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyList,
@@ -27,6 +26,7 @@
     parsers::dirstate_parents_to_pytuple,
 };
 use hg::{
+    dirstate::parsers::Timestamp,
     dirstate_tree::dispatch::DirstateMapMethods,
     errors::HgError,
     revlog::Node,
@@ -312,7 +312,7 @@
         p2: PyObject,
         now: PyObject
     ) -> PyResult<PyBytes> {
-        let now = Duration::new(now.extract(py)?, 0);
+        let now = Timestamp(now.extract(py)?);
         let parents = DirstateParents {
             p1: extract_node_id(py, &p1)?,
             p2: extract_node_id(py, &p2)?,
--- a/rust/hg-cpython/src/parsers.rs	Tue Apr 06 21:07:12 2021 +0200
+++ b/rust/hg-cpython/src/parsers.rs	Mon Apr 12 14:43:45 2021 +0200
@@ -14,13 +14,13 @@
     PythonObject, ToPyObject,
 };
 use hg::{
-    pack_dirstate, parse_dirstate, utils::hg_path::HgPathBuf, DirstateEntry,
-    DirstateParents, FastHashMap, PARENT_SIZE,
+    dirstate::parsers::Timestamp, pack_dirstate, parse_dirstate,
+    utils::hg_path::HgPathBuf, DirstateEntry, DirstateParents, FastHashMap,
+    PARENT_SIZE,
 };
 use std::convert::TryInto;
 
 use crate::dirstate::{extract_dirstate, make_dirstate_tuple};
-use std::time::Duration;
 
 fn parse_dirstate_wrapper(
     py: Python,
@@ -98,7 +98,7 @@
             p1: p1.try_into().unwrap(),
             p2: p2.try_into().unwrap(),
         },
-        Duration::from_secs(now.as_object().extract::<u64>(py)?),
+        Timestamp(now.as_object().extract::<u64>(py)?),
     ) {
         Ok(packed) => {
             for (filename, entry) in dirstate_map.iter() {