From 2a1afad3eda7d8c5635de6e7f524ed943cecc22b Mon Sep 17 00:00:00 2001 From: Bernardo Date: Mon, 21 Jan 2019 19:11:39 +0100 Subject: avoid boxing --- crates/ra_vfs/src/io/mod.rs | 45 ++++++++++++++++++++++++++++++----------- crates/ra_vfs/src/io/watcher.rs | 16 +++++++-------- crates/ra_vfs/src/lib.rs | 17 ++++------------ 3 files changed, 44 insertions(+), 34 deletions(-) diff --git a/crates/ra_vfs/src/io/mod.rs b/crates/ra_vfs/src/io/mod.rs index 6d5af7690..daac6c6f2 100644 --- a/crates/ra_vfs/src/io/mod.rs +++ b/crates/ra_vfs/src/io/mod.rs @@ -9,26 +9,27 @@ use crossbeam_channel::{Receiver, Sender}; use parking_lot::Mutex; use relative_path::RelativePathBuf; use thread_worker::WorkerHandle; -use walkdir::{DirEntry, WalkDir}; +use walkdir::WalkDir; mod watcher; use watcher::Watcher; pub use watcher::WatcherChange; -use crate::VfsRoot; +use crate::{RootFilter, VfsRoot}; pub(crate) enum Task { AddRoot { root: VfsRoot, path: PathBuf, - filter: Box bool + Send>, + root_filter: Arc, + nested_roots: Vec, }, /// this variant should only be created by the watcher HandleChange(WatcherChange), LoadChange(WatcherChange), Watch { dir: PathBuf, - filter: Box bool + Send>, + root_filter: Arc, }, } @@ -109,7 +110,7 @@ impl Worker { fn watch( watcher: &Arc>>, dir: &Path, - filter_entry: impl Fn(&DirEntry) -> bool, + filter_entry: &RootFilter, emit_for_existing: bool, ) { let mut watcher = watcher.lock(); @@ -125,10 +126,19 @@ fn watch( fn handle_task(task: Task, watcher: &Arc>>) -> TaskResult { match task { - Task::AddRoot { root, path, filter } => { - watch(watcher, &path, &*filter, false); + Task::AddRoot { + root, + path, + root_filter, + nested_roots, + } => { + watch(watcher, &path, &*root_filter, false); log::debug!("loading {} ...", path.as_path().display()); - let files = load_root(path.as_path(), &*filter); + let files = load_root( + path.as_path(), + root_filter.as_ref(), + nested_roots.as_slice(), + ); log::debug!("... loaded {}", path.as_path().display()); TaskResult::AddRoot(AddRootResult { root, files }) } @@ -143,16 +153,27 @@ fn handle_task(task: Task, watcher: &Arc>>) -> TaskResult None => TaskResult::NoOp, } } - Task::Watch { dir, filter } => { - watch(watcher, &dir, &*filter, true); + Task::Watch { dir, root_filter } => { + watch(watcher, &dir, root_filter.as_ref(), true); TaskResult::NoOp } } } -fn load_root(root: &Path, filter: &dyn Fn(&DirEntry) -> bool) -> Vec<(RelativePathBuf, String)> { +fn load_root( + root: &Path, + root_filter: &RootFilter, + nested_roots: &[PathBuf], +) -> Vec<(RelativePathBuf, String)> { let mut res = Vec::new(); - for entry in WalkDir::new(root).into_iter().filter_entry(filter) { + for entry in WalkDir::new(root).into_iter().filter_entry(|entry| { + if entry.file_type().is_dir() && nested_roots.iter().any(|it| it == entry.path()) { + // do not load files of a nested root + false + } else { + root_filter.can_contain(entry.path()).is_some() + } + }) { let entry = match entry { Ok(entry) => entry, Err(e) => { diff --git a/crates/ra_vfs/src/io/watcher.rs b/crates/ra_vfs/src/io/watcher.rs index e33298477..5e9bc8ff3 100644 --- a/crates/ra_vfs/src/io/watcher.rs +++ b/crates/ra_vfs/src/io/watcher.rs @@ -1,4 +1,4 @@ -use crate::io; +use crate::{io, RootFilter}; use crossbeam_channel::Sender; use drop_bomb::DropBomb; use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher as NotifyWatcher}; @@ -8,7 +8,7 @@ use std::{ thread, time::Duration, }; -use walkdir::{DirEntry, WalkDir}; +use walkdir::WalkDir; #[derive(Debug)] pub enum WatcherChange { @@ -83,13 +83,11 @@ impl Watcher { }) } - pub fn watch_recursive( - &mut self, - dir: &Path, - filter_entry: impl Fn(&DirEntry) -> bool, - emit_for_contents: bool, - ) { - for res in WalkDir::new(dir).into_iter().filter_entry(filter_entry) { + pub fn watch_recursive(&mut self, dir: &Path, filter: &RootFilter, emit_for_contents: bool) { + for res in WalkDir::new(dir) + .into_iter() + .filter_entry(|entry| filter.can_contain(entry.path()).is_some()) + { match res { Ok(entry) => { if entry.path().is_dir() { diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs index 5db0d8646..1d0af6a09 100644 --- a/crates/ra_vfs/src/lib.rs +++ b/crates/ra_vfs/src/lib.rs @@ -28,7 +28,6 @@ use crossbeam_channel::Receiver; use ra_arena::{impl_arena_id, Arena, RawId}; use relative_path::RelativePathBuf; use rustc_hash::{FxHashMap, FxHashSet}; -use walkdir::DirEntry; pub use crate::io::TaskResult as VfsTask; use io::{Task, TaskResult, WatcherChange, WatcherChangeData, Worker}; @@ -128,23 +127,17 @@ impl Vfs { let root = res.roots.alloc(root_filter.clone()); res.root2files.insert(root, Default::default()); - let nested = roots[..i] + let nested_roots = roots[..i] .iter() .filter(|it| it.starts_with(path)) .map(|it| it.clone()) .collect::>(); - let filter = move |entry: &DirEntry| { - if entry.file_type().is_dir() && nested.iter().any(|it| it == entry.path()) { - false - } else { - root_filter.can_contain(entry.path()).is_some() - } - }; let task = io::Task::AddRoot { root, path: path.clone(), - filter: Box::new(filter), + root_filter, + nested_roots, }; res.worker.sender().send(task).unwrap(); } @@ -232,13 +225,11 @@ impl Vfs { WatcherChange::Create(path) if path.is_dir() => { if let Some((root, _path, _file)) = self.find_root(&path) { let root_filter = self.roots[root].clone(); - let filter = - move |entry: &DirEntry| root_filter.can_contain(entry.path()).is_some(); self.worker .sender() .send(Task::Watch { dir: path.to_path_buf(), - filter: Box::new(filter), + root_filter, }) .unwrap() } -- cgit v1.2.3