Mercurial > hg
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 |