Patchwork D10369: dirstate-tree: Add map `get` and `contains_key` methods

login
register
mail settings
Submitter phabricator
Date April 12, 2021, 12:24 p.m.
Message ID <differential-rev-PHID-DREV-35dfux7kcp4ceixzpe7u-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/48687/
State Superseded
Headers show

Comments

phabricator - April 12, 2021, 12:24 p.m.
SimonSapin created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D10369

AFFECTED FILES
  rust/hg-core/src/dirstate_tree/dirstate_map.rs
  rust/hg-core/src/utils/hg_path.rs

CHANGE DETAILS




To: SimonSapin, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/rust/hg-core/src/utils/hg_path.rs b/rust/hg-core/src/utils/hg_path.rs
--- a/rust/hg-core/src/utils/hg_path.rs
+++ b/rust/hg-core/src/utils/hg_path.rs
@@ -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'/') {
diff --git a/rust/hg-core/src/dirstate_tree/dirstate_map.rs b/rust/hg-core/src/dirstate_tree/dirstate_map.rs
--- a/rust/hg-core/src/dirstate_tree/dirstate_map.rs
+++ b/rust/hg-core/src/dirstate_tree/dirstate_map.rs
@@ -51,6 +51,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 =
@@ -262,12 +278,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> {
@@ -286,12 +306,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<'_> {