Skip to content

Commit

Permalink
fix: -x is applied to traversal as well.
Browse files Browse the repository at this point in the history
Previously `dua` would cross filesystems for traversal and simply not
yield them, which somewhat defeated the purpose.

Now it will avoid traversing into filesystem entries that are on a different
filesystem, which should improve its performance visibly whenever multiple
filesystems are involved.
  • Loading branch information
Byron committed Feb 23, 2023
2 parents e6c10c5 + dbc9845 commit 31dacad
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ pub fn aggregate(
continue;
}
};
for entry in walk_options.iter_from_path(path.as_ref()) {
for entry in walk_options.iter_from_path(path.as_ref(), device_id) {
stats.entries_traversed += 1;
progress.throttled(|out| {
write!(out, "Enumerating {} entries\r", stats.entries_traversed).ok();
Expand Down
24 changes: 16 additions & 8 deletions src/common.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::crossdev;
use crate::traverse::{EntryData, Tree, TreeIndex};
use byte_unit::{n_gb_bytes, n_gib_bytes, n_mb_bytes, n_mib_bytes, ByteUnit};
use std::path::PathBuf;
Expand Down Expand Up @@ -130,8 +131,8 @@ pub struct WalkOptions {
type WalkDir = jwalk::WalkDirGeneric<((), Option<Result<std::fs::Metadata, jwalk::Error>>)>;

impl WalkOptions {
pub(crate) fn iter_from_path(&self, path: &Path) -> WalkDir {
WalkDir::new(path)
pub(crate) fn iter_from_path(&self, root: &Path, root_device_id: u64) -> WalkDir {
WalkDir::new(root)
.follow_links(false)
.sort(match self.sorting {
TraversalSorting::None => false,
Expand All @@ -140,16 +141,23 @@ impl WalkOptions {
.skip_hidden(false)
.process_read_dir({
let ignore_dirs = self.ignore_dirs.clone();
let cross_filesystems = self.cross_filesystems;
move |_, _, _, dir_entry_results| {
dir_entry_results.iter_mut().for_each(|dir_entry_result| {
if let Ok(dir_entry) = dir_entry_result {
let metadata = dir_entry.metadata();

if dir_entry.file_type.is_file() || dir_entry.file_type().is_symlink() {
dir_entry.client_state = Some(dir_entry.metadata());
}
if dir_entry.file_type.is_dir()
&& ignore_dirs.contains(&dir_entry.path())
{
dir_entry.read_children_path = None;
dir_entry.client_state = Some(metadata);
} else if dir_entry.file_type.is_dir() {
let ok_for_fs = cross_filesystems
|| metadata
.as_ref()
.map(|m| crossdev::is_same_device(root_device_id, m))
.unwrap_or(true);
if !ok_for_fs || ignore_dirs.contains(&dir_entry.path()) {
dir_entry.read_children_path = None;
}
}
}
})
Expand Down
2 changes: 1 addition & 1 deletion src/traverse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ impl Traversal {
}
};
for (eid, entry) in walk_options
.iter_from_path(path.as_ref())
.iter_from_path(path.as_ref(), device_id)
.into_iter()
.enumerate()
{
Expand Down

0 comments on commit 31dacad

Please sign in to comment.