Skip to content

Commit

Permalink
suppress size algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
solidiquis committed Nov 29, 2023
1 parent 93d79b8 commit 867859b
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 68 deletions.
10 changes: 7 additions & 3 deletions src/file/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,10 @@ impl File {
}

pub fn display_path<'a>(&'a self, path_prefix: Option<&'a Path>) -> DisplayPath<'a> {
DisplayPath { file: self, path_prefix }
DisplayPath {
file: self,
path_prefix,
}
}

#[cfg(unix)]
Expand Down Expand Up @@ -207,9 +210,10 @@ impl Display for DisplayPath<'_> {
let display = match self.path_prefix {
Some(prefix) => {
let path = self.file.path();
path.strip_prefix(prefix).map_or_else(|_| path.display(), |p| p.display())
path.strip_prefix(prefix)
.map_or_else(|_| path.display(), |p| p.display())
},
None => self.file.path().display()
None => self.file.path().display(),
};

let link_target = self.file.symlink_target().map(|p| p.canonicalize());
Expand Down
23 changes: 8 additions & 15 deletions src/file/order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,11 @@ pub type FileComparator = dyn Fn(&File, &File) -> Ordering;
/// Yields function pointer to the appropriate `File` comparator.
pub fn comparator(sort: Sort, dir_order: DirOrder) -> Option<Box<FileComparator>> {
match dir_order {
DirOrder::First if matches!(sort, Sort::None) => Some(Box::new(move |a, b| {
dir_first_comparator(a, b)
})),
DirOrder::First if matches!(sort, Sort::None) => Some(Box::new(dir_first_comparator)),
DirOrder::First => Some(Box::new(move |a, b| {
dir_first_comparator_with_fallback(a, b, base_comparator(sort))
})),
DirOrder::Last if matches!(sort, Sort::None) => Some(Box::new(move |a, b| {
dir_last_comparator(a, b)
})),
DirOrder::Last if matches!(sort, Sort::None) => Some(Box::new(dir_last_comparator)),
DirOrder::Last => Some(Box::new(move |a, b| {
dir_last_comparator_with_fallback(a, b, base_comparator(sort))
})),
Expand All @@ -43,7 +39,7 @@ fn dir_first_comparator(a: &File, b: &File) -> Ordering {
match (a.is_dir(), b.is_dir()) {
(true, false) => Ordering::Greater,
(false, true) => Ordering::Less,
_ => Ordering::Equal
_ => Ordering::Equal,
}
}

Expand All @@ -61,14 +57,11 @@ fn dir_last_comparator_with_fallback(
}

/// Orders directories last relative to all other file-types.
fn dir_last_comparator(
a: &File,
b: &File,
) -> Ordering {
fn dir_last_comparator(a: &File, b: &File) -> Ordering {
match (a.is_dir(), b.is_dir()) {
(true, false) => Ordering::Less,
(false, true) => Ordering::Greater,
_ => Ordering::Equal
_ => Ordering::Equal,
}
}

Expand All @@ -90,9 +83,9 @@ fn base_comparator(sort_type: Sort) -> Box<FileComparator> {
}

mod time_stamping {
pub(self) use super::File;
pub(self) use core::cmp::Ordering;
pub(self) use std::time::SystemTime;
use super::File;
use core::cmp::Ordering;
use std::time::SystemTime;

pub mod accessed {
use super::*;
Expand Down
115 changes: 68 additions & 47 deletions src/file/tree/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use super::order::{self, FileComparator};
use super::order;
use crate::{
error::prelude::*,
file::File,
user::{args::{Layout, SortType, Sort}, column, Context},
user::{
args::{Layout, Sort, SortType},
column, Context,
},
};
use ahash::{HashMap, HashSet};
use indextree::{Arena, NodeId};
Expand Down Expand Up @@ -128,9 +131,11 @@ impl Tree {
comparator(node_a, node_b)
});

all_dirents.into_iter().for_each(|n| root_id.append(n, &mut arena));
}
_ => {
all_dirents
.into_iter()
.for_each(|n| root_id.append(n, &mut arena));
},
_ => {
for (dir_id, dirsize) in dirsize_map.into_iter() {
let dir = arena[dir_id].get_mut();
*dir.size_mut() += dirsize;
Expand Down Expand Up @@ -178,51 +183,72 @@ impl Tree {
root_id,
} = Self::load(ctx)?;

let mut dir_stack = vec![root_id];

'outer: while let Some(node_id) = dir_stack.last() {
let current_dir = *node_id;

let current_node_path = arena[current_dir].get().path();

let Some(dirents) = branches.get_mut(current_node_path) else {
dir_stack.pop();
continue;
#[cfg(unix)]
macro_rules! update_metadata {
($dirent_id:expr) => {
let dirent = arena[$dirent_id].get();
if let Ok(inode) = dirent.inode() {
column_metadata.update_inode_attr_widths(&inode);
}
};
}

while let Some(dirent_node_id) = dirents.pop() {
current_dir.append(dirent_node_id, &mut arena);
match ctx.sort_type {
SortType::Flat if matches!(ctx.layout, Layout::Flat) => {
let mut all_dirents = branches
.values()
.flatten()
.filter_map(|n| (*n != root_id).then_some(*n))
.collect::<Vec<_>>();

let dirent_node = arena[dirent_node_id].get();
if let Some(comparator) = order::comparator(Sort::None, ctx.dir_order) {
all_dirents.sort_by(|id_a, id_b| {
let node_a = arena[*id_a].get();
let node_b = arena[*id_b].get();
comparator(node_a, node_b)
});
}

#[cfg(unix)]
match dirent_node.inode() {
Ok(value) => {
column_metadata.update_inode_attr_widths(&value);
value
},
Err(err) => {
log::warn!(
"Failed to query inode of {}: {err}",
dirent_node.path().display(),
);
continue;
},
};
for dirent_id in all_dirents {
root_id.append(dirent_id, &mut arena);

if dirent_node.file_type().is_some_and(|f| f.is_dir()) {
dir_stack.push(dirent_node_id);
continue 'outer;
#[cfg(unix)]
update_metadata!(dirent_id);
}
}
},
_ => {
let dirs = arena
.iter()
.filter_map(|node| {
if node.get().is_dir() {
arena
.get_node_id(node)
.map(|n| (node.get().path().to_path_buf(), n))
} else {
None
}
})
.collect::<Vec<_>>();

dir_stack.pop();
}
dirs.into_iter().for_each(|(path, dir)| {
if let Some(mut dirents) = branches.remove(&path) {
if let Some(comparator) = order::comparator(Sort::None, ctx.dir_order) {
dirents.sort_by(|id_a, id_b| {
let node_a = arena[*id_a].get();
let node_b = arena[*id_b].get();
comparator(node_a, node_b)
});
}

if !matches!(ctx.sort, Sort::Size | Sort::Rsize) {
if let Some(comparator) = order::comparator(ctx.sort, ctx.dir_order) {
Self::tree_sort(root_id, &mut arena, comparator);
}
for dirent_id in dirents {
dir.append(dirent_id, &mut arena);

#[cfg(unix)]
update_metadata!(dirent_id);
}
}
});
},
}

let tree = Self { root_id, arena };
Expand Down Expand Up @@ -291,11 +317,6 @@ impl Tree {
pub fn arena(&self) -> &Arena<File> {
&self.arena
}

/// Sort [`File`]s in the `arena` with the provided `comparator`.
pub fn tree_sort(root_id: NodeId, arena: &mut Arena<File>, comparator: Box<FileComparator>) {
todo!()
}
}

impl Deref for Tree {
Expand Down
4 changes: 2 additions & 2 deletions src/render/row/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pub fn formatter<'a>(buf: &'a mut String, ctx: &'a Context) -> Result<RowFormatt
let long_format = long::Format::new(file, ctx);
writeln!(buf, "{long_format} {prefix}{name}")
})),
}
},
}
}

Expand Down Expand Up @@ -117,6 +117,6 @@ pub fn formatter<'a>(buf: &'a mut String, ctx: &'a Context) -> Result<RowFormatt
writeln!(buf, "{size:>max_size_width$} {prefix}{name}")
}))
}
}
},
}
}
2 changes: 1 addition & 1 deletion src/user/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ pub enum SortType {
#[default]
Tree,
/// Sort directory entries relative to all directory entries
Flat
Flat,
}

/// How directories should be ordered relative to regular files.
Expand Down

0 comments on commit 867859b

Please sign in to comment.