Skip to content

Commit f54de3d

Browse files
committed
fix: fixed freeze when reading from current directory
1 parent 6458557 commit f54de3d

File tree

3 files changed

+54
-25
lines changed

3 files changed

+54
-25
lines changed

benchmarks/run

+27-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// Search one file in ~/
12
cmd 1() {
23
# Benchmark 1: Searching file in ~/
34
# File is in "/home/user/.wine/drive_c/users/user/AppData/Local/mygame/User Data/Crashpad/reports/SomeFile"
@@ -10,13 +11,38 @@ cmd 1() {
1011
"$HUNT" \
1112
}
1213

14+
// Search multiple files in ~/
1315
cmd 2() {
1416
# Benchmark 2: Searching multiple files in ~/
1517
HUNT="hunt --hidden --exact SomeFile $HOME";
1618
FD="fd --hidden --no-ignore --color=never SomeFile $HOME";
17-
FIND="find $HOME -name SomeFile -print -quit";
19+
FIND="find $HOME -name SomeFile -print";
1820
# LOCATE='locate -n 1 -A SomeFile'
1921
hyperfine -N --warmup 2 --ignore-failure "$FIND" \
2022
"$FD" \
2123
"$HUNT" \
24+
}
25+
26+
// Search multiple files in /
27+
cmd 3() {
28+
# Benchmark 3: Searching multiple files in /
29+
HUNT="hunt --hidden --exact SomeFile /";
30+
FD="fd --hidden --no-ignore --color=never SomeFile /";
31+
# FIND="find / -name SomeFile -print";
32+
# LOCATE='locate -n 1 -A SomeFile'
33+
hyperfine -N --warmup 1 --ignore-failure \
34+
"$FD" \
35+
"$HUNT" \
36+
}
37+
38+
// Search all files in ~/
39+
cmd 4() {
40+
# Benchmark 3: Searching multiple files in /
41+
HUNT="hunt --hidden $HOME";
42+
FD="fd --unrestricted --color=never . $HOME";
43+
# FIND="find / -name SomeFile -print";
44+
# LOCATE='locate -n 1 -A SomeFile'
45+
hyperfine -N --warmup 1 --ignore-failure \
46+
"$FD" \
47+
"$HUNT" \
2248
}

src/print.rs

+16-11
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ impl Search {
77
if self.output == Output::SuperSimple {
88
return Ok(());
99
}
10+
1011
let stdout = std::io::stdout();
1112
let mut stdout = std::io::BufWriter::new(stdout.lock());
13+
1214
let (mut ex, mut co) = buffers;
1315
if ex.is_empty() && co.is_empty() {
1416
if self.output == Output::Normal {
@@ -20,17 +22,20 @@ impl Search {
2022
ctx = "sort";
2123
rayon::join(|| co.par_sort(), || ex.par_sort());
2224
}
23-
if self.output == Output::Normal {
24-
writeln!(stdout, "Contains:")?;
25-
}
26-
for path in co.into_iter() {
27-
writeln!(stdout, "{path}")?;
28-
}
29-
if self.output == Output::Normal {
30-
writeln!(stdout, "\nExact:")?;
31-
}
32-
for path in ex.into_iter() {
33-
writeln!(stdout, "{}", path.display())?;
25+
crate::perf! {
26+
ctx = "print";
27+
if self.output == Output::Normal {
28+
writeln!(stdout, "Contains:")?;
29+
}
30+
for path in co.into_iter() {
31+
writeln!(stdout, "{path}")?;
32+
}
33+
if self.output == Output::Normal {
34+
writeln!(stdout, "\nExact:")?;
35+
}
36+
for path in ex.into_iter() {
37+
writeln!(stdout, "{}", path.display())?;
38+
}
3439
}
3540
Ok(())
3641
}

src/search.rs

+11-13
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,21 @@ impl Search {
1616
} else {
1717
std::path::Path::new(".").to_owned()
1818
};
19-
search_path(&path, self, sender.clone());
19+
return rayon::scope(|s| {
20+
s.spawn(|_| search_path(&path, self, sender));
21+
receive_paths(receiver, self)
22+
});
2023
}
2124
// Check if paths are valid and canonicalize if necessary
2225
let dirs = self.dirs.iter().map(|path| {
2326
if !path.exists() {
24-
eprintln!("ERROR: The {:?} directory does not exist", path);
27+
eprintln!("Error: The {:?} directory does not exist", path);
2528
std::process::exit(1)
2629
}
2730

2831
if self.canonicalize {
2932
std::borrow::Cow::Owned(path.canonicalize().unwrap_or_else(|_| {
30-
eprintln!("ERROR: The {:?} directory does not exist", path);
33+
eprintln!("Error: The {:?} directory does not exist", path);
3134
std::process::exit(1)
3235
}))
3336
} else {
@@ -57,7 +60,7 @@ impl std::fmt::Display for SearchResult {
5760
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
5861
match self {
5962
SearchResult::Exact(p) => write!(f, "{}", p.display()),
60-
SearchResult::Contains(s) => write!(f, "{}", s),
63+
SearchResult::Contains(s) => f.write_str(s),
6164
}
6265
}
6366
}
@@ -66,12 +69,8 @@ fn receive_paths(receiver: Receiver, search: &Search) -> Buffers {
6669
let stdout = std::io::stdout();
6770
let mut stdout = std::io::BufWriter::new(stdout.lock());
6871

69-
crate::perf! {
70-
ctx = "alloc vecs";
71-
72-
let mut exact = Vec::with_capacity(8);
73-
let mut contains = Vec::with_capacity(8);
74-
}
72+
let mut exact = Vec::with_capacity(8);
73+
let mut contains = Vec::with_capacity(8);
7574

7675
while let Ok(path) = receiver.recv() {
7776
crate::perf! {
@@ -99,7 +98,6 @@ fn search_path(dir: &Path, search: &Search, sender: Sender) {
9998
read.flatten()
10099
.par_bridge()
101100
.for_each(|entry| search_dir(entry, search, sender.clone()));
102-
// return par_fold(read.flatten(), |entry| search_dir(entry, search, sender.clone()));
103101
} else if search.verbose {
104102
eprintln!("Could not read {:?}", dir);
105103
}
@@ -145,12 +143,12 @@ fn search_dir(entry: std::fs::DirEntry, search: &Search, sender: Sender) {
145143
if starts && ends && ftype {
146144
// If file name is equal to search name, write it to the "Exact" buffer
147145
if sname == search.name {
148-
crate::perf! { ctx = "send_ex"; sender.send(SearchResult::Exact(path.clone())).unwrap(); }
146+
sender.send(SearchResult::Exact(path.clone())).unwrap();
149147
}
150148
// If file name contains the search name, write it to the "Contains" buffer
151149
else if !search.exact && sname.contains(&search.name) {
152150
let s = crate::print::format_with_highlight(&fname, &sname, &path, search);
153-
crate::perf! { ctx = "send"; sender.send(SearchResult::Contains(s)).unwrap(); }
151+
sender.send(SearchResult::Contains(s)).unwrap();
154152
}
155153
}
156154

0 commit comments

Comments
 (0)