Skip to content
Merged
2 changes: 0 additions & 2 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ impl App {
bytes_format,
top_down,
align_right,
max_depth,
..
} = self.args;
let direction = Direction::from_top_down(top_down);
Expand All @@ -79,7 +78,6 @@ impl App {
column_width_distribution,
direction,
bar_alignment,
max_depth,
}
.to_string()
}};
Expand Down
7 changes: 4 additions & 3 deletions src/app/sub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{
visualizer::{BarAlignment, ColumnWidthDistribution, Direction, Visualizer},
};
use serde::Serialize;
use std::{io::stdout, iter::once, num::NonZeroUsize, path::PathBuf};
use std::{io::stdout, iter::once, num::NonZeroU64, path::PathBuf};

/// The sub program of the main application.
pub struct Sub<Size, SizeGetter, Report>
Expand All @@ -35,7 +35,7 @@ where
/// Distribution and number of characters/blocks can be placed in a line.
pub column_width_distribution: ColumnWidthDistribution,
/// Maximum number of levels that should be visualized.
pub max_depth: NonZeroUsize,
pub max_depth: NonZeroU64,
/// [Get the size](GetSize) of files/directories.
pub size_getter: SizeGetter,
/// Reports measurement progress.
Expand Down Expand Up @@ -76,6 +76,7 @@ where
reporter: &reporter,
root,
size_getter,
max_depth: max_depth.get(),
}
.into()
});
Expand All @@ -100,6 +101,7 @@ where
OsStringDisplay::os_string_from("(total)"),
Size::default(),
children,
max_depth.get(),
)
};

Expand Down Expand Up @@ -142,7 +144,6 @@ where
direction,
bar_alignment,
column_width_distribution,
max_depth,
};

print!("{visualizer}"); // visualizer already ends with "\n", println! isn't needed here.
Expand Down
4 changes: 2 additions & 2 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub use threads::Threads;

use crate::{bytes_format::BytesFormat, visualizer::ColumnWidthDistribution};
use clap::{ColorChoice, Parser};
use std::{num::NonZeroUsize, path::PathBuf};
use std::{num::NonZeroU64, path::PathBuf};
use terminal_size::{terminal_size, Width};
use text_block_macros::text_block;

