@@ -17,6 +17,7 @@ use crossbeam_channel::{never, select, unbounded, Receiver, Sender};
1717use notify:: { Config , EventKind , RecommendedWatcher , RecursiveMode , Watcher } ;
1818use paths:: { AbsPath , AbsPathBuf , Utf8PathBuf } ;
1919use rayon:: iter:: { IndexedParallelIterator as _, IntoParallelIterator as _, ParallelIterator } ;
20+ use rustc_hash:: FxHashSet ;
2021use vfs:: loader:: { self , LoadingProgress } ;
2122use walkdir:: WalkDir ;
2223
@@ -61,8 +62,8 @@ type NotifyEvent = notify::Result<notify::Event>;
6162
6263struct NotifyActor {
6364 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 > ,
6667 // Drop order is significant.
6768 watcher : Option < ( RecommendedWatcher , Receiver < NotifyEvent > ) > ,
6869}
@@ -75,7 +76,12 @@ enum Event {
7576
7677impl NotifyActor {
7778 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+ }
7985 }
8086
8187 fn next_event ( & self , receiver : & Receiver < Message > ) -> Option < Event > {
@@ -107,7 +113,8 @@ impl NotifyActor {
107113 let config_version = config. version ;
108114
109115 let n_total = config. load . len ( ) ;
110- self . watched_entries . clear ( ) ;
116+ self . watched_dir_entries . clear ( ) ;
117+ self . watched_file_entries . clear ( ) ;
111118
112119 let send = |msg| ( self . sender ) ( msg) ;
113120 send ( loader:: Message :: Progress {
@@ -154,7 +161,14 @@ impl NotifyActor {
154161 self . watch ( & path) ;
155162 }
156163 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+ }
158172 }
159173 self . send ( loader:: Message :: Progress {
160174 n_total,
@@ -185,13 +199,13 @@ impl NotifyActor {
185199 . expect ( "path is absolute" ) ,
186200 )
187201 } )
188- . filter_map ( |path| {
202+ . filter_map ( |path| -> Option < ( AbsPathBuf , Option < Vec < u8 > > ) > {
189203 let meta = fs:: metadata ( & path) . ok ( ) ?;
190204 if meta. file_type ( ) . is_dir ( )
191205 && self
192- . watched_entries
206+ . watched_dir_entries
193207 . iter ( )
194- . any ( |entry| entry . contains_dir ( & path) )
208+ . any ( |dir| dir . contains_dir ( & path) )
195209 {
196210 self . watch ( path. as_ref ( ) ) ;
197211 return None ;
@@ -200,10 +214,12 @@ impl NotifyActor {
200214 if !meta. file_type ( ) . is_file ( ) {
201215 return None ;
202216 }
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) ) )
207223 {
208224 return None ;
209225 }
0 commit comments