mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-11 05:00:16 +00:00
WIP: Start on updating file handles
Co-Authored-By: Max Brunsfeld <max@zed.dev> Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
111d98d6c1
commit
6535304da8
2 changed files with 46 additions and 15 deletions
|
@ -429,7 +429,7 @@ impl Buffer {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn path(&self) -> Option<&Arc<Path>> {
|
||||
pub fn path(&self) -> Option<Arc<Path>> {
|
||||
self.file.as_ref().map(|file| file.path())
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ use std::{
|
|||
ops::{AddAssign, Deref},
|
||||
os::unix::{ffi::OsStrExt, fs::MetadataExt},
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
sync::{Arc, Weak},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
|
@ -47,6 +47,7 @@ enum ScanState {
|
|||
pub struct Worktree {
|
||||
snapshot: Snapshot,
|
||||
background_snapshot: Arc<Mutex<Snapshot>>,
|
||||
handles: Arc<Mutex<HashMap<Arc<Path>, Weak<Mutex<FileHandleState>>>>>,
|
||||
scan_state: (watch::Sender<ScanState>, watch::Receiver<ScanState>),
|
||||
_event_stream_handle: fsevent::Handle,
|
||||
poll_scheduled: bool,
|
||||
|
@ -55,7 +56,12 @@ pub struct Worktree {
|
|||
#[derive(Clone)]
|
||||
pub struct FileHandle {
|
||||
worktree: ModelHandle<Worktree>,
|
||||
state: Arc<Mutex<FileHandleState>>,
|
||||
}
|
||||
|
||||
struct FileHandleState {
|
||||
path: Arc<Path>,
|
||||
is_deleted: bool,
|
||||
}
|
||||
|
||||
impl Worktree {
|
||||
|
@ -78,17 +84,19 @@ impl Worktree {
|
|||
fsevent::EventStream::new(&[snapshot.abs_path.as_ref()], Duration::from_millis(100));
|
||||
|
||||
let background_snapshot = Arc::new(Mutex::new(snapshot.clone()));
|
||||
let handles = Arc::new(Mutex::new(Default::default()));
|
||||
|
||||
let tree = Self {
|
||||
snapshot,
|
||||
background_snapshot: background_snapshot.clone(),
|
||||
handles: handles.clone(),
|
||||
scan_state: watch::channel_with(ScanState::Scanning),
|
||||
_event_stream_handle: event_stream_handle,
|
||||
poll_scheduled: false,
|
||||
};
|
||||
|
||||
std::thread::spawn(move || {
|
||||
let scanner = BackgroundScanner::new(background_snapshot, scan_state_tx, id);
|
||||
let scanner = BackgroundScanner::new(background_snapshot, handles, scan_state_tx, id);
|
||||
scanner.run(event_stream)
|
||||
});
|
||||
|
||||
|
@ -374,21 +382,21 @@ impl fmt::Debug for Snapshot {
|
|||
}
|
||||
|
||||
impl FileHandle {
|
||||
pub fn path(&self) -> &Arc<Path> {
|
||||
&self.path
|
||||
pub fn path(&self) -> Arc<Path> {
|
||||
self.state.lock().path.clone()
|
||||
}
|
||||
|
||||
pub fn load_history(&self, ctx: &AppContext) -> impl Future<Output = Result<History>> {
|
||||
self.worktree.read(ctx).load_history(&self.path, ctx)
|
||||
self.worktree.read(ctx).load_history(&self.path(), ctx)
|
||||
}
|
||||
|
||||
pub fn save<'a>(&self, content: BufferSnapshot, ctx: &AppContext) -> Task<Result<()>> {
|
||||
let worktree = self.worktree.read(ctx);
|
||||
worktree.save(&self.path, content, ctx)
|
||||
worktree.save(&self.path(), content, ctx)
|
||||
}
|
||||
|
||||
pub fn entry_id(&self) -> (usize, Arc<Path>) {
|
||||
(self.worktree.id(), self.path.clone())
|
||||
(self.worktree.id(), self.path())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -561,18 +569,25 @@ impl<'a> sum_tree::Dimension<'a, EntrySummary> for VisibleFileCount {
|
|||
struct BackgroundScanner {
|
||||
snapshot: Arc<Mutex<Snapshot>>,
|
||||
notify: Sender<ScanState>,
|
||||
handles: Arc<Mutex<HashMap<Arc<Path>, Weak<Mutex<FileHandleState>>>>>,
|
||||
other_mount_paths: HashSet<PathBuf>,
|
||||
thread_pool: scoped_pool::Pool,
|
||||
root_char_bag: CharBag,
|
||||
}
|
||||
|
||||
impl BackgroundScanner {
|
||||
fn new(snapshot: Arc<Mutex<Snapshot>>, notify: Sender<ScanState>, worktree_id: usize) -> Self {
|
||||
fn new(
|
||||
snapshot: Arc<Mutex<Snapshot>>,
|
||||
handles: Arc<Mutex<HashMap<Arc<Path>, Weak<Mutex<FileHandleState>>>>>,
|
||||
notify: Sender<ScanState>,
|
||||
worktree_id: usize,
|
||||
) -> Self {
|
||||
let root_char_bag = CharBag::from(snapshot.lock().root_name_chars.as_slice());
|
||||
let mut scanner = Self {
|
||||
root_char_bag,
|
||||
snapshot,
|
||||
notify,
|
||||
handles,
|
||||
other_mount_paths: Default::default(),
|
||||
thread_pool: scoped_pool::Pool::new(16, format!("worktree-{}-scanner", worktree_id)),
|
||||
};
|
||||
|
@ -997,13 +1012,27 @@ pub trait WorktreeHandle {
|
|||
|
||||
impl WorktreeHandle for ModelHandle<Worktree> {
|
||||
fn file(&self, path: impl AsRef<Path>, app: &AppContext) -> Result<FileHandle> {
|
||||
self.read(app)
|
||||
let tree = self.read(app);
|
||||
let entry = tree
|
||||
.entry_for_path(&path)
|
||||
.map(|entry| FileHandle {
|
||||
worktree: self.clone(),
|
||||
path: entry.path().clone(),
|
||||
})
|
||||
.ok_or_else(|| anyhow!("path does not exist in tree"))
|
||||
.ok_or_else(|| anyhow!("path does not exist in tree"))?;
|
||||
let path = entry.path().clone();
|
||||
let mut handles = tree.handles.lock();
|
||||
let state = if let Some(state) = handles.get(&path).and_then(Weak::upgrade) {
|
||||
state
|
||||
} else {
|
||||
let state = Arc::new(Mutex::new(FileHandleState {
|
||||
path: path.clone(),
|
||||
is_deleted: false,
|
||||
}));
|
||||
handles.insert(path, Arc::downgrade(&state));
|
||||
state
|
||||
};
|
||||
|
||||
Ok(FileHandle {
|
||||
worktree: self.clone(),
|
||||
state,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1329,6 +1358,7 @@ mod tests {
|
|||
ignores: Default::default(),
|
||||
root_name_chars: Default::default(),
|
||||
})),
|
||||
Arc::new(Mutex::new(Default::default())),
|
||||
notify_tx,
|
||||
0,
|
||||
);
|
||||
|
@ -1363,6 +1393,7 @@ mod tests {
|
|||
ignores: Default::default(),
|
||||
root_name_chars: Default::default(),
|
||||
})),
|
||||
Arc::new(Mutex::new(Default::default())),
|
||||
notify_tx,
|
||||
1,
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue