Made the map seek target a publicly implementable interface
Integrated remove_range with the existing git code co-authored-by: Nathan <nathan@zed.dev>
This commit is contained in:
parent
ee3637216e
commit
6ef0f70528
4 changed files with 48 additions and 37 deletions
|
@ -3,12 +3,13 @@ use collections::HashMap;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
|
cmp::Ordering,
|
||||||
ffi::OsStr,
|
ffi::OsStr,
|
||||||
os::unix::prelude::OsStrExt,
|
os::unix::prelude::OsStrExt,
|
||||||
path::{Component, Path, PathBuf},
|
path::{Component, Path, PathBuf},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
use sum_tree::TreeMap;
|
use sum_tree::{MapSeekTarget, TreeMap};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
|
||||||
pub use git2::Repository as LibGitRepository;
|
pub use git2::Repository as LibGitRepository;
|
||||||
|
@ -233,3 +234,16 @@ impl std::ops::Deref for RepoPath {
|
||||||
&self.0
|
&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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use client::{proto, Client};
|
||||||
use clock::ReplicaId;
|
use clock::ReplicaId;
|
||||||
use collections::{HashMap, VecDeque};
|
use collections::{HashMap, VecDeque};
|
||||||
use fs::{
|
use fs::{
|
||||||
repository::{GitFileStatus, GitRepository, RepoPath},
|
repository::{GitFileStatus, GitRepository, RepoPath, RepoPathDescendants},
|
||||||
Fs, LineEnding,
|
Fs, LineEnding,
|
||||||
};
|
};
|
||||||
use futures::{
|
use futures::{
|
||||||
|
@ -54,7 +54,7 @@ use std::{
|
||||||
},
|
},
|
||||||
time::{Duration, SystemTime},
|
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};
|
use util::{paths::HOME, ResultExt, TakeUntilExt, TryFutureExt};
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, PartialOrd, Ord)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, PartialOrd, Ord)]
|
||||||
|
@ -3023,7 +3023,7 @@ impl BackgroundScanner {
|
||||||
snapshot.repository_entries.update(&work_dir, |entry| {
|
snapshot.repository_entries.update(&work_dir, |entry| {
|
||||||
entry
|
entry
|
||||||
.worktree_statuses
|
.worktree_statuses
|
||||||
.remove_range(&repo_path, &PathDescendants(&repo_path))
|
.remove_range(&repo_path, &RepoPathDescendants(&repo_path))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ use arrayvec::ArrayVec;
|
||||||
pub use cursor::{Cursor, FilterCursor, Iter};
|
pub use cursor::{Cursor, FilterCursor, Iter};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::{cmp::Ordering, fmt, iter::FromIterator, sync::Arc};
|
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)]
|
#[cfg(test)]
|
||||||
const TREE_BASE: usize = 2;
|
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 {
|
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 {
|
impl<'a, S: Summary, D: Dimension<'a, S> + Ord> SeekTarget<'a, S, D> for D {
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
use std::{
|
use std::{cmp::Ordering, fmt::Debug};
|
||||||
cmp::Ordering,
|
|
||||||
fmt::Debug,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{Bias, Dimension, Edit, Item, KeyedItem, SeekTarget, SumTree, Summary};
|
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>
|
SeekTarget<'a, MapKey<K>, MapKeyRef<'a, K>> for MapSeekTargetAdaptor<'_, T>
|
||||||
{
|
{
|
||||||
fn cmp(&self, cursor_location: &MapKeyRef<K>, _: &()) -> Ordering {
|
fn cmp(&self, cursor_location: &MapKeyRef<K>, _: &()) -> Ordering {
|
||||||
MapSeekTarget::cmp(self.0, cursor_location)
|
if let Some(key) = &cursor_location.0 {
|
||||||
|
MapSeekTarget::cmp_cursor(self.0, key)
|
||||||
|
} else {
|
||||||
|
Ordering::Greater
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait MapSeekTarget<K>: Debug {
|
pub trait MapSeekTarget<K>: Debug {
|
||||||
fn cmp(&self, cursor_location: &MapKeyRef<K>) -> Ordering;
|
fn cmp_cursor(&self, cursor_location: &K) -> Ordering;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: Debug + Ord> MapSeekTarget<K> for K {
|
impl<K: Debug + Ord> MapSeekTarget<K> for K {
|
||||||
fn cmp(&self, cursor_location: &MapKeyRef<K>) -> Ordering {
|
fn cmp_cursor(&self, cursor_location: &K) -> Ordering {
|
||||||
if let Some(key) = &cursor_location.0 {
|
self.cmp(cursor_location)
|
||||||
self.cmp(key)
|
|
||||||
} else {
|
|
||||||
Ordering::Greater
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct PathDescendants<'a>(&'a Path);
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,6 +384,21 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_remove_between_and_path_successor() {
|
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();
|
let mut map = TreeMap::default();
|
||||||
|
|
||||||
map.insert(PathBuf::from("a"), 1);
|
map.insert(PathBuf::from("a"), 1);
|
||||||
|
@ -415,7 +409,10 @@ mod tests {
|
||||||
map.insert(PathBuf::from("c"), 5);
|
map.insert(PathBuf::from("c"), 5);
|
||||||
map.insert(PathBuf::from("c/a"), 6);
|
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")), Some(&1));
|
||||||
assert_eq!(map.get(&PathBuf::from("a/a")), Some(&1));
|
assert_eq!(map.get(&PathBuf::from("a/a")), Some(&1));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue