Mercurial > public > mercurial-scm > hg
diff rust/hg-cpython/src/dirstate/dirstate_map.rs @ 47954:4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
This will enable using it in rhg too.
The `OwningDirstateMap::new_empty` constructor is generic and accepts a value
of any type that gives acces to a bytes buffer. That buffer must stay valid
as long as the value hasn?t been dropped, and must keep its memory address
even if the value is moved. The `StableDeref` marker trait encodes those
constraints. Previously no trait was needed because the value was always
of type `PyBytes` which we know satisfies those constraints.
The buffer type is ereased in the struct itself through boxing and
dynamic dispatch, in order to simplify other signatures that mention
`OwningDirstateMap`.
Differential Revision: https://phab.mercurial-scm.org/D11396
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Thu, 09 Sep 2021 18:07:40 +0200 |
parents | e5fb14a07866 |
children | 1194394510ba |
line wrap: on
line diff
--- a/rust/hg-cpython/src/dirstate/dirstate_map.rs Mon Sep 06 13:39:54 2021 +0200 +++ b/rust/hg-cpython/src/dirstate/dirstate_map.rs Thu Sep 09 18:07:40 2021 +0200 @@ -24,15 +24,17 @@ dirstate::non_normal_entries::{ NonNormalEntries, NonNormalEntriesIterator, }, - dirstate::owning::OwningDirstateMap, parsers::dirstate_parents_to_pytuple, + pybytes_deref::PyBytesDeref, }; use hg::{ dirstate::parsers::Timestamp, dirstate::MTIME_UNSET, dirstate::SIZE_NON_NORMAL, + dirstate_tree::dirstate_map::DirstateMap as TreeDirstateMap, dirstate_tree::dispatch::DirstateMapMethods, dirstate_tree::on_disk::DirstateV2ParseError, + dirstate_tree::owning::OwningDirstateMap, revlog::Node, utils::files::normalize_case, utils::hg_path::{HgPath, HgPathBuf}, @@ -62,8 +64,13 @@ on_disk: PyBytes, ) -> PyResult<PyObject> { let (inner, parents) = if use_dirstate_tree { - let (map, parents) = OwningDirstateMap::new_v1(py, on_disk) + let on_disk = PyBytesDeref::new(py, on_disk); + let mut map = OwningDirstateMap::new_empty(on_disk); + let (on_disk, map_placeholder) = map.get_mut_pair(); + + let (actual_map, parents) = TreeDirstateMap::new_v1(on_disk) .map_err(|e| dirstate_error(py, e))?; + *map_placeholder = actual_map; (Box::new(map) as _, parents) } else { let bytes = on_disk.data(py); @@ -86,10 +93,13 @@ let dirstate_error = |e: DirstateError| { PyErr::new::<exc::OSError, _>(py, format!("Dirstate error: {:?}", e)) }; - let inner = OwningDirstateMap::new_v2( - py, on_disk, data_size, tree_metadata, + let on_disk = PyBytesDeref::new(py, on_disk); + let mut map = OwningDirstateMap::new_empty(on_disk); + let (on_disk, map_placeholder) = map.get_mut_pair(); + *map_placeholder = TreeDirstateMap::new_v2( + on_disk, data_size, tree_metadata.data(py), ).map_err(dirstate_error)?; - let map = Self::create_instance(py, Box::new(inner))?; + let map = Self::create_instance(py, Box::new(map))?; Ok(map.into_object()) }