dirstate-tree: Add map `get` and `contains_key` methods
Differential Revision: https://phab.mercurial-scm.org/D10369
--- a/rust/hg-core/src/dirstate_tree/dirstate_map.rs Tue Apr 06 14:29:05 2021 +0200
+++ b/rust/hg-core/src/dirstate_tree/dirstate_map.rs Tue Apr 06 14:35:39 2021 +0200
@@ -52,6 +52,22 @@
}
}
+ fn get_node(&self, path: &HgPath) -> Option<&Node> {
+ let mut children = &self.root;
+ let mut components = path.components();
+ let mut component =
+ components.next().expect("expected at least one components");
+ loop {
+ let child = children.get(component)?;
+ if let Some(next_component) = components.next() {
+ component = next_component;
+ children = &child.children;
+ } else {
+ return Some(child);
+ }
+ }
+ }
+
fn get_or_insert_node(&mut self, path: &HgPath) -> &mut Node {
let mut child_nodes = &mut self.root;
let mut inclusive_ancestor_paths =
@@ -265,12 +281,16 @@
todo!()
}
- fn copy_map_contains_key(&self, _key: &HgPath) -> bool {
- todo!()
+ fn copy_map_contains_key(&self, key: &HgPath) -> bool {
+ if let Some(node) = self.get_node(key) {
+ node.copy_source.is_some()
+ } else {
+ false
+ }
}
- fn copy_map_get(&self, _key: &HgPath) -> Option<&HgPathBuf> {
- todo!()
+ fn copy_map_get(&self, key: &HgPath) -> Option<&HgPathBuf> {
+ self.get_node(key)?.copy_source.as_ref()
}
fn copy_map_remove(&mut self, _key: &HgPath) -> Option<HgPathBuf> {
@@ -289,12 +309,12 @@
todo!()
}
- fn contains_key(&self, _key: &HgPath) -> bool {
- todo!()
+ fn contains_key(&self, key: &HgPath) -> bool {
+ self.get(key).is_some()
}
- fn get(&self, _key: &HgPath) -> Option<&DirstateEntry> {
- todo!()
+ fn get(&self, key: &HgPath) -> Option<&DirstateEntry> {
+ self.get_node(key)?.entry.as_ref()
}
fn iter(&self) -> StateMapIter<'_> {
--- a/rust/hg-core/src/utils/hg_path.rs Tue Apr 06 14:29:05 2021 +0200
+++ b/rust/hg-core/src/utils/hg_path.rs Tue Apr 06 14:35:39 2021 +0200
@@ -226,6 +226,11 @@
inner.extend(other.as_ref().bytes());
HgPathBuf::from_bytes(&inner)
}
+
+ pub fn components(&self) -> impl Iterator<Item = &HgPath> {
+ self.inner.split(|&byte| byte == b'/').map(HgPath::new)
+ }
+
pub fn parent(&self) -> &Self {
let inner = self.as_bytes();
HgPath::new(match inner.iter().rposition(|b| *b == b'/') {