Expand Down Expand Up @@ -105,7 +105,7 @@ pub struct Args {

/// Maximum depth to display the data (must be greater than 0).
#[clap(long, default_value = "10")]
pub max_depth: NonZeroUsize,
pub max_depth: NonZeroU64,

/// Width of the visualization.
#[clap(long, conflicts_with = "column_width")]
Expand Down
5 changes: 3 additions & 2 deletions src/data_tree/constructors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ use crate::size;

impl<Name, Size: size::Size> DataTree<Name, Size> {
/// Create a tree representation of a directory.
pub fn dir(name: Name, inode_size: Size, children: Vec<Self>) -> Self {
pub fn dir(name: Name, inode_size: Size, children: Vec<Self>, depth: u64) -> Self {
let size = inode_size + children.iter().map(DataTree::size).sum();
let children = if depth > 0 { children } else { Vec::new() };
DataTree {
name,
size,
Expand All @@ -26,6 +27,6 @@ impl<Name, Size: size::Size> DataTree<Name, Size> {
where
Size: Copy,
{
move |name, children| DataTree::dir(name, inode_size, children)
move |name, children| DataTree::dir(name, inode_size, children, 1)
}
}
26 changes: 20 additions & 6 deletions src/data_tree/retain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,30 @@ where
Self: Send,
Size: size::Size,
{
/// Recursively cull all descendants that do not satisfy given `predicate`, in parallel.
pub fn par_retain(&mut self, predicate: impl Fn(&Self) -> bool + Copy + Sync) {
self.children.retain(predicate);
/// Internal function to be used by [`Self::par_retain`].
fn par_retain_with_depth(
&mut self,
current_depth: u64,
predicate: impl Fn(&Self, u64) -> bool + Copy + Sync,
) {
self.children
.retain(|child| predicate(child, current_depth));
let next_depth = current_depth + 1;
self.children
.par_iter_mut()
.for_each(|child| child.par_retain(predicate));
.for_each(|child| child.par_retain_with_depth(next_depth, predicate))
}

/// Recursively cull all descendants that do not satisfy given `predicate`, in parallel.
pub fn par_retain(&mut self, predicate: impl Fn(&Self, u64) -> bool + Copy + Sync) {
self.par_retain_with_depth(0, predicate)
}

/// Process the tree via [`par_retain`](Self::par_retain) method.
pub fn into_par_retained(mut self, predicate: impl Fn(&Self) -> bool + Copy + Sync) -> Self {
pub fn into_par_retained(
mut self,
predicate: impl Fn(&Self, u64) -> bool + Copy + Sync,
) -> Self {
self.par_retain(predicate);
self
}
Expand All @@ -28,7 +42,7 @@ where
Size: Into<u64>,
{
let minimal = self.size().into() as f32 * min_ratio;
self.par_retain(|descendant| descendant.size().into() as f32 >= minimal);
self.par_retain(|descendant, _| descendant.size().into() as f32 >= minimal);
}

/// Process the tree via [`par_cull_insignificant_data`](Self::par_cull_insignificant_data) method.
Expand Down
5 changes: 3 additions & 2 deletions src/data_tree/retain/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ type SampleData = Bytes;
type SampleTree = DataTree<SampleName, SampleData>;

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

fn file(name: &'static str, size: u64) -> SampleTree {
Expand All @@ -23,6 +23,7 @@ fn culled_dir<const INODE_SIZE: u64>(
name.to_string(),
(INODE_SIZE + culled_size).into(),
children,
10,
)
}

Expand Down Expand Up @@ -156,7 +157,7 @@ fn edge_cases() {
),
],
)
.into_par_retained(|descendant| descendant.name().starts_with('!').not())
.into_par_retained(|descendant, _| descendant.name().starts_with('!').not())
.into_reflection();
let expected = dir(
"root",
Expand Down
6 changes: 6 additions & 0 deletions src/fs_tree_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use std::{
/// root: std::env::current_dir().unwrap(),
/// size_getter: GetApparentSize,
/// reporter: ErrorOnlyReporter::new(ErrorReport::SILENT),
/// max_depth: 10,
/// };
/// let data_tree: DataTree<OsStringDisplay, Bytes> = builder.into();
/// ```
Expand All @@ -45,6 +46,8 @@ where
pub size_getter: SizeGetter,
/// Reports progress to external system.
pub reporter: Report,
/// Deepest level of descendent display in the graph. The sizes beyond the max depth still count toward total.
pub max_depth: u64,
}

impl<Size, SizeGetter, Report> From<FsTreeBuilder<Size, SizeGetter, Report>>
Expand All @@ -60,6 +63,7 @@ where
root,
size_getter,
reporter,
max_depth,
} = builder;

TreeBuilder::<PathBuf, OsStringDisplay, Size, _, _> {
Expand Down Expand Up @@ -118,6 +122,8 @@ where
},

join_path: |prefix, name| prefix.join(&name.0),

max_depth,
}
.into()
}
Expand Down
7 changes: 6 additions & 1 deletion src/tree_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ where
pub get_info: GetInfo,
/// Function to join parent's `path` with a child's name to make the child's `name`.
pub join_path: JoinPath,
/// Deepest level of descendent to store as arrays. The sizes beyond the max depth still count toward total.
pub max_depth: u64,
}

impl<Path, Name, Size, GetInfo, JoinPath> From<TreeBuilder<Path, Name, Size, GetInfo, JoinPath>>
Expand All @@ -41,9 +43,11 @@ where
name,
get_info,
join_path,
max_depth,
} = builder;

let Info { size, children } = get_info(&path);
let max_depth = max_depth.saturating_sub(1);

let children: Vec<_> = children
.into_par_iter()
Expand All @@ -52,10 +56,11 @@ where
name,
get_info,
join_path,
max_depth,
})
.map(Self::from)
.collect();

DataTree::dir(name, size, children)
DataTree::dir(name, size, children, max_depth)
}
}
5 changes: 1 addition & 4 deletions src/visualizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub use proportion_bar::{ProportionBar, ProportionBarBlock};
pub use tree::{TreeHorizontalSlice, TreeSkeletalComponent};

use super::{data_tree::DataTree, size};
use std::{fmt::Display, num::NonZeroUsize};
use std::fmt::Display;

/// Visualize a [`DataTree`].
///
Expand All @@ -38,7 +38,6 @@ use std::{fmt::Display, num::NonZeroUsize};
/// direction: Direction::BottomUp,
/// bar_alignment: BarAlignment::Right,
/// column_width_distribution: ColumnWidthDistribution::total(100),
/// max_depth: std::num::NonZeroUsize::new(10).unwrap(),
/// };
/// println!("{visualizer}");
/// # }
Expand All @@ -59,8 +58,6 @@ where
pub bar_alignment: BarAlignment,
/// Distribution and total number of characters/blocks can be placed in a line.
pub column_width_distribution: ColumnWidthDistribution,
/// Maximum number of levels that should be visualized.
pub max_depth: NonZeroUsize,
}

