Mercurial > public > mercurial-scm > hg
diff rust/hg-cpython/src/dirstate/dirstate_map.rs @ 47674:ff97e793ed36
dirstate-v2: Introduce a docket file
.hg/dirstate now only contains some metadata to point to a separate data file
named .hg/dirstate.{}.d with a random hexadecimal identifier. For now every
update creates a new data file and removes the old one, but later we?ll
(usually) append to an existing file.
Separating into two files allows doing the "write to a temporary file then
atomically rename into destination" dance with only a small docket file,
without always rewriting a lot of data.
Differential Revision: https://phab.mercurial-scm.org/D11088
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Thu, 08 Jul 2021 12:18:21 +0200 |
parents | 7a15dea6d303 |
children | 48aec076b8fb |
line wrap: on
line diff
--- a/rust/hg-cpython/src/dirstate/dirstate_map.rs Thu Jul 15 17:24:09 2021 +0200 +++ b/rust/hg-cpython/src/dirstate/dirstate_map.rs Thu Jul 08 12:18:21 2021 +0200 @@ -57,17 +57,15 @@ /// Returns a `(dirstate_map, parents)` tuple @staticmethod - def new( + def new_v1( use_dirstate_tree: bool, - use_dirstate_v2: bool, on_disk: PyBytes, ) -> PyResult<PyObject> { let dirstate_error = |e: DirstateError| { PyErr::new::<exc::OSError, _>(py, format!("Dirstate error: {:?}", e)) }; - let (inner, parents) = if use_dirstate_tree || use_dirstate_v2 { - let (map, parents) = - OwningDirstateMap::new(py, on_disk, use_dirstate_v2) + let (inner, parents) = if use_dirstate_tree { + let (map, parents) = OwningDirstateMap::new_v1(py, on_disk) .map_err(dirstate_error)?; (Box::new(map) as _, parents) } else { @@ -81,6 +79,20 @@ Ok((map, parents).to_py_object(py).into_object()) } + /// Returns a DirstateMap + @staticmethod + def new_v2( + on_disk: PyBytes, + ) -> PyResult<PyObject> { + let dirstate_error = |e: DirstateError| { + PyErr::new::<exc::OSError, _>(py, format!("Dirstate error: {:?}", e)) + }; + let inner = OwningDirstateMap::new_v2(py, on_disk) + .map_err(dirstate_error)?; + let map = Self::create_instance(py, Box::new(inner))?; + Ok(map.into_object()) + } + def clear(&self) -> PyResult<PyObject> { self.inner(py).borrow_mut().clear(); Ok(py.None()) @@ -304,25 +316,37 @@ .to_py_object(py)) } - def write( + def write_v1( &self, - use_dirstate_v2: bool, p1: PyObject, p2: PyObject, now: PyObject ) -> PyResult<PyBytes> { let now = Timestamp(now.extract(py)?); + + let mut inner = self.inner(py).borrow_mut(); let parents = DirstateParents { p1: extract_node_id(py, &p1)?, p2: extract_node_id(py, &p2)?, }; + let result = inner.pack_v1(parents, now); + match result { + Ok(packed) => Ok(PyBytes::new(py, &packed)), + Err(_) => Err(PyErr::new::<exc::OSError, _>( + py, + "Dirstate error".to_string(), + )), + } + } + + def write_v2( + &self, + now: PyObject + ) -> PyResult<PyBytes> { + let now = Timestamp(now.extract(py)?); let mut inner = self.inner(py).borrow_mut(); - let result = if use_dirstate_v2 { - inner.pack_v2(parents, now) - } else { - inner.pack_v1(parents, now) - }; + let result = inner.pack_v2(now); match result { Ok(packed) => Ok(PyBytes::new(py, &packed)), Err(_) => Err(PyErr::new::<exc::OSError, _>(