diff --git a/zed/src/worktree/worktree.rs b/zed/src/worktree/worktree.rs index 261487bd2f..dea9c1bcdb 100644 --- a/zed/src/worktree/worktree.rs +++ b/zed/src/worktree/worktree.rs @@ -33,7 +33,7 @@ pub struct Worktree(Arc>); struct WorktreeState { id: usize, path: PathBuf, - entries: Vec, + entries: HashMap, file_paths: Vec, histories: HashMap, scanning: bool, @@ -55,7 +55,7 @@ impl Worktree { let tree = Self(Arc::new(RwLock::new(WorktreeState { id, path: path.into(), - entries: Vec::new(), + entries: HashMap::new(), file_paths: Vec::new(), histories: HashMap::new(), scanning: ctx.is_some(), @@ -102,7 +102,7 @@ impl Worktree { if metadata.file_type().is_dir() { 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(); tx.send(Ok(DirToScan { @@ -110,7 +110,6 @@ impl Worktree { path, relative_path, ignore: Some(ignore), - dirs_to_scan: tx_, dirs_to_scan: tx.clone(), })) .unwrap(); @@ -127,7 +126,7 @@ impl Worktree { .into_iter() .collect::>()?; } 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(()) @@ -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); 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() }); - new_children.push(self.push_file( + new_children.push(self.insert_file( Some(to_scan.id), name, 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(); } Ok(()) } - fn push_dir( + fn insert_dir( &self, parent: Option, name: OsString, @@ -201,18 +201,21 @@ impl Worktree { ) -> usize { let entries = &mut self.0.write().entries; let dir_id = entries.len(); - entries.push(Entry::Dir { - parent, - name, - ino, - is_symlink, - is_ignored, - children: Vec::new(), - }); + entries.insert( + dir_id, + Entry::Dir { + parent, + name, + ino, + is_symlink, + is_ignored, + children: Vec::new(), + }, + ); dir_id } - fn push_file( + fn insert_file( &self, parent: Option, name: OsString, @@ -228,13 +231,16 @@ impl Worktree { let mut state = self.0.write(); let entry_id = state.entries.len(); - state.entries.push(Entry::File { - parent, - name, - ino, - is_symlink, - is_ignored, - }); + state.entries.insert( + entry_id, + Entry::File { + parent, + name, + ino, + is_symlink, + is_ignored, + }, + ); state.file_paths.push(PathEntry { entry_id, path_chars, @@ -254,7 +260,7 @@ impl Worktree { let mut entries = Vec::new(); loop { - let entry = &state.entries[entry_id]; + let entry = &state.entries[&entry_id]; entries.push(entry); if let Some(parent_id) = entry.parent() { 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 { - match &self.0.read().entries[entry_id] { + match &self.0.read().entries[&entry_id] { Entry::Dir { name, children, .. } => { write!( f, @@ -498,7 +504,7 @@ impl Iterator for Iter { if !self.started { 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 { entry_id: 0, child_idx: 0, @@ -511,7 +517,7 @@ impl Iterator for Iter { } 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() { let child_id = children[post_inc(&mut parent.child_idx)]; @@ -522,7 +528,7 @@ impl Iterator for Iter { return Some(Traversal::Push { entry_id: child_id, - entry: state.entries[child_id].clone(), + entry: state.entries[&child_id].clone(), }); } else { self.stack.pop(); @@ -614,7 +620,7 @@ pub fn match_paths( .iter() .map(|tree| { 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(); if name == "/" { 1