comparison 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
comparison
equal deleted inserted replaced
47953:8f031a274cd6 47954:4afd6cc447b9
22 dirstate::make_dirstate_item, 22 dirstate::make_dirstate_item,
23 dirstate::make_dirstate_item_raw, 23 dirstate::make_dirstate_item_raw,
24 dirstate::non_normal_entries::{ 24 dirstate::non_normal_entries::{
25 NonNormalEntries, NonNormalEntriesIterator, 25 NonNormalEntries, NonNormalEntriesIterator,
26 }, 26 },
27 dirstate::owning::OwningDirstateMap,
28 parsers::dirstate_parents_to_pytuple, 27 parsers::dirstate_parents_to_pytuple,
28 pybytes_deref::PyBytesDeref,
29 }; 29 };
30 use hg::{ 30 use hg::{
31 dirstate::parsers::Timestamp, 31 dirstate::parsers::Timestamp,
32 dirstate::MTIME_UNSET, 32 dirstate::MTIME_UNSET,
33 dirstate::SIZE_NON_NORMAL, 33 dirstate::SIZE_NON_NORMAL,
34 dirstate_tree::dirstate_map::DirstateMap as TreeDirstateMap,
34 dirstate_tree::dispatch::DirstateMapMethods, 35 dirstate_tree::dispatch::DirstateMapMethods,
35 dirstate_tree::on_disk::DirstateV2ParseError, 36 dirstate_tree::on_disk::DirstateV2ParseError,
37 dirstate_tree::owning::OwningDirstateMap,
36 revlog::Node, 38 revlog::Node,
37 utils::files::normalize_case, 39 utils::files::normalize_case,
38 utils::hg_path::{HgPath, HgPathBuf}, 40 utils::hg_path::{HgPath, HgPathBuf},
39 DirstateEntry, DirstateError, DirstateMap as RustDirstateMap, 41 DirstateEntry, DirstateError, DirstateMap as RustDirstateMap,
40 DirstateParents, EntryState, StateMapIter, 42 DirstateParents, EntryState, StateMapIter,
60 def new_v1( 62 def new_v1(
61 use_dirstate_tree: bool, 63 use_dirstate_tree: bool,
62 on_disk: PyBytes, 64 on_disk: PyBytes,
63 ) -> PyResult<PyObject> { 65 ) -> PyResult<PyObject> {
64 let (inner, parents) = if use_dirstate_tree { 66 let (inner, parents) = if use_dirstate_tree {
65 let (map, parents) = OwningDirstateMap::new_v1(py, on_disk) 67 let on_disk = PyBytesDeref::new(py, on_disk);
68 let mut map = OwningDirstateMap::new_empty(on_disk);
69 let (on_disk, map_placeholder) = map.get_mut_pair();
70
71 let (actual_map, parents) = TreeDirstateMap::new_v1(on_disk)
66 .map_err(|e| dirstate_error(py, e))?; 72 .map_err(|e| dirstate_error(py, e))?;
73 *map_placeholder = actual_map;
67 (Box::new(map) as _, parents) 74 (Box::new(map) as _, parents)
68 } else { 75 } else {
69 let bytes = on_disk.data(py); 76 let bytes = on_disk.data(py);
70 let mut map = RustDirstateMap::default(); 77 let mut map = RustDirstateMap::default();
71 let parents = map.read(bytes).map_err(|e| dirstate_error(py, e))?; 78 let parents = map.read(bytes).map_err(|e| dirstate_error(py, e))?;
84 tree_metadata: PyBytes, 91 tree_metadata: PyBytes,
85 ) -> PyResult<PyObject> { 92 ) -> PyResult<PyObject> {
86 let dirstate_error = |e: DirstateError| { 93 let dirstate_error = |e: DirstateError| {
87 PyErr::new::<exc::OSError, _>(py, format!("Dirstate error: {:?}", e)) 94 PyErr::new::<exc::OSError, _>(py, format!("Dirstate error: {:?}", e))
88 }; 95 };
89 let inner = OwningDirstateMap::new_v2( 96 let on_disk = PyBytesDeref::new(py, on_disk);
90 py, on_disk, data_size, tree_metadata, 97 let mut map = OwningDirstateMap::new_empty(on_disk);
98 let (on_disk, map_placeholder) = map.get_mut_pair();
99 *map_placeholder = TreeDirstateMap::new_v2(
100 on_disk, data_size, tree_metadata.data(py),
91 ).map_err(dirstate_error)?; 101 ).map_err(dirstate_error)?;
92 let map = Self::create_instance(py, Box::new(inner))?; 102 let map = Self::create_instance(py, Box::new(map))?;
93 Ok(map.into_object()) 103 Ok(map.into_object())
94 } 104 }
95 105
96 def clear(&self) -> PyResult<PyObject> { 106 def clear(&self) -> PyResult<PyObject> {
97 self.inner(py).borrow_mut().clear(); 107 self.inner(py).borrow_mut().clear();