Now that the DirstateItem python class is implemented in Rust containing
a DirstateEntry value, use that value directly instead of reconstructing
it from v1 data.
Also rename from set_v1 since dirstate-v1 data is not used anymore.
| Alphare |
| hg-reviewers |
Now that the DirstateItem python class is implemented in Rust containing
a DirstateEntry value, use that value directly instead of reconstructing
it from v1 data.
Also rename from set_v1 since dirstate-v1 data is not used anymore.
| Automatic diff as part of commit; lint not applicable. |
| Automatic diff as part of commit; unit tests not applicable. |
| Path | Packages | |||
|---|---|---|---|---|
| M | mercurial/dirstatemap.py (8 lines) | |||
| M | rust/hg-core/src/dirstate/dirstate_map.rs (2 lines) | |||
| M | rust/hg-core/src/dirstate_tree/dirstate_map.rs (2 lines) | |||
| M | rust/hg-core/src/dirstate_tree/dispatch.rs (8 lines) | |||
| M | rust/hg-core/src/dirstate_tree/owning_dispatch.rs (4 lines) | |||
| M | rust/hg-cpython/src/dirstate/dirstate_map.rs (16 lines) | |||
| M | rust/hg-cpython/src/dirstate/item.rs (4 lines) |
| Status | Author | Revision | |
|---|---|---|---|
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | SimonSapin |
| def set_tracked(self, filename): | def set_tracked(self, filename): | ||||
| new = False | new = False | ||||
| entry = self.get(filename) | entry = self.get(filename) | ||||
| if entry is None: | if entry is None: | ||||
| self.addfile(filename, added=True) | self.addfile(filename, added=True) | ||||
| new = True | new = True | ||||
| elif not entry.tracked: | elif not entry.tracked: | ||||
| entry.set_tracked() | entry.set_tracked() | ||||
| self._rustmap.set_v1(filename, entry) | self._rustmap.set_dirstate_item(filename, entry) | ||||
| new = True | new = True | ||||
| else: | else: | ||||
| # XXX This is probably overkill for more case, but we need this to | # XXX This is probably overkill for more case, but we need this to | ||||
| # fully replace the `normallookup` call with `set_tracked` one. | # fully replace the `normallookup` call with `set_tracked` one. | ||||
| # Consider smoothing this in the future. | # Consider smoothing this in the future. | ||||
| self.set_possibly_dirty(filename) | self.set_possibly_dirty(filename) | ||||
| return new | return new | ||||
| for name in self._rustmap.tracked_dirs(): | for name in self._rustmap.tracked_dirs(): | ||||
| f[normcase(name)] = name | f[normcase(name)] = name | ||||
| return f | return f | ||||
| def set_possibly_dirty(self, filename): | def set_possibly_dirty(self, filename): | ||||
| """record that the current state of the file on disk is unknown""" | """record that the current state of the file on disk is unknown""" | ||||
| entry = self[filename] | entry = self[filename] | ||||
| entry.set_possibly_dirty() | entry.set_possibly_dirty() | ||||
| self._rustmap.set_v1(filename, entry) | self._rustmap.set_dirstate_item(filename, entry) | ||||
| def set_clean(self, filename, mode, size, mtime): | def set_clean(self, filename, mode, size, mtime): | ||||
| """mark a file as back to a clean state""" | """mark a file as back to a clean state""" | ||||
| entry = self[filename] | entry = self[filename] | ||||
| mtime = mtime & rangemask | mtime = mtime & rangemask | ||||
| size = size & rangemask | size = size & rangemask | ||||
| entry.set_clean(mode, size, mtime) | entry.set_clean(mode, size, mtime) | ||||
| self._rustmap.set_v1(filename, entry) | self._rustmap.set_dirstate_item(filename, entry) | ||||
| self._rustmap.copymap().pop(filename, None) | self._rustmap.copymap().pop(filename, None) | ||||
| def __setitem__(self, key, value): | def __setitem__(self, key, value): | ||||
| assert isinstance(value, DirstateItem) | assert isinstance(value, DirstateItem) | ||||
| self._rustmap.set_v1(key, value) | self._rustmap.set_dirstate_item(key, value) | ||||
| pub fn clear(&mut self) { | pub fn clear(&mut self) { | ||||
| self.state_map = StateMap::default(); | self.state_map = StateMap::default(); | ||||
| self.copy_map.clear(); | self.copy_map.clear(); | ||||
| self.non_normal_set = None; | self.non_normal_set = None; | ||||
| self.other_parent_set = None; | self.other_parent_set = None; | ||||
| } | } | ||||
| pub fn set_v1_inner(&mut self, filename: &HgPath, entry: DirstateEntry) { | pub fn set_entry(&mut self, filename: &HgPath, entry: DirstateEntry) { | ||||
| self.state_map.insert(filename.to_owned(), entry); | self.state_map.insert(filename.to_owned(), entry); | ||||
| } | } | ||||
| /// Add a tracked file to the dirstate | /// Add a tracked file to the dirstate | ||||
| pub fn add_file( | pub fn add_file( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| entry: DirstateEntry, | entry: DirstateEntry, | ||||
| impl<'on_disk> super::dispatch::DirstateMapMethods for DirstateMap<'on_disk> { | impl<'on_disk> super::dispatch::DirstateMapMethods for DirstateMap<'on_disk> { | ||||
| fn clear(&mut self) { | fn clear(&mut self) { | ||||
| self.root = Default::default(); | self.root = Default::default(); | ||||
| self.nodes_with_entry_count = 0; | self.nodes_with_entry_count = 0; | ||||
| self.nodes_with_copy_source_count = 0; | self.nodes_with_copy_source_count = 0; | ||||
| } | } | ||||
| fn set_v1(&mut self, filename: &HgPath, entry: DirstateEntry) { | fn set_entry(&mut self, filename: &HgPath, entry: DirstateEntry) { | ||||
| let node = | let node = | ||||
| self.get_or_insert(&filename).expect("no parse error in v1"); | self.get_or_insert(&filename).expect("no parse error in v1"); | ||||
| node.data = NodeData::Entry(entry); | node.data = NodeData::Entry(entry); | ||||
| node.children = ChildNodes::default(); | node.children = ChildNodes::default(); | ||||
| node.copy_source = None; | node.copy_source = None; | ||||
| node.descendants_with_entry_count = 0; | node.descendants_with_entry_count = 0; | ||||
| node.tracked_descendants_count = 0; | node.tracked_descendants_count = 0; | ||||
| } | } | ||||
| /// abstracted in this trait. | /// abstracted in this trait. | ||||
| /// | /// | ||||
| /// The dirstate map associates paths of files in the working directory to | /// The dirstate map associates paths of files in the working directory to | ||||
| /// various information about the state of those files. | /// various information about the state of those files. | ||||
| pub trait DirstateMapMethods { | pub trait DirstateMapMethods { | ||||
| /// Remove information about all files in this map | /// Remove information about all files in this map | ||||
| fn clear(&mut self); | fn clear(&mut self); | ||||
| fn set_v1(&mut self, filename: &HgPath, entry: DirstateEntry); | /// Add the given filename to the map if it is not already there, and | ||||
| /// associate the given entry with it. | |||||
| fn set_entry(&mut self, filename: &HgPath, entry: DirstateEntry); | |||||
| /// Add or change the information associated to a given file. | /// Add or change the information associated to a given file. | ||||
| /// | /// | ||||
| /// `old_state` is the state in the entry that `get` would have returned | /// `old_state` is the state in the entry that `get` would have returned | ||||
| /// before this call, or `EntryState::Unknown` if there was no such entry. | /// before this call, or `EntryState::Unknown` if there was no such entry. | ||||
| /// | /// | ||||
| /// `entry.state` should never be `EntryState::Unknown`. | /// `entry.state` should never be `EntryState::Unknown`. | ||||
| fn add_file( | fn add_file( | ||||
| fn clear(&mut self) { | fn clear(&mut self) { | ||||
| self.clear() | self.clear() | ||||
| } | } | ||||
| /// Used to set a value directory. | /// Used to set a value directory. | ||||
| /// | /// | ||||
| /// XXX Is temporary during a refactor of V1 dirstate and will disappear | /// XXX Is temporary during a refactor of V1 dirstate and will disappear | ||||
| /// shortly. | /// shortly. | ||||
| fn set_v1(&mut self, filename: &HgPath, entry: DirstateEntry) { | fn set_entry(&mut self, filename: &HgPath, entry: DirstateEntry) { | ||||
| self.set_v1_inner(&filename, entry) | self.set_entry(&filename, entry) | ||||
| } | } | ||||
| fn add_file( | fn add_file( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| entry: DirstateEntry, | entry: DirstateEntry, | ||||
| added: bool, | added: bool, | ||||
| merged: bool, | merged: bool, | ||||
| use crate::StatusOptions; | use crate::StatusOptions; | ||||
| use std::path::PathBuf; | use std::path::PathBuf; | ||||
| impl DirstateMapMethods for OwningDirstateMap { | impl DirstateMapMethods for OwningDirstateMap { | ||||
| fn clear(&mut self) { | fn clear(&mut self) { | ||||
| self.get_mut().clear() | self.get_mut().clear() | ||||
| } | } | ||||
| fn set_v1(&mut self, filename: &HgPath, entry: DirstateEntry) { | fn set_entry(&mut self, filename: &HgPath, entry: DirstateEntry) { | ||||
| self.get_mut().set_v1(filename, entry) | self.get_mut().set_entry(filename, entry) | ||||
| } | } | ||||
| fn add_file( | fn add_file( | ||||
| &mut self, | &mut self, | ||||
| filename: &HgPath, | filename: &HgPath, | ||||
| entry: DirstateEntry, | entry: DirstateEntry, | ||||
| added: bool, | added: bool, | ||||
| merged: bool, | merged: bool, | ||||
| { | { | ||||
| Some(entry) => { | Some(entry) => { | ||||
| Ok(Some(DirstateItem::new_as_pyobject(py, entry)?)) | Ok(Some(DirstateItem::new_as_pyobject(py, entry)?)) | ||||
| }, | }, | ||||
| None => Ok(default) | None => Ok(default) | ||||
| } | } | ||||
| } | } | ||||
| def set_v1(&self, path: PyObject, item: PyObject) -> PyResult<PyObject> { | def set_dirstate_item( | ||||
| &self, | |||||
| path: PyObject, | |||||
| item: DirstateItem | |||||
| ) -> PyResult<PyObject> { | |||||
| let f = path.extract::<PyBytes>(py)?; | let f = path.extract::<PyBytes>(py)?; | ||||
| let filename = HgPath::new(f.data(py)); | let filename = HgPath::new(f.data(py)); | ||||
| let state = item.getattr(py, "state")?.extract::<PyBytes>(py)?; | self.inner(py).borrow_mut().set_entry(filename, item.get_entry(py)); | ||||
| let state = state.data(py)[0]; | |||||
| let entry = DirstateEntry::from_v1_data( | |||||
| state.try_into().expect("state is always valid"), | |||||
| item.getattr(py, "mode")?.extract(py)?, | |||||
| item.getattr(py, "size")?.extract(py)?, | |||||
| item.getattr(py, "mtime")?.extract(py)?, | |||||
| ); | |||||
| self.inner(py).borrow_mut().set_v1(filename, entry); | |||||
| Ok(py.None()) | Ok(py.None()) | ||||
| } | } | ||||
| def addfile( | def addfile( | ||||
| &self, | &self, | ||||
| f: PyObject, | f: PyObject, | ||||
| mode: PyObject, | mode: PyObject, | ||||
| size: PyObject, | size: PyObject, | ||||
| impl DirstateItem { | impl DirstateItem { | ||||
| pub fn new_as_pyobject( | pub fn new_as_pyobject( | ||||
| py: Python<'_>, | py: Python<'_>, | ||||
| entry: DirstateEntry, | entry: DirstateEntry, | ||||
| ) -> PyResult<PyObject> { | ) -> PyResult<PyObject> { | ||||
| Ok(DirstateItem::create_instance(py, Cell::new(entry))?.into_object()) | Ok(DirstateItem::create_instance(py, Cell::new(entry))?.into_object()) | ||||
| } | } | ||||
| pub fn get_entry(&self, py: Python<'_>) -> DirstateEntry { | |||||
| self.entry(py).get() | |||||
| } | |||||
| // TODO: Use https://doc.rust-lang.org/std/cell/struct.Cell.html#method.update instead when it’s stable | // TODO: Use https://doc.rust-lang.org/std/cell/struct.Cell.html#method.update instead when it’s stable | ||||
| pub fn update(&self, py: Python<'_>, f: impl FnOnce(&mut DirstateEntry)) { | pub fn update(&self, py: Python<'_>, f: impl FnOnce(&mut DirstateEntry)) { | ||||
| let mut entry = self.entry(py).get(); | let mut entry = self.entry(py).get(); | ||||
| f(&mut entry); | f(&mut entry); | ||||
| self.entry(py).set(entry) | self.entry(py).set(entry) | ||||
| } | } | ||||
| } | } | ||||