mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-30 14:17:02 +00:00
Switch worktree entries to HashMap
This commit is contained in:
parent
3803eb85a5
commit
cdfd61369e
1 changed files with 37 additions and 31 deletions
|
@ -33,7 +33,7 @@ pub struct Worktree(Arc<RwLock<WorktreeState>>);
|
||||||
struct WorktreeState {
|
struct WorktreeState {
|
||||||
id: usize,
|
id: usize,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
entries: Vec<Entry>,
|
entries: HashMap<usize, Entry>,
|
||||||
file_paths: Vec<PathEntry>,
|
file_paths: Vec<PathEntry>,
|
||||||
histories: HashMap<usize, History>,
|
histories: HashMap<usize, History>,
|
||||||
scanning: bool,
|
scanning: bool,
|
||||||
|
@ -55,7 +55,7 @@ impl Worktree {
|
||||||
let tree = Self(Arc::new(RwLock::new(WorktreeState {
|
let tree = Self(Arc::new(RwLock::new(WorktreeState {
|
||||||
id,
|
id,
|
||||||
path: path.into(),
|
path: path.into(),
|
||||||
entries: Vec::new(),
|
entries: HashMap::new(),
|
||||||
file_paths: Vec::new(),
|
file_paths: Vec::new(),
|
||||||
histories: HashMap::new(),
|
histories: HashMap::new(),
|
||||||
scanning: ctx.is_some(),
|
scanning: ctx.is_some(),
|
||||||
|
@ -102,7 +102,7 @@ impl Worktree {
|
||||||
|
|
||||||
if metadata.file_type().is_dir() {
|
if metadata.file_type().is_dir() {
|
||||||
let is_ignored = is_ignored || name == ".git";
|
let is_ignored = is_ignored || name == ".git";
|
||||||
let id = self.push_dir(None, name, ino, is_symlink, is_ignored);
|
let id = self.insert_dir(None, name, ino, is_symlink, is_ignored);
|
||||||
let (tx, rx) = channel::unbounded();
|
let (tx, rx) = channel::unbounded();
|
||||||
|
|
||||||
tx.send(Ok(DirToScan {
|
tx.send(Ok(DirToScan {
|
||||||
|
@ -110,7 +110,6 @@ impl Worktree {
|
||||||
path,
|
path,
|
||||||
relative_path,
|
relative_path,
|
||||||
ignore: Some(ignore),
|
ignore: Some(ignore),
|
||||||
dirs_to_scan: tx_,
|
|
||||||
dirs_to_scan: tx.clone(),
|
dirs_to_scan: tx.clone(),
|
||||||
}))
|
}))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -127,7 +126,7 @@ impl Worktree {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect::<io::Result<()>>()?;
|
.collect::<io::Result<()>>()?;
|
||||||
} else {
|
} else {
|
||||||
self.push_file(None, name, ino, is_symlink, is_ignored, relative_path);
|
self.insert_file(None, name, ino, is_symlink, is_ignored, relative_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -157,7 +156,7 @@ impl Worktree {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let id = self.push_dir(Some(to_scan.id), name, ino, is_symlink, is_ignored);
|
let id = self.insert_dir(Some(to_scan.id), name, ino, is_symlink, is_ignored);
|
||||||
new_children.push(id);
|
new_children.push(id);
|
||||||
|
|
||||||
let dirs_to_scan = to_scan.dirs_to_scan.clone();
|
let dirs_to_scan = to_scan.dirs_to_scan.clone();
|
||||||
|
@ -173,7 +172,7 @@ impl Worktree {
|
||||||
i.matched(to_scan.path.join(&name), false).is_ignore()
|
i.matched(to_scan.path.join(&name), false).is_ignore()
|
||||||
});
|
});
|
||||||
|
|
||||||
new_children.push(self.push_file(
|
new_children.push(self.insert_file(
|
||||||
Some(to_scan.id),
|
Some(to_scan.id),
|
||||||
name,
|
name,
|
||||||
ino,
|
ino,
|
||||||
|
@ -184,14 +183,15 @@ impl Worktree {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Entry::Dir { children, .. } = &mut self.0.write().entries[to_scan.id] {
|
if let Some(Entry::Dir { children, .. }) = &mut self.0.write().entries.get_mut(&to_scan.id)
|
||||||
|
{
|
||||||
*children = new_children.clone();
|
*children = new_children.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_dir(
|
fn insert_dir(
|
||||||
&self,
|
&self,
|
||||||
parent: Option<usize>,
|
parent: Option<usize>,
|
||||||
name: OsString,
|
name: OsString,
|
||||||
|
@ -201,18 +201,21 @@ impl Worktree {
|
||||||
) -> usize {
|
) -> usize {
|
||||||
let entries = &mut self.0.write().entries;
|
let entries = &mut self.0.write().entries;
|
||||||
let dir_id = entries.len();
|
let dir_id = entries.len();
|
||||||
entries.push(Entry::Dir {
|
entries.insert(
|
||||||
parent,
|
dir_id,
|
||||||
name,
|
Entry::Dir {
|
||||||
ino,
|
parent,
|
||||||
is_symlink,
|
name,
|
||||||
is_ignored,
|
ino,
|
||||||
children: Vec::new(),
|
is_symlink,
|
||||||
});
|
is_ignored,
|
||||||
|
children: Vec::new(),
|
||||||
|
},
|
||||||
|
);
|
||||||
dir_id
|
dir_id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_file(
|
fn insert_file(
|
||||||
&self,
|
&self,
|
||||||
parent: Option<usize>,
|
parent: Option<usize>,
|
||||||
name: OsString,
|
name: OsString,
|
||||||
|
@ -228,13 +231,16 @@ impl Worktree {
|
||||||
|
|
||||||
let mut state = self.0.write();
|
let mut state = self.0.write();
|
||||||
let entry_id = state.entries.len();
|
let entry_id = state.entries.len();
|
||||||
state.entries.push(Entry::File {
|
state.entries.insert(
|
||||||
parent,
|
entry_id,
|
||||||
name,
|
Entry::File {
|
||||||
ino,
|
parent,
|
||||||
is_symlink,
|
name,
|
||||||
is_ignored,
|
ino,
|
||||||
});
|
is_symlink,
|
||||||
|
is_ignored,
|
||||||
|
},
|
||||||
|
);
|
||||||
state.file_paths.push(PathEntry {
|
state.file_paths.push(PathEntry {
|
||||||
entry_id,
|
entry_id,
|
||||||
path_chars,
|
path_chars,
|
||||||
|
@ -254,7 +260,7 @@ impl Worktree {
|
||||||
|
|
||||||
let mut entries = Vec::new();
|
let mut entries = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
let entry = &state.entries[entry_id];
|
let entry = &state.entries[&entry_id];
|
||||||
entries.push(entry);
|
entries.push(entry);
|
||||||
if let Some(parent_id) = entry.parent() {
|
if let Some(parent_id) = entry.parent() {
|
||||||
entry_id = parent_id;
|
entry_id = parent_id;
|
||||||
|
@ -277,7 +283,7 @@ impl Worktree {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fmt_entry(&self, f: &mut fmt::Formatter<'_>, entry_id: usize, indent: usize) -> fmt::Result {
|
fn fmt_entry(&self, f: &mut fmt::Formatter<'_>, entry_id: usize, indent: usize) -> fmt::Result {
|
||||||
match &self.0.read().entries[entry_id] {
|
match &self.0.read().entries[&entry_id] {
|
||||||
Entry::Dir { name, children, .. } => {
|
Entry::Dir { name, children, .. } => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
|
@ -498,7 +504,7 @@ impl Iterator for Iter {
|
||||||
if !self.started {
|
if !self.started {
|
||||||
self.started = true;
|
self.started = true;
|
||||||
|
|
||||||
return if let Some(entry) = state.entries.first().cloned() {
|
return if let Some(entry) = state.entries.get(&0).cloned() {
|
||||||
self.stack.push(IterStackEntry {
|
self.stack.push(IterStackEntry {
|
||||||
entry_id: 0,
|
entry_id: 0,
|
||||||
child_idx: 0,
|
child_idx: 0,
|
||||||
|
@ -511,7 +517,7 @@ impl Iterator for Iter {
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Some(parent) = self.stack.last_mut() {
|
while let Some(parent) = self.stack.last_mut() {
|
||||||
if let Entry::Dir { children, .. } = &state.entries[parent.entry_id] {
|
if let Entry::Dir { children, .. } = &state.entries[&parent.entry_id] {
|
||||||
if parent.child_idx < children.len() {
|
if parent.child_idx < children.len() {
|
||||||
let child_id = children[post_inc(&mut parent.child_idx)];
|
let child_id = children[post_inc(&mut parent.child_idx)];
|
||||||
|
|
||||||
|
@ -522,7 +528,7 @@ impl Iterator for Iter {
|
||||||
|
|
||||||
return Some(Traversal::Push {
|
return Some(Traversal::Push {
|
||||||
entry_id: child_id,
|
entry_id: child_id,
|
||||||
entry: state.entries[child_id].clone(),
|
entry: state.entries[&child_id].clone(),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
self.stack.pop();
|
self.stack.pop();
|
||||||
|
@ -614,7 +620,7 @@ pub fn match_paths(
|
||||||
.iter()
|
.iter()
|
||||||
.map(|tree| {
|
.map(|tree| {
|
||||||
let skip_prefix = if trees.len() == 1 {
|
let skip_prefix = if trees.len() == 1 {
|
||||||
if let Some(Entry::Dir { name, .. }) = tree.entries.get(0) {
|
if let Some(Entry::Dir { name, .. }) = tree.entries.get(&0) {
|
||||||
let name = name.to_string_lossy();
|
let name = name.to_string_lossy();
|
||||||
if name == "/" {
|
if name == "/" {
|
||||||
1
|
1
|
||||||
|
|
Loading…
Reference in a new issue