dirstate-tree: Abstract "non-normal" and "other parent" sets
Instead of exposing `HashSet`s directly, have slightly higher-level
methods for the operations that Python bindings need on them.
Differential Revision: https://phab.mercurial-scm.org/D10363
--- a/mercurial/dirstate.py Tue Mar 30 14:15:23 2021 +0200
+++ b/mercurial/dirstate.py Thu Apr 08 14:58:44 2021 +0200
@@ -340,9 +340,8 @@
oldp2 != self._nodeconstants.nullid
and p2 == self._nodeconstants.nullid
):
- candidatefiles = self._map.nonnormalset.union(
- self._map.otherparentset
- )
+ candidatefiles = self._map.non_normal_or_other_parent_paths()
+
for f in candidatefiles:
s = self._map.get(f)
if s is None:
@@ -1725,6 +1724,9 @@
self.nonnormalset = nonnorm
return otherparents
+ def non_normal_or_other_parent_paths(self):
+ return self.nonnormalset.union(self.otherparentset)
+
@propertycache
def identity(self):
self._map
@@ -1939,6 +1941,9 @@
otherparents = self._rustmap.other_parent_entries()
return otherparents
+ def non_normal_or_other_parent_paths(self):
+ return self._rustmap.non_normal_or_other_parent_paths()
+
@propertycache
def dirfoldmap(self):
f = {}
--- a/rust/hg-core/src/dirstate_tree/dispatch.rs Tue Mar 30 14:15:23 2021 +0200
+++ b/rust/hg-core/src/dirstate_tree/dispatch.rs Thu Apr 08 14:58:44 2021 +0200
@@ -1,4 +1,3 @@
-use std::collections::HashSet;
use std::path::PathBuf;
use std::time::Duration;
@@ -44,22 +43,27 @@
fn clear_ambiguous_times(&mut self, filenames: Vec<HgPathBuf>, now: i32);
+ fn non_normal_entries_contains(&mut self, key: &HgPath) -> bool;
+
fn non_normal_entries_remove(&mut self, key: &HgPath) -> bool;
- fn non_normal_entries_union(
+ fn non_normal_or_other_parent_paths(
&mut self,
- other: HashSet<HgPathBuf>,
- ) -> Vec<HgPathBuf>;
+ ) -> Box<dyn Iterator<Item = &HgPathBuf> + '_>;
fn set_non_normal_other_parent_entries(&mut self, force: bool);
- fn get_non_normal_other_parent_entries_panic(
- &self,
- ) -> (&HashSet<HgPathBuf>, &HashSet<HgPathBuf>);
+ fn iter_non_normal_paths(
+ &mut self,
+ ) -> Box<dyn Iterator<Item = &HgPathBuf> + Send + '_>;
- fn get_non_normal_other_parent_entries(
+ fn iter_non_normal_paths_panic(
+ &self,
+ ) -> Box<dyn Iterator<Item = &HgPathBuf> + Send + '_>;
+
+ fn iter_other_parent_paths(
&mut self,
- ) -> (&mut HashSet<HgPathBuf>, &mut HashSet<HgPathBuf>);
+ ) -> Box<dyn Iterator<Item = &HgPathBuf> + Send + '_>;
fn has_tracked_dir(
&mut self,
@@ -169,31 +173,50 @@
self.clear_ambiguous_times(filenames, now)
}
+ fn non_normal_entries_contains(&mut self, key: &HgPath) -> bool {
+ let (non_normal, _other_parent) =
+ self.get_non_normal_other_parent_entries();
+ non_normal.contains(key)
+ }
+
fn non_normal_entries_remove(&mut self, key: &HgPath) -> bool {
self.non_normal_entries_remove(key)
}
- fn non_normal_entries_union(
+ fn non_normal_or_other_parent_paths(
&mut self,
- other: HashSet<HgPathBuf>,
- ) -> Vec<HgPathBuf> {
- self.non_normal_entries_union(other)
+ ) -> Box<dyn Iterator<Item = &HgPathBuf> + '_> {
+ let (non_normal, other_parent) =
+ self.get_non_normal_other_parent_entries();
+ Box::new(non_normal.union(other_parent))
}
fn set_non_normal_other_parent_entries(&mut self, force: bool) {
self.set_non_normal_other_parent_entries(force)
}
- fn get_non_normal_other_parent_entries_panic(
- &self,
- ) -> (&HashSet<HgPathBuf>, &HashSet<HgPathBuf>) {
- self.get_non_normal_other_parent_entries_panic()
+ fn iter_non_normal_paths(
+ &mut self,
+ ) -> Box<dyn Iterator<Item = &HgPathBuf> + Send + '_> {
+ let (non_normal, _other_parent) =
+ self.get_non_normal_other_parent_entries();
+ Box::new(non_normal.iter())
}
- fn get_non_normal_other_parent_entries(
+ fn iter_non_normal_paths_panic(
+ &self,
+ ) -> Box<dyn Iterator<Item = &HgPathBuf> + Send + '_> {
+ let (non_normal, _other_parent) =
+ self.get_non_normal_other_parent_entries_panic();
+ Box::new(non_normal.iter())
+ }
+
+ fn iter_other_parent_paths(
&mut self,
- ) -> (&mut HashSet<HgPathBuf>, &mut HashSet<HgPathBuf>) {
- self.get_non_normal_other_parent_entries()
+ ) -> Box<dyn Iterator<Item = &HgPathBuf> + Send + '_> {
+ let (_non_normal, other_parent) =
+ self.get_non_normal_other_parent_entries();
+ Box::new(other_parent.iter())
}
fn has_tracked_dir(
--- a/rust/hg-cpython/src/dirstate/dirstate_map.rs Tue Mar 30 14:15:23 2021 +0200
+++ b/rust/hg-cpython/src/dirstate/dirstate_map.rs Thu Apr 08 14:58:44 2021 +0200
@@ -173,11 +173,8 @@
def other_parent_entries(&self) -> PyResult<PyObject> {
let mut inner_shared = self.inner(py).borrow_mut();
- let (_, other_parent) =
- inner_shared.get_non_normal_other_parent_entries();
-
let set = PySet::empty(py)?;
- for path in other_parent.iter() {
+ for path in inner_shared.iter_other_parent_paths() {
set.add(py, PyBytes::new(py, path.as_bytes()))?;
}
Ok(set.into_object())
@@ -192,8 +189,7 @@
Ok(self
.inner(py)
.borrow_mut()
- .get_non_normal_other_parent_entries().0
- .contains(HgPath::new(key.data(py))))
+ .non_normal_entries_contains(HgPath::new(key.data(py))))
}
def non_normal_entries_display(&self) -> PyResult<PyString> {
@@ -201,14 +197,17 @@
PyString::new(
py,
&format!(
- "NonNormalEntries: {:?}",
- self
- .inner(py)
- .borrow_mut()
- .get_non_normal_other_parent_entries().0
- .iter().map(|o| o))
+ "NonNormalEntries: {}",
+ hg::utils::join_display(
+ self
+ .inner(py)
+ .borrow_mut()
+ .iter_non_normal_paths(),
+ ", "
+ )
)
)
+ )
}
def non_normal_entries_remove(&self, key: PyObject) -> PyResult<PyObject> {
@@ -220,22 +219,11 @@
Ok(py.None())
}
- def non_normal_entries_union(&self, other: PyObject) -> PyResult<PyList> {
- let other: PyResult<_> = other.iter(py)?
- .map(|f| {
- Ok(HgPathBuf::from_bytes(
- f?.extract::<PyBytes>(py)?.data(py),
- ))
- })
- .collect();
-
- let res = self
- .inner(py)
- .borrow_mut()
- .non_normal_entries_union(other?);
+ def non_normal_or_other_parent_paths(&self) -> PyResult<PyList> {
+ let mut inner = self.inner(py).borrow_mut();
let ret = PyList::new(py, &[]);
- for filename in res.iter() {
+ for filename in inner.non_normal_or_other_parent_paths() {
let as_pystring = PyBytes::new(py, filename.as_bytes());
ret.append(py, as_pystring.into_object());
}
@@ -253,7 +241,7 @@
NonNormalEntriesIterator::from_inner(py, unsafe {
leaked_ref.map(py, |o| {
- o.get_non_normal_other_parent_entries_panic().0.iter()
+ o.iter_non_normal_paths_panic()
})
})
}
--- a/rust/hg-cpython/src/dirstate/non_normal_entries.rs Tue Mar 30 14:15:23 2021 +0200
+++ b/rust/hg-cpython/src/dirstate/non_normal_entries.rs Thu Apr 08 14:58:44 2021 +0200
@@ -7,14 +7,13 @@
use cpython::{
exc::NotImplementedError, CompareOp, ObjectProtocol, PyBytes, PyClone,
- PyErr, PyList, PyObject, PyResult, PyString, Python, PythonObject,
- ToPyObject, UnsafePyLeaked,
+ PyErr, PyObject, PyResult, PyString, Python, PythonObject, ToPyObject,
+ UnsafePyLeaked,
};
use crate::dirstate::DirstateMap;
use hg::utils::hg_path::HgPathBuf;
use std::cell::RefCell;
-use std::collections::hash_set;
py_class!(pub class NonNormalEntries |py| {
data dmap: DirstateMap;
@@ -25,9 +24,6 @@
def remove(&self, key: PyObject) -> PyResult<PyObject> {
self.dmap(py).non_normal_entries_remove(py, key)
}
- def union(&self, other: PyObject) -> PyResult<PyList> {
- self.dmap(py).non_normal_entries_union(py, other)
- }
def __richcmp__(&self, other: PyObject, op: CompareOp) -> PyResult<bool> {
match op {
CompareOp::Eq => self.is_equal_to(py, other),
@@ -66,7 +62,8 @@
}
}
-type NonNormalEntriesIter<'a> = hash_set::Iter<'a, HgPathBuf>;
+type NonNormalEntriesIter<'a> =
+ Box<dyn Iterator<Item = &'a HgPathBuf> + Send + 'a>;
py_shared_iterator!(
NonNormalEntriesIterator,