Skip to content

Commit ec4ad45

Browse files
authored
feat(api)!: remove depth from DataTree::dir (#283)
* feat(api)!: remove `depth` from `DataTree::dir` * fix: `--max-depth` with multiple names * test: ensure specific structures * test: fix * style: digit separators
1 parent cde72da commit ec4ad45

8 files changed

Lines changed: 152 additions & 16 deletions

File tree

src/app/sub.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,14 @@ where
9696
let data_tree = if iter.len() == 0 {
9797
data_tree
9898
} else {
99+
let max_depth = max_depth.get();
99100
let children: Vec<_> = once(data_tree).chain(iter).collect();
100101
DataTree::dir(
101102
OsStringDisplay::os_string_from("(total)"),
102103
Size::default(),
103104
children,
104-
max_depth.get(),
105105
)
106+
.into_par_retained(|_, depth| depth + 1 < max_depth)
106107
};
107108

108109
if reporter.destroy().is_err() {

src/data_tree/constructors.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ use crate::size;
33

44
impl<Name, Size: size::Size> DataTree<Name, Size> {
55
/// Create a tree representation of a directory.
6-
pub fn dir(name: Name, inode_size: Size, children: Vec<Self>, depth: u64) -> Self {
6+
pub fn dir(name: Name, inode_size: Size, children: Vec<Self>) -> Self {
77
let size = inode_size + children.iter().map(DataTree::size).sum();
8-
let children = if depth > 0 { children } else { Vec::new() };
98
DataTree {
109
name,
1110
size,
@@ -27,6 +26,11 @@ impl<Name, Size: size::Size> DataTree<Name, Size> {
2726
where
2827
Size: Copy,
2928
{
30-
move |name, children| DataTree::dir(name, inode_size, children, 1)
29+
move |name, children| DataTree::dir(name, inode_size, children)
30+
}
31+
32+
/// Remove the children. Free memory usage.
33+
pub(crate) fn drop_children(&mut self) {
34+
self.children = Vec::new();
3135
}
3236
}

src/data_tree/retain/test.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ type SampleData = Bytes;
77
type SampleTree = DataTree<SampleName, SampleData>;
88

99
fn dir<const INODE_SIZE: u64>(name: &'static str, children: Vec<SampleTree>) -> SampleTree {
10-
SampleTree::dir(name.to_string(), INODE_SIZE.into(), children, 10)
10+
SampleTree::dir(name.to_string(), INODE_SIZE.into(), children)
1111
}
1212

1313
fn file(name: &'static str, size: u64) -> SampleTree {
@@ -23,7 +23,6 @@ fn culled_dir<const INODE_SIZE: u64>(
2323
name.to_string(),
2424
(INODE_SIZE + culled_size).into(),
2525
children,
26-
10,
2726
)
2827
}
2928

src/tree_builder.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,13 @@ where
5959
max_depth,
6060
})
6161
.map(Self::from)
62-
.collect();
62+
.collect(); // TODO: this collect can be called into different types depending on whether `max_depth` is 0
6363

64-
DataTree::dir(name, size, children, max_depth)
64+
let mut tree = DataTree::dir(name, size, children);
65+
if max_depth == 0 {
66+
// TODO: replace this with a more memory efficient method that doesn't require constructing `children` in the first place
67+
tree.drop_children();
68+
}
69+
tree
6570
}
6671
}

tests/_utils.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,13 @@ impl Default for SampleWorkspace {
7777
MergeableFileSystemTree::<&str, String>::from(dir! {
7878
"flat" => dir! {
7979
"0" => file!("")
80-
"1" => file!("a".repeat(1000))
81-
"2" => file!("a".repeat(2000))
82-
"3" => file!("a".repeat(3000))
80+
"1" => file!("a".repeat(100_000))
81+
"2" => file!("a".repeat(200_000))
82+
"3" => file!("a".repeat(300_000))
8383
}
8484
"nested" => dir! {
8585
"0" => dir! {
86-
"1" => file!("a".repeat(5000))
86+
"1" => file!("a".repeat(500_000))
8787
}
8888
}
8989
"empty-dir" => dir! {}

tests/json.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ type SampleTree = DataTree<SampleName, SampleData>;
3030

3131
fn sample_tree() -> SampleTree {
3232
let dir = |name: &'static str, children: Vec<SampleTree>| {
33-
SampleTree::dir(name.to_string(), 1024.into(), children, 10)
33+
SampleTree::dir(name.to_string(), 1024.into(), children)
3434
};
3535
let file =
3636
|name: &'static str, size: u64| SampleTree::file(name.to_string(), Bytes::from(size));

tests/usual_cli.rs

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,6 @@ fn multiple_names() {
623623
OsStringDisplay::os_string_from("(total)"),
624624
0.into(),
625625
children.collect(),
626-
10,
627626
)
628627
})
629628
.into_par_sorted(|left, right| left.size().cmp(&right.size()).reverse());
@@ -640,4 +639,132 @@ fn multiple_names() {
640639
eprintln!("EXPECTED:\n{expected}\n");
641640

642641
assert_eq!(actual, expected);
642+
643+
let mut lines = actual.lines();
644+
assert!(lines.next().unwrap().contains("┌──1"));
645+
assert!(lines.next().unwrap().contains("┌─┴0"));
646+
assert!(lines.next().unwrap().contains("┌─┴nested"));
647+
assert!(lines.next().unwrap().contains("│ ┌──1"));
648+
assert!(lines.next().unwrap().contains("│ ├──2"));
649+
assert!(lines.next().unwrap().contains("│ ├──3"));
650+
assert!(lines.next().unwrap().contains("├─┴flat"));
651+
assert!(lines.next().unwrap().contains("┌─┴(total)"));
652+
assert_eq!(lines.next(), None);
653+
}
654+
655+
#[test]
656+
fn multiple_names_max_depth_2() {
657+
let workspace = SampleWorkspace::default();
658+
let actual = Command::new(PDU)
659+
.with_current_dir(&workspace)
660+
.with_arg("--quantity=apparent-size")
661+
.with_arg("--total-width=100")
662+
.with_arg("--max-depth=2")
663+
.with_arg("nested")
664+
.with_arg("flat")
665+
.with_arg("empty-dir")
666+
.pipe(stdio)
667+
.output()
668+
.expect("spawn command")
669+
.pipe(stdout_text);
670+
eprintln!("ACTUAL:\n{actual}\n");
671+
672+
let mut data_tree = ["nested", "flat", "empty-dir"]
673+
.iter()
674+
.map(|name| {
675+
let builder = FsTreeBuilder {
676+
root: workspace.to_path_buf().join(name),
677+
size_getter: GetApparentSize,
678+
reporter: ErrorOnlyReporter::new(ErrorReport::SILENT),
679+
max_depth: 1,
680+
};
681+
let mut data_tree: DataTree<OsStringDisplay, _> = builder.into();
682+
*data_tree.name_mut() = OsStringDisplay::os_string_from(name);
683+
data_tree
684+
})
685+
.pipe(|children| {
686+
DataTree::dir(
687+
OsStringDisplay::os_string_from("(total)"),
688+
0.into(),
689+
children.collect(),
690+
)
691+
})
692+
.into_par_sorted(|left, right| left.size().cmp(&right.size()).reverse());
693+
data_tree.par_cull_insignificant_data(0.01);
694+
let visualizer = Visualizer::<OsStringDisplay, _> {
695+
data_tree: &data_tree,
696+
bytes_format: BytesFormat::MetricUnits,
697+
direction: Direction::BottomUp,
698+
bar_alignment: BarAlignment::Left,
699+
column_width_distribution: ColumnWidthDistribution::total(100),
700+
};
701+
let expected = format!("{visualizer}");
702+
let expected = expected.trim_end();
703+
eprintln!("EXPECTED:\n{expected}\n");
704+
705+
assert_eq!(actual, expected);
706+
707+
let mut lines = actual.lines();
708+
assert!(lines.next().unwrap().contains("┌──nested"));
709+
assert!(lines.next().unwrap().contains("├──flat"));
710+
assert!(lines.next().unwrap().contains("┌─┴(total)"));
711+
assert_eq!(lines.next(), None);
712+
}
713+
714+
#[test]
715+
fn multiple_names_max_depth_1() {
716+
let workspace = SampleWorkspace::default();
717+
let actual = Command::new(PDU)
718+
.with_current_dir(&workspace)
719+
.with_arg("--quantity=apparent-size")
720+
.with_arg("--total-width=100")
721+
.with_arg("--max-depth=1")
722+
.with_arg("nested")
723+
.with_arg("flat")
724+
.with_arg("empty-dir")
725+
.pipe(stdio)
726+
.output()
727+
.expect("spawn command")
728+
.pipe(stdout_text);
729+
eprintln!("ACTUAL:\n{actual}\n");
730+
731+
let mut data_tree = ["nested", "flat", "empty-dir"]
732+
.iter()
733+
.map(|name| {
734+
let builder = FsTreeBuilder {
735+
root: workspace.to_path_buf().join(name),
736+
size_getter: GetApparentSize,
737+
reporter: ErrorOnlyReporter::new(ErrorReport::SILENT),
738+
max_depth: 10,
739+
};
740+
let mut data_tree: DataTree<OsStringDisplay, _> = builder.into();
741+
*data_tree.name_mut() = OsStringDisplay::os_string_from(name);
742+
data_tree
743+
})
744+
.pipe(|children| {
745+
DataTree::dir(
746+
OsStringDisplay::os_string_from("(total)"),
747+
0.into(),
748+
children.collect(),
749+
)
750+
})
751+
.into_par_retained(|_, _| false)
752+
.into_par_sorted(|left, right| left.size().cmp(&right.size()).reverse());
753+
data_tree.par_cull_insignificant_data(0.01);
754+
let visualizer = Visualizer::<OsStringDisplay, _> {
755+
data_tree: &data_tree,
756+
bytes_format: BytesFormat::MetricUnits,
757+
direction: Direction::BottomUp,
758+
bar_alignment: BarAlignment::Left,
759+
column_width_distribution: ColumnWidthDistribution::total(100),
760+
};
761+
let expected = format!("{visualizer}");
762+
let expected = expected.trim_end();
763+
eprintln!("EXPECTED:\n{expected}\n");
764+
765+
assert_eq!(actual, expected);
766+
767+
let mut lines = actual.lines();
768+
assert!(lines.next().unwrap().contains("┌──(total)"));
769+
assert_eq!(lines.next(), None);
643770
}

tests/visualizer.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ fn nested_tree<Size: size::Size>(
403403
) -> DataTree<&'static str, Size> {
404404
if let Some((head, tail)) = dir_names.split_first() {
405405
let child = nested_tree(tail, size_per_dir, file_name, file_size);
406-
DataTree::dir(*head, size_per_dir, vec![child], 10)
406+
DataTree::dir(*head, size_per_dir, vec![child])
407407
} else {
408408
DataTree::file(file_name, file_size)
409409
}
@@ -649,7 +649,7 @@ fn empty_dir<Size>(inode_size: Size) -> DataTree<&'static str, Size>
649649
where
650650
Size: size::Size + Ord + From<u64> + Send,
651651
{
652-
DataTree::dir("empty directory", inode_size, Vec::new(), 10).into_par_sorted(order_tree)
652+
DataTree::dir("empty directory", inode_size, Vec::new()).into_par_sorted(order_tree)
653653
}
654654

655655
test_case! {

0 commit comments

Comments
 (0)