mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 04:19:13 +00:00
Slightly optimize watch list in vfs
This commit is contained in:
parent
c6ae9cde99
commit
e437db2483
3 changed files with 30 additions and 12 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2333,6 +2333,7 @@ dependencies = [
|
||||||
"notify",
|
"notify",
|
||||||
"paths",
|
"paths",
|
||||||
"rayon",
|
"rayon",
|
||||||
|
"rustc-hash",
|
||||||
"stdx",
|
"stdx",
|
||||||
"tracing",
|
"tracing",
|
||||||
"vfs",
|
"vfs",
|
||||||
|
|
|
@ -21,6 +21,7 @@ rayon = "1.10.0"
|
||||||
stdx.workspace = true
|
stdx.workspace = true
|
||||||
vfs.workspace = true
|
vfs.workspace = true
|
||||||
paths.workspace = true
|
paths.workspace = true
|
||||||
|
rustc-hash.workspace = true
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
|
@ -17,6 +17,7 @@ use crossbeam_channel::{never, select, unbounded, Receiver, Sender};
|
||||||
use notify::{Config, EventKind, RecommendedWatcher, RecursiveMode, Watcher};
|
use notify::{Config, EventKind, RecommendedWatcher, RecursiveMode, Watcher};
|
||||||
use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
|
use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
|
||||||
use rayon::iter::{IndexedParallelIterator as _, IntoParallelIterator as _, ParallelIterator};
|
use rayon::iter::{IndexedParallelIterator as _, IntoParallelIterator as _, ParallelIterator};
|
||||||
|
use rustc_hash::FxHashSet;
|
||||||
use vfs::loader::{self, LoadingProgress};
|
use vfs::loader::{self, LoadingProgress};
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
|
@ -61,8 +62,8 @@ type NotifyEvent = notify::Result<notify::Event>;
|
||||||
|
|
||||||
struct NotifyActor {
|
struct NotifyActor {
|
||||||
sender: loader::Sender,
|
sender: loader::Sender,
|
||||||
// FIXME: Consider hashset
|
watched_file_entries: FxHashSet<AbsPathBuf>,
|
||||||
watched_entries: Vec<loader::Entry>,
|
watched_dir_entries: Vec<loader::Directories>,
|
||||||
// Drop order is significant.
|
// Drop order is significant.
|
||||||
watcher: Option<(RecommendedWatcher, Receiver<NotifyEvent>)>,
|
watcher: Option<(RecommendedWatcher, Receiver<NotifyEvent>)>,
|
||||||
}
|
}
|
||||||
|
@ -75,7 +76,12 @@ enum Event {
|
||||||
|
|
||||||
impl NotifyActor {
|
impl NotifyActor {
|
||||||
fn new(sender: loader::Sender) -> NotifyActor {
|
fn new(sender: loader::Sender) -> NotifyActor {
|
||||||
NotifyActor { sender, watched_entries: Vec::new(), watcher: None }
|
NotifyActor {
|
||||||
|
sender,
|
||||||
|
watched_dir_entries: Vec::new(),
|
||||||
|
watched_file_entries: FxHashSet::default(),
|
||||||
|
watcher: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_event(&self, receiver: &Receiver<Message>) -> Option<Event> {
|
fn next_event(&self, receiver: &Receiver<Message>) -> Option<Event> {
|
||||||
|
@ -107,7 +113,8 @@ impl NotifyActor {
|
||||||
let config_version = config.version;
|
let config_version = config.version;
|
||||||
|
|
||||||
let n_total = config.load.len();
|
let n_total = config.load.len();
|
||||||
self.watched_entries.clear();
|
self.watched_dir_entries.clear();
|
||||||
|
self.watched_file_entries.clear();
|
||||||
|
|
||||||
let send = |msg| (self.sender)(msg);
|
let send = |msg| (self.sender)(msg);
|
||||||
send(loader::Message::Progress {
|
send(loader::Message::Progress {
|
||||||
|
@ -154,7 +161,14 @@ impl NotifyActor {
|
||||||
self.watch(&path);
|
self.watch(&path);
|
||||||
}
|
}
|
||||||
for entry in entry_rx {
|
for entry in entry_rx {
|
||||||
self.watched_entries.push(entry);
|
match entry {
|
||||||
|
loader::Entry::Files(files) => {
|
||||||
|
self.watched_file_entries.extend(files)
|
||||||
|
}
|
||||||
|
loader::Entry::Directories(dir) => {
|
||||||
|
self.watched_dir_entries.push(dir)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.send(loader::Message::Progress {
|
self.send(loader::Message::Progress {
|
||||||
n_total,
|
n_total,
|
||||||
|
@ -185,13 +199,13 @@ impl NotifyActor {
|
||||||
.expect("path is absolute"),
|
.expect("path is absolute"),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.filter_map(|path| {
|
.filter_map(|path| -> Option<(AbsPathBuf, Option<Vec<u8>>)> {
|
||||||
let meta = fs::metadata(&path).ok()?;
|
let meta = fs::metadata(&path).ok()?;
|
||||||
if meta.file_type().is_dir()
|
if meta.file_type().is_dir()
|
||||||
&& self
|
&& self
|
||||||
.watched_entries
|
.watched_dir_entries
|
||||||
.iter()
|
.iter()
|
||||||
.any(|entry| entry.contains_dir(&path))
|
.any(|dir| dir.contains_dir(&path))
|
||||||
{
|
{
|
||||||
self.watch(path.as_ref());
|
self.watch(path.as_ref());
|
||||||
return None;
|
return None;
|
||||||
|
@ -200,10 +214,12 @@ impl NotifyActor {
|
||||||
if !meta.file_type().is_file() {
|
if !meta.file_type().is_file() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if !self
|
|
||||||
.watched_entries
|
if !(self.watched_file_entries.contains(&path)
|
||||||
|
|| self
|
||||||
|
.watched_dir_entries
|
||||||
.iter()
|
.iter()
|
||||||
.any(|entry| entry.contains_file(&path))
|
.any(|dir| dir.contains_file(&path)))
|
||||||
{
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue