comparison rust/hg-cpython/src/dirstate/dirstate_map.rs @ 47122:9aba0cde0ed9

rust: Read dirstate from disk in DirstateMap constructor Before this changeset, Python code first creates an empty `DirstateMap` Rust object, then immediately calls its `read` method with a byte string of the contents of the `.hg/dirstate` file. This makes that byte string available to the constructor of `DirstateMap` in the hg-cpython crate. This is a first step towards enabling parts of `DirstateMap` in the hg-core crate to borrow from this buffer without copying. Differential Revision: https://phab.mercurial-scm.org/D10556
author Simon Sapin <simon.sapin@octobus.net>
date Fri, 30 Apr 2021 18:13:31 +0200
parents b6339a993b91
children d8ac62374943
comparison
equal deleted inserted replaced
47121:b6339a993b91 47122:9aba0cde0ed9
30 dirstate_tree::dispatch::DirstateMapMethods, 30 dirstate_tree::dispatch::DirstateMapMethods,
31 errors::HgError, 31 errors::HgError,
32 revlog::Node, 32 revlog::Node,
33 utils::files::normalize_case, 33 utils::files::normalize_case,
34 utils::hg_path::{HgPath, HgPathBuf}, 34 utils::hg_path::{HgPath, HgPathBuf},
35 DirsMultiset, DirstateEntry, DirstateMap as RustDirstateMap, 35 DirsMultiset, DirstateEntry, DirstateError,
36 DirstateMapError, DirstateParents, EntryState, StateMapIter, 36 DirstateMap as RustDirstateMap, DirstateMapError, DirstateParents,
37 EntryState, StateMapIter,
37 }; 38 };
38 39
39 // TODO 40 // TODO
40 // This object needs to share references to multiple members of its Rust 41 // This object needs to share references to multiple members of its Rust
41 // inner struct, namely `copy_map`, `dirs` and `all_dirs`. 42 // inner struct, namely `copy_map`, `dirs` and `all_dirs`.
49 // All attributes also have to have a separate refcount data attribute for 50 // All attributes also have to have a separate refcount data attribute for
50 // leaks, with all methods that go along for reference sharing. 51 // leaks, with all methods that go along for reference sharing.
51 py_class!(pub class DirstateMap |py| { 52 py_class!(pub class DirstateMap |py| {
52 @shared data inner: Box<dyn DirstateMapMethods + Send>; 53 @shared data inner: Box<dyn DirstateMapMethods + Send>;
53 54
54 def __new__(_cls, use_dirstate_tree: bool) -> PyResult<Self> { 55 /// Returns a `(dirstate_map, parents)` tuple
55 let inner = if use_dirstate_tree { 56 @staticmethod
56 Box::new(hg::dirstate_tree::dirstate_map::DirstateMap::new()) as _ 57 def new(use_dirstate_tree: bool, on_disk: PyBytes) -> PyResult<PyObject> {
58 let dirstate_error = |_: DirstateError| {
59 PyErr::new::<exc::OSError, _>(py, "Dirstate error".to_string())
60 };
61 let bytes = on_disk.data(py);
62 let (inner, parents) = if use_dirstate_tree {
63 let mut map = hg::dirstate_tree::dirstate_map::DirstateMap::new();
64 let parents = map.read(bytes).map_err(dirstate_error)?;
65 (Box::new(map) as _, parents)
57 } else { 66 } else {
58 Box::new(RustDirstateMap::default()) as _ 67 let mut map = RustDirstateMap::default();
68 let parents = map.read(bytes).map_err(dirstate_error)?;
69 (Box::new(map) as _, parents)
59 }; 70 };
60 Self::create_instance(py, inner) 71 let map = Self::create_instance(py, inner)?;
72 let parents = parents.map(|p| dirstate_parents_to_pytuple(py, &p));
73 Ok((map, parents).to_py_object(py).into_object())
61 } 74 }
62 75
63 def clear(&self) -> PyResult<PyObject> { 76 def clear(&self) -> PyResult<PyObject> {
64 self.inner(py).borrow_mut().clear(); 77 self.inner(py).borrow_mut().clear();
65 Ok(py.None()) 78 Ok(py.None())
269 PyErr::new::<exc::ValueError, _>(py, e.to_string()) 282 PyErr::new::<exc::ValueError, _>(py, e.to_string())
270 })? 283 })?
271 .to_py_object(py)) 284 .to_py_object(py))
272 } 285 }
273 286
274 def read(&self, st: PyObject) -> PyResult<Option<PyObject>> {
275 match self.inner(py).borrow_mut()
276 .read(st.extract::<PyBytes>(py)?.data(py))
277 {
278 Ok(Some(parents)) => Ok(Some(
279 dirstate_parents_to_pytuple(py, parents)
280 .into_object()
281 )),
282 Ok(None) => Ok(Some(py.None())),
283 Err(_) => Err(PyErr::new::<exc::OSError, _>(
284 py,
285 "Dirstate error".to_string(),
286 )),
287 }
288 }
289 def write( 287 def write(
290 &self, 288 &self,
291 p1: PyObject, 289 p1: PyObject,
292 p2: PyObject, 290 p2: PyObject,
293 now: PyObject 291 now: PyObject