@@ -17,6 +17,7 @@ use crossbeam_channel::{never, select, unbounded, Receiver, Sender};
17
17
use notify:: { Config , EventKind , RecommendedWatcher , RecursiveMode , Watcher } ;
18
18
use paths:: { AbsPath , AbsPathBuf , Utf8PathBuf } ;
19
19
use rayon:: iter:: { IndexedParallelIterator as _, IntoParallelIterator as _, ParallelIterator } ;
20
+ use rustc_hash:: FxHashSet ;
20
21
use vfs:: loader:: { self , LoadingProgress } ;
21
22
use walkdir:: WalkDir ;
22
23
@@ -61,8 +62,8 @@ type NotifyEvent = notify::Result<notify::Event>;
61
62
62
63
struct NotifyActor {
63
64
sender : loader:: Sender ,
64
- // FIXME: Consider hashset
65
- watched_entries : Vec < loader:: Entry > ,
65
+ watched_file_entries : FxHashSet < AbsPathBuf > ,
66
+ watched_dir_entries : Vec < loader:: Directories > ,
66
67
// Drop order is significant.
67
68
watcher : Option < ( RecommendedWatcher , Receiver < NotifyEvent > ) > ,
68
69
}
@@ -75,7 +76,12 @@ enum Event {
75
76
76
77
impl NotifyActor {
77
78
fn new ( sender : loader:: Sender ) -> NotifyActor {
78
- NotifyActor { sender, watched_entries : Vec :: new ( ) , watcher : None }
79
+ NotifyActor {
80
+ sender,
81
+ watched_dir_entries : Vec :: new ( ) ,
82
+ watched_file_entries : FxHashSet :: default ( ) ,
83
+ watcher : None ,
84
+ }
79
85
}
80
86
81
87
fn next_event ( & self , receiver : & Receiver < Message > ) -> Option < Event > {
@@ -107,7 +113,8 @@ impl NotifyActor {
107
113
let config_version = config. version ;
108
114
109
115
let n_total = config. load . len ( ) ;
110
- self . watched_entries . clear ( ) ;
116
+ self . watched_dir_entries . clear ( ) ;
117
+ self . watched_file_entries . clear ( ) ;
111
118
112
119
let send = |msg| ( self . sender ) ( msg) ;
113
120
send ( loader:: Message :: Progress {
@@ -154,7 +161,14 @@ impl NotifyActor {
154
161
self . watch ( & path) ;
155
162
}
156
163
for entry in entry_rx {
157
- self . watched_entries . push ( entry) ;
164
+ match entry {
165
+ loader:: Entry :: Files ( files) => {
166
+ self . watched_file_entries . extend ( files)
167
+ }
168
+ loader:: Entry :: Directories ( dir) => {
169
+ self . watched_dir_entries . push ( dir)
170
+ }
171
+ }
158
172
}
159
173
self . send ( loader:: Message :: Progress {
160
174
n_total,
@@ -185,13 +199,13 @@ impl NotifyActor {
185
199
. expect ( "path is absolute" ) ,
186
200
)
187
201
} )
188
- . filter_map ( |path| {
202
+ . filter_map ( |path| -> Option < ( AbsPathBuf , Option < Vec < u8 > > ) > {
189
203
let meta = fs:: metadata ( & path) . ok ( ) ?;
190
204
if meta. file_type ( ) . is_dir ( )
191
205
&& self
192
- . watched_entries
206
+ . watched_dir_entries
193
207
. iter ( )
194
- . any ( |entry| entry . contains_dir ( & path) )
208
+ . any ( |dir| dir . contains_dir ( & path) )
195
209
{
196
210
self . watch ( path. as_ref ( ) ) ;
197
211
return None ;
@@ -200,10 +214,12 @@ impl NotifyActor {
200
214
if !meta. file_type ( ) . is_file ( ) {
201
215
return None ;
202
216
}
203
- if !self
204
- . watched_entries
205
- . iter ( )
206
- . any ( |entry| entry. contains_file ( & path) )
217
+
218
+ if !( self . watched_file_entries . contains ( & path)
219
+ || self
220
+ . watched_dir_entries
221
+ . iter ( )
222
+ . any ( |dir| dir. contains_file ( & path) ) )
207
223
{
208
224
return None ;
209
225
}
0 commit comments