Mercurial > hg
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(); |