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 +++++++-------- 2 files changed, 40 insertions(+), 21 deletions(-) (limited to 'crates/ra_vfs/src/io') 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() { -- cgit v1.2.3