mod copy;
Expand Down
16 changes: 1 addition & 15 deletions src/visualizer/methods/initial_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ where
{
#[derive(Clone)]
struct Param<Name, NodeData> {
remaining_depth: usize,
index_as_child: usize,
ancestors: Vec<NodeInfo<Name, NodeData>>,
preceding_sibling: Option<NodeInfo<Name, NodeData>>,
Expand All @@ -69,11 +68,7 @@ where
Size: size::Size,
Act: FnMut(&'a DataTree<Name, Size>, Param<&'a Name, Size>) -> ActResult<&'a Name, Size>,
{
if param.remaining_depth == 0 {
return None;
}
let ActResult { node_info } = act(tree, param.clone());
let remaining_depth = param.remaining_depth - 1;
let mut preceding_sibling = None;
for (index_as_child, child) in tree.children().iter().enumerate() {
let mut ancestors = Vec::with_capacity(param.ancestors.len() + 1);
Expand All @@ -83,7 +78,6 @@ where
child,
act,
Param {
remaining_depth,
index_as_child,
ancestors,
preceding_sibling,
Expand All @@ -103,18 +97,12 @@ where
let Param {
index_as_child,
ancestors,
remaining_depth,
preceding_sibling,
} = param;
let name = node.name();
let node_data = node.size();
let row_index = initial_table.len();
debug_assert_op!(remaining_depth > 0);
let children_count = if remaining_depth != 1 {
node.children().len()
} else {
0
};
let children_count = node.children().len();
let fs_size = node.size().into();
let percentage = if total_fs_size == 0 {
"0%".to_string()
Expand All @@ -134,7 +122,6 @@ where
sibling_count,
index_as_child,
children_count,
remaining_depth,
};

initial_table.column_width.size_column_width =
Expand All @@ -151,7 +138,6 @@ where
ActResult { node_info }
},
Param {
remaining_depth: visualizer.max_depth.get(),
index_as_child: 0,
ancestors: Vec::new(),
preceding_sibling: None,
Expand Down
1 change: 0 additions & 1 deletion src/visualizer/methods/node_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,4 @@ pub struct NodeInfo<Name, NodeData> {
pub sibling_count: NonZeroUsize,
pub index_as_child: usize,
pub children_count: usize,
pub remaining_depth: usize,
}
6 changes: 1 addition & 5 deletions src/visualizer/methods/tree_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,7 @@ where
.map(|initial_row| {
let child_position =
ChildPosition::from_index(initial_row.index_as_child, initial_row.sibling_count);
let parenthood = if initial_row.remaining_depth == 0 {
Parenthood::Childless
} else {
Parenthood::from_children_count(initial_row.children_count)
};
let parenthood = Parenthood::from_children_count(initial_row.children_count);
let skeletal_component = TreeSkeletalComponent {
child_position,
parenthood,
Expand Down
1 change: 1 addition & 0 deletions tests/_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ where
panic!("Unexpected call to report_error: {error:?}")
}),
root: root.join(suffix),
max_depth: 10,
}
.pipe(DataTree::<OsStringDisplay, Size>::from)
.into_par_sorted(|left, right| left.name().cmp(right.name()))
Expand Down
3 changes: 1 addition & 2 deletions tests/cli_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use pipe_trait::Pipe;
use pretty_assertions::assert_eq;
use std::{
collections::BTreeSet,
convert::TryInto,
path::Path,
process::{Command, Output, Stdio},
};
Expand Down Expand Up @@ -133,6 +132,7 @@ fn fs_errors() {
root: workspace.to_path_buf(),
size_getter: GetApparentSize,
reporter: ErrorOnlyReporter::new(ErrorReport::SILENT),
max_depth: 10,
};
let mut data_tree: DataTree<OsStringDisplay, _> = builder.into();
data_tree.par_sort_by(|left, right| left.size().cmp(&right.size()).reverse());
Expand All @@ -143,7 +143,6 @@ fn fs_errors() {
direction: Direction::BottomUp,
bar_alignment: BarAlignment::Left,
column_width_distribution: ColumnWidthDistribution::total(100),
max_depth: 10.try_into().unwrap(),
};
let expected_stdout = format!("{visualizer}");
eprintln!("EXPECTED STDOUT:\n{}\n", &expected_stdout);
Expand Down
4 changes: 2 additions & 2 deletions tests/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type SampleTree = DataTree<SampleName, SampleData>;

fn sample_tree() -> SampleTree {
let dir = |name: &'static str, children: Vec<SampleTree>| {
SampleTree::dir(name.to_string(), 1024.into(), children)
SampleTree::dir(name.to_string(), 1024.into(), children, 10)
};
let file =
|name: &'static str, size: u64| SampleTree::file(name.to_string(), Bytes::from(size));
Expand Down Expand Up @@ -82,6 +82,7 @@ fn json_output() {
root: workspace.to_path_buf(),
size_getter: GetApparentSize,
reporter: ErrorOnlyReporter::new(ErrorReport::SILENT),
max_depth: 10,
};
let expected = builder
.pipe(DataTree::<_, Bytes>::from)
Expand Down Expand Up @@ -133,7 +134,6 @@ fn json_input() {
direction: Direction::BottomUp,
bar_alignment: BarAlignment::Left,
column_width_distribution: ColumnWidthDistribution::total(100),
max_depth: 10.try_into().unwrap(),
};
let expected = format!("{visualizer}");
let expected = expected.trim_end();
Expand Down
Loading