Skip to content

Commit ed3682c

Browse files
committed
add sequential file access hint on windows and where available on unix
1 parent 5f9e12e commit ed3682c

3 files changed

Lines changed: 39 additions & 4 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/uu/tsort/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ thiserror = { workspace = true }
2525
uucore = { workspace = true }
2626
rustc-hash = { workspace = true }
2727

28-
[target.'cfg(unix)'.dependencies]
28+
[target.'cfg(windows)'.dependencies]
29+
windows-sys = { workspace = true, features = ["Win32_Storage_FileSystem"] }
30+
31+
[target.'cfg(any(unix, target_os = "wasi"))'.dependencies]
2932
rustix = { workspace = true, features = ["fs"] }
3033

3134
[[bin]]

src/uu/tsort/src/tsort.rs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use std::collections::VecDeque;
1212
use std::collections::hash_map::Entry;
1313
use std::ffi::OsString;
1414
use std::fs::File;
15+
use std::fs::OpenOptions;
1516
use std::io::{self, BufRead, BufReader, BufWriter, Write};
1617
use string_interner::StringInterner;
1718
use string_interner::backend::BucketBackend;
@@ -54,17 +55,47 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
5455
if input == "-" {
5556
process_input(io::stdin().lock(), &mut g)?;
5657
} else {
58+
let mut options: OpenOptions;
5759
// some platforms cannot catch this as read error. Needs additional cost by stat
5860
#[cfg(windows)]
5961
{
62+
use std::os::windows::fs::OpenOptionsExt;
63+
use windows_sys::Win32::Storage::FileSystem::FILE_FLAG_SEQUENTIAL_SCAN;
6064
let input = std::path::Path::new(input);
6165
if input.is_dir() {
6266
return Err(TsortError::IsDir(input.to_string_lossy().to_string()).into());
6367
}
68+
// advise the OS we will access the data sequentially if possible (windows)
69+
options = File::options()
70+
.custom_flags(FILE_FLAG_SEQUENTIAL_SCAN)
71+
.clone();
6472
}
65-
let file = File::open(input).map_err_context(|| input.maybe_quote().to_string())?;
66-
// advise the OS we will access the data sequentially if possible
67-
#[cfg(any(target_os = "linux", target_os = "android", target_os = "freebsd"))]
73+
74+
#[cfg(not(windows))]
75+
{
76+
options = File::options();
77+
}
78+
let file = options
79+
.read(true)
80+
.open(input)
81+
.map_err_context(|| input.maybe_quote().to_string())?;
82+
83+
// advise the OS we will access the data sequentially if possible (unix)
84+
#[cfg(all(
85+
any(unix, target_os = "wasi"),
86+
not(any(
87+
target_vendor = "apple",
88+
target_os = "netbsd",
89+
target_os = "openbsd",
90+
target_os = "dragonfly",
91+
target_os = "espidf",
92+
target_os = "haiku",
93+
target_os = "horizon",
94+
target_os = "redox",
95+
target_os = "solaris",
96+
target_os = "vita",
97+
))
98+
))]
6899
let _ = rustix::fs::fadvise(&file, 0, None, rustix::fs::Advice::Sequential);
69100

70101
let reader = BufReader::new(file);

0 commit comments

Comments
 (0)