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) | ||||
} | } | ||||
} | } |