Made the map seek target a publicly implementable interface

Mikayla Maki and Nathan created

Integrated remove_range with the existing git code

co-authored-by: Nathan <nathan@zed.dev>

Change summary

crates/fs/src/repository.rs     | 16 +++++++++
crates/project/src/worktree.rs  |  6 +-
crates/sum_tree/src/sum_tree.rs |  4 +-
crates/sum_tree/src/tree_map.rs | 57 ++++++++++++++++------------------
4 files changed, 47 insertions(+), 36 deletions(-)

Detailed changes

crates/fs/src/repository.rs 🔗

@@ -3,12 +3,13 @@ use collections::HashMap;
 use parking_lot::Mutex;
 use serde_derive::{Deserialize, Serialize};
 use std::{
+    cmp::Ordering,
     ffi::OsStr,
     os::unix::prelude::OsStrExt,
     path::{Component, Path, PathBuf},
     sync::Arc,
 };
-use sum_tree::TreeMap;
+use sum_tree::{MapSeekTarget, TreeMap};
 use util::ResultExt;
 
 pub use git2::Repository as LibGitRepository;
@@ -233,3 +234,16 @@ impl std::ops::Deref for RepoPath {
         &self.0
     }
 }
+
+#[derive(Debug)]
+pub struct RepoPathDescendants<'a>(pub &'a Path);
+
+impl<'a> MapSeekTarget<RepoPath> for RepoPathDescendants<'a> {
+    fn cmp_cursor(&self, key: &RepoPath) -> Ordering {
+        if key.starts_with(&self.0) {
+            Ordering::Greater
+        } else {
+            self.0.cmp(key)
+        }
+    }
+}

crates/project/src/worktree.rs 🔗

@@ -7,7 +7,7 @@ use client::{proto, Client};
 use clock::ReplicaId;
 use collections::{HashMap, VecDeque};
 use fs::{
-    repository::{GitFileStatus, GitRepository, RepoPath},
+    repository::{GitFileStatus, GitRepository, RepoPath, RepoPathDescendants},
     Fs, LineEnding,
 };
 use futures::{
@@ -54,7 +54,7 @@ use std::{
     },
     time::{Duration, SystemTime},
 };
-use sum_tree::{Bias, Edit, SeekTarget, SumTree, TreeMap, TreeSet, PathDescendants};
+use sum_tree::{Bias, Edit, SeekTarget, SumTree, TreeMap, TreeSet};
 use util::{paths::HOME, ResultExt, TakeUntilExt, TryFutureExt};
 
 #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, PartialOrd, Ord)]
@@ -3023,7 +3023,7 @@ impl BackgroundScanner {
             snapshot.repository_entries.update(&work_dir, |entry| {
                 entry
                     .worktree_statuses
-                    .remove_range(&repo_path, &PathDescendants(&repo_path))
+                    .remove_range(&repo_path, &RepoPathDescendants(&repo_path))
             });
         }
 

crates/sum_tree/src/sum_tree.rs 🔗

@@ -5,7 +5,7 @@ use arrayvec::ArrayVec;
 pub use cursor::{Cursor, FilterCursor, Iter};
 use std::marker::PhantomData;
 use std::{cmp::Ordering, fmt, iter::FromIterator, sync::Arc};
-pub use tree_map::{TreeMap, TreeSet, PathDescendants};
+pub use tree_map::{MapSeekTarget, TreeMap, TreeSet};
 
 #[cfg(test)]
 const TREE_BASE: usize = 2;
@@ -47,7 +47,7 @@ impl<'a, T: Summary> Dimension<'a, T> for T {
 }
 
 pub trait SeekTarget<'a, S: Summary, D: Dimension<'a, S>>: fmt::Debug {
-   fn cmp(&self, cursor_location: &D, cx: &S::Context) -> Ordering;
+    fn cmp(&self, cursor_location: &D, cx: &S::Context) -> Ordering;
 }
 
 impl<'a, S: Summary, D: Dimension<'a, S> + Ord> SeekTarget<'a, S, D> for D {

crates/sum_tree/src/tree_map.rs 🔗

@@ -1,8 +1,4 @@
-use std::{
-    cmp::Ordering,
-    fmt::Debug,
-    path::{Path, PathBuf},
-};
+use std::{cmp::Ordering, fmt::Debug};
 
 use crate::{Bias, Dimension, Edit, Item, KeyedItem, SeekTarget, SumTree, Summary};
 
@@ -173,38 +169,21 @@ impl<'a, K: Debug + Clone + Default + Ord, T: MapSeekTarget<K>>
     SeekTarget<'a, MapKey<K>, MapKeyRef<'a, K>> for MapSeekTargetAdaptor<'_, T>
 {
     fn cmp(&self, cursor_location: &MapKeyRef<K>, _: &()) -> Ordering {
-        MapSeekTarget::cmp(self.0, cursor_location)
-    }
-}
-
-pub trait MapSeekTarget<K>: Debug {
-    fn cmp(&self, cursor_location: &MapKeyRef<K>) -> Ordering;
-}
-
-impl<K: Debug + Ord> MapSeekTarget<K> for K {
-    fn cmp(&self, cursor_location: &MapKeyRef<K>) -> Ordering {
         if let Some(key) = &cursor_location.0 {
-            self.cmp(key)
+            MapSeekTarget::cmp_cursor(self.0, key)
         } else {
             Ordering::Greater
         }
     }
 }
 
-#[derive(Debug)]
-pub struct PathDescendants<'a>(&'a Path);
+pub trait MapSeekTarget<K>: Debug {
+    fn cmp_cursor(&self, cursor_location: &K) -> Ordering;
+}
 
-impl MapSeekTarget<PathBuf> for PathDescendants<'_> {
-    fn cmp(&self, cursor_location: &MapKeyRef<PathBuf>) -> Ordering {
-        if let Some(key) = &cursor_location.0 {
-            if key.starts_with(&self.0) {
-                Ordering::Greater
-            } else {
-                self.0.cmp(key)
-            }
-        } else {
-            Ordering::Greater
-        }
+impl<K: Debug + Ord> MapSeekTarget<K> for K {
+    fn cmp_cursor(&self, cursor_location: &K) -> Ordering {
+        self.cmp(cursor_location)
     }
 }
 
@@ -405,6 +384,21 @@ mod tests {
 
     #[test]
     fn test_remove_between_and_path_successor() {
+        use std::path::{Path, PathBuf};
+
+        #[derive(Debug)]
+        pub struct PathDescendants<'a>(&'a Path);
+
+        impl MapSeekTarget<PathBuf> for PathDescendants<'_> {
+            fn cmp_cursor(&self, key: &PathBuf) -> Ordering {
+                if key.starts_with(&self.0) {
+                    Ordering::Greater
+                } else {
+                    self.0.cmp(key)
+                }
+            }
+        }
+
         let mut map = TreeMap::default();
 
         map.insert(PathBuf::from("a"), 1);
@@ -415,7 +409,10 @@ mod tests {
         map.insert(PathBuf::from("c"), 5);
         map.insert(PathBuf::from("c/a"), 6);
 
-        map.remove_range(&PathBuf::from("b/a"), &PathDescendants(&PathBuf::from("b/a")));
+        map.remove_range(
+            &PathBuf::from("b/a"),
+            &PathDescendants(&PathBuf::from("b/a")),
+        );
 
         assert_eq!(map.get(&PathBuf::from("a")), Some(&1));
         assert_eq!(map.get(&PathBuf::from("a/a")), Some(&1));