summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPiotr Wach <pwach@bloomberg.net>2024-01-10 22:30:20 +0000
committerPiotr Wach <pwach@bloomberg.net>2024-01-14 15:01:10 +0000
commit226cbb8b2d6388ddd7a7e48fdac1a4db2ee75474 (patch)
tree1522244207da554e65d209e7f1c203fd13f6912f /src
parent30d8dd5fb54ef6db8b4444524407f15db25d7b02 (diff)
Traverse children vs parent & fix parent node size after refresh
Diffstat (limited to 'src')
-rw-r--r--src/aggregate.rs2
-rw-r--r--src/common.rs3
-rw-r--r--src/interactive/app/eventloop.rs41
-rw-r--r--src/interactive/app/handlers.rs2
-rw-r--r--src/interactive/app/terminal.rs2
-rw-r--r--src/interactive/app/tree_view.rs5
-rw-r--r--src/traverse.rs32
7 files changed, 55 insertions, 32 deletions
diff --git a/src/aggregate.rs b/src/aggregate.rs
index ec4d5ae..356a1a9 100644
--- a/src/aggregate.rs
+++ b/src/aggregate.rs
@@ -41,7 +41,7 @@ pub fn aggregate(
continue;
}
};
- for entry in walk_options.iter_from_path(path.as_ref(), device_id) {
+ for entry in walk_options.iter_from_path(path.as_ref(), device_id, false) {
stats.entries_traversed += 1;
progress.throttled(|| {
if let Some(err) = err.as_mut() {
diff --git a/src/common.rs b/src/common.rs
index 254fbbf..8bd0451 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -176,11 +176,12 @@ pub struct WalkOptions {
type WalkDir = jwalk::WalkDirGeneric<((), Option<Result<std::fs::Metadata, jwalk::Error>>)>;
impl WalkOptions {
- pub fn iter_from_path(&self, root: &Path, root_device_id: u64) -> WalkDir {
+ pub fn iter_from_path(&self, root: &Path, root_device_id: u64, skip_root: bool) -> WalkDir {
let ignore_dirs = self.ignore_dirs.clone();
let cwd = std::env::current_dir().unwrap_or_else(|_| root.to_owned());
WalkDir::new(root)
.follow_links(false)
+ .min_depth(if skip_root { 1 } else { 0 })
.sort(match self.sorting {
TraversalSorting::None => false,
TraversalSorting::AlphabeticalByFileName => true,
diff --git a/src/interactive/app/eventloop.rs b/src/interactive/app/eventloop.rs
index b370f78..5ce8cd6 100644
--- a/src/interactive/app/eventloop.rs
+++ b/src/interactive/app/eventloop.rs
@@ -66,7 +66,7 @@ impl AppState {
pub fn traverse(&mut self, traversal: &Traversal, input: Vec<PathBuf>) -> Result<()> {
let background_traversal =
- BackgroundTraversal::start(traversal.root_index, &self.walk_options, input)?;
+ BackgroundTraversal::start(traversal.root_index, &self.walk_options, input, false)?;
self.navigation_mut().view_root = traversal.root_index;
self.active_traversal = Some(background_traversal);
Ok(())
@@ -125,7 +125,7 @@ impl AppState {
crossbeam::select! {
recv(events) -> event => {
let Ok(event) = event else {
- return Ok(Some(WalkResult { num_errors: 0 }));
+ return Ok(Some(WalkResult { num_errors: traversal.io_errors }));
};
let res = self.process_terminal_event(
window,
@@ -153,7 +153,7 @@ impl AppState {
}
} else {
let Ok(event) = events.recv() else {
- return Ok(Some(WalkResult { num_errors: 0 }));
+ return Ok(Some(WalkResult { num_errors: traversal.io_errors }));
};
let result =
self.process_terminal_event(window, traversal, display, terminal, event)?;
@@ -309,23 +309,30 @@ impl AppState {
}
fn refresh(&mut self, tree: &mut TreeView<'_>, what: Refresh) -> anyhow::Result<()> {
+ // TODO: we should refresh parent_idx not selected index
match what {
Refresh::Selected => {
- if let Some(selected) = self.navigation().selected {
- let parent_idx = tree
- .fs_parent_of(selected)
- .expect("there is always a parent to a selection");
- let path = tree.path_of(selected);
- tree.remove_entries(selected);
- tree.recompute_sizes_recursively(parent_idx);
- self.entries = tree.sorted_entries(parent_idx, self.sorting);
- self.navigation_mut().selected = self.entries.first().map(|e| e.index);
- self.active_traversal = Some(BackgroundTraversal::start(
- parent_idx,
- &self.walk_options,
- vec![path],
- )?);
+ let mut path = tree.path_of(self.navigation().view_root);
+ if path.to_str().unwrap() == "" {
+ path = PathBuf::from(".");
}
+ log::info!("Refreshing {:?}", path);
+
+ let entries_deleted = tree.remove_entries(self.navigation().view_root, false);
+ log::info!("Deleted {entries_deleted} entries");
+
+ tree.recompute_sizes_recursively(self.navigation().view_root);
+ self.entries = tree.sorted_entries(self.navigation().view_root, self.sorting);
+ self.navigation_mut().selected = self.entries.first().map(|e| e.index);
+
+ self.active_traversal = Some(BackgroundTraversal::start(
+ self.navigation().view_root,
+ &self.walk_options,
+ vec![path],
+ true,
+ )?);
+
+ self.received_events = false;
}
Refresh::AllInView => {
log::info!("Not implemented")
diff --git a/src/interactive/app/handlers.rs b/src/interactive/app/handlers.rs
index 754fa51..32a63ab 100644
--- a/src/interactive/app/handlers.rs
+++ b/src/interactive/app/handlers.rs
@@ -312,7 +312,7 @@ impl AppState {
let parent_idx = tree_view
.fs_parent_of(index)
.expect("us being unable to delete the root index");
- let entries_deleted = tree_view.remove_entries(index);
+ let entries_deleted = tree_view.remove_entries(index, true);
if !tree_view.exists(self.navigation().view_root) {
self.go_to_root(tree_view);
diff --git a/src/interactive/app/terminal.rs b/src/interactive/app/terminal.rs
index 64c68af..6672188 100644
--- a/src/interactive/app/terminal.rs
+++ b/src/interactive/app/terminal.rs
@@ -120,7 +120,7 @@ mod tests {
return Ok(res);
}
}
- Ok(WalkResult { num_errors: 0 })
+ Ok(WalkResult { num_errors: self.traversal.io_errors })
}
}
}
diff --git a/src/interactive/app/tree_view.rs b/src/interactive/app/tree_view.rs
index 74ec4fa..2126206 100644
--- a/src/interactive/app/tree_view.rs
+++ b/src/interactive/app/tree_view.rs
@@ -59,11 +59,14 @@ impl TreeView<'_> {
current_path(&self.traversal.tree, view_root, self.glob_tree_root)
}
- pub fn remove_entries(&mut self, index: TreeIndex) -> usize {
+ pub fn remove_entries(&mut self, index: TreeIndex, remove_index: bool) -> usize {
let mut entries_deleted = 0;
let mut bfs = Bfs::new(self.tree(), index);
while let Some(nx) = bfs.next(&self.tree()) {
+ if nx == index && !remove_index {
+ continue;
+ }
self.tree_mut().remove_node(nx);
self.traversal.entries_traversed -= 1;
entries_deleted += 1;
diff --git a/src/traverse.rs b/src/traverse.rs
index 6c24788..b879698 100644
--- a/src/traverse.rs
+++ b/src/traverse.rs
@@ -72,9 +72,9 @@ pub struct Traversal {
}
impl Traversal {
- pub fn recompute_root_size(&self) -> u128 {
+ pub fn recompute_node_size(&self, node_index: TreeIndex) -> u128 {
self.tree
- .neighbors_directed(self.root_index, Direction::Outgoing)
+ .neighbors_directed(node_index, Direction::Outgoing)
.map(|idx| get_size_or_panic(&self.tree, idx))
.sum()
}
@@ -134,6 +134,7 @@ pub enum TraversalEvent {
/// An in-progress traversal which exposes newly obtained entries
pub struct BackgroundTraversal {
walk_options: WalkOptions,
+ root_idx: TreeIndex,
previous_node_idx: TreeIndex,
parent_node_idx: TreeIndex,
directory_info_per_depth_level: Vec<EntryInfo>,
@@ -141,6 +142,7 @@ pub struct BackgroundTraversal {
previous_depth: usize,
inodes: InodeFilter,
throttle: Option<Throttle>,
+ skip_root: bool,
pub event_rx: Receiver<TraversalEvent>,
}
@@ -151,6 +153,7 @@ impl BackgroundTraversal {
root_idx: TreeIndex,
walk_options: &WalkOptions,
input: Vec<PathBuf>,
+ skip_root: bool,
) -> anyhow::Result<BackgroundTraversal> {
let (entry_tx, entry_rx) = crossbeam::channel::bounded(100);
std::thread::Builder::new()
@@ -160,6 +163,7 @@ impl BackgroundTraversal {
let mut io_errors: u64 = 0;
move || {
for root_path in input.into_iter() {
+ log::info!("Walking {root_path:?}");
let device_id = match crossdev::init(root_path.as_ref()) {
Ok(id) => id,
Err(_) => {
@@ -170,9 +174,10 @@ impl BackgroundTraversal {
let root_path = Arc::new(root_path);
for entry in walk_options
- .iter_from_path(root_path.as_ref(), device_id)
+ .iter_from_path(root_path.as_ref(), device_id, skip_root)
.into_iter()
{
+ log::info!("{:?}", entry);
if entry_tx
.send(TraversalEvent::Entry(
entry,
@@ -195,6 +200,7 @@ impl BackgroundTraversal {
Ok(Self {
walk_options: walk_options.clone(),
+ root_idx,
previous_node_idx: root_idx,
parent_node_idx: root_idx,
directory_info_per_depth_level: Vec::new(),
@@ -202,6 +208,7 @@ impl BackgroundTraversal {
previous_depth: 0,
inodes: InodeFilter::default(),
throttle: Some(Throttle::new(Duration::from_millis(250), None)),
+ skip_root,
event_rx: entry_rx,
})
}
@@ -223,12 +230,17 @@ impl BackgroundTraversal {
t.entries_traversed += 1;
let mut data = EntryData::default();
match entry {
- Ok(entry) => {
- data.name = if entry.depth < 1 {
- (*root_path).clone()
+ Ok(mut entry) => {
+ if self.skip_root {
+ entry.depth = entry.depth - 1;
+ data.name = entry.file_name.into()
} else {
- entry.file_name.into()
- };
+ data.name = if entry.depth < 1 {
+ (*root_path).clone()
+ } else {
+ entry.file_name.into()
+ }
+ }
let mut file_size = 0u128;
let mut mtime: SystemTime = UNIX_EPOCH;
@@ -360,10 +372,10 @@ impl BackgroundTraversal {
);
self.parent_node_idx = parent_or_panic(&mut t.tree, self.parent_node_idx);
}
- let root_size = t.recompute_root_size();
+ let root_size = t.recompute_node_size(self.root_idx);
set_entry_info_or_panic(
&mut t.tree,
- t.root_index,
+ self.root_idx,
EntryInfo {
size: root_size,
entries_count: (t.entries_traversed > 0).then_some(t.entries_traversed),