Use our own struct instead of accumulating DirEntrys

DirEntry keeps a handle to an open file, so keeping a reference to them
while traversing a large directory, such as a home directory, can
trigger a too many open files error.
This commit is contained in:
Cameron Cordes
2021-02-15 20:06:45 -05:00
parent 2b84afb12e
commit 827aad57dc

View File

@@ -22,7 +22,18 @@ mod rack {
struct Traversal { struct Traversal {
dirs: Vec<DirEntry>, dirs: Vec<DirEntry>,
entries: Vec<DirEntry>, entries: Vec<SearchableFile>,
}
struct SearchableFile {
path: PathBuf,
}
/// Use our own structure since DirEntry keeps hold of open files until they are dropped
impl From<DirEntry> for SearchableFile {
fn from(entry: DirEntry) -> SearchableFile {
SearchableFile { path: entry.path() }
}
} }
impl Rack { impl Rack {
@@ -93,22 +104,25 @@ mod rack {
continue; continue;
} }
if let Ok(mut contents) = Rack::get_dir_entries(path) { match Rack::get_dir_entries(path) {
traversal.dirs.append(&mut contents); Ok(mut contents) => {
} traversal.dirs.append(&mut contents);
}
Err(msg) => println!("Error reading dir: {}. {}", path, msg),
};
} else { } else {
if self.should_ignore(&gitignore, path, &entry) { if self.should_ignore(&gitignore, path, &entry) {
continue; continue;
} }
traversal.entries.push(entry); traversal.entries.push(entry.into());
} }
} }
let mut results = traversal let mut results = traversal
.entries .entries
.iter() .iter()
.filter_map(|e| self.check_file(&e.path()).ok()) .filter_map(|e| self.check_file(&e.path).ok())
.filter(|mat| mat.matches.len() > 0) .filter(|mat| mat.matches.len() > 0)
.collect::<Vec<FileMatch>>(); .collect::<Vec<FileMatch>>();
self.matches.append(&mut results); self.matches.append(&mut results);