mirror of
https://github.com/bootandy/dust.git
synced 2026-06-08 11:29:05 +03:00
Use more rusty patterns and preallocate enough space
This commit is contained in:
+10
-11
@@ -109,18 +109,14 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn build_tree(biggest_ones: Vec<(String, u64)>, depth: Option<u64>) -> Node {
|
fn build_tree(biggest_ones: Vec<(String, u64)>, depth: Option<u64>) -> Node {
|
||||||
let mut top_parent = Node {
|
let mut top_parent = Node::default();
|
||||||
name: "".to_string(),
|
|
||||||
size: 0,
|
|
||||||
children: vec![],
|
|
||||||
};
|
|
||||||
|
|
||||||
// assume sorted order
|
// assume sorted order
|
||||||
for b in biggest_ones {
|
for b in biggest_ones {
|
||||||
let n = Node {
|
let n = Node {
|
||||||
name: b.0,
|
name: b.0,
|
||||||
size: b.1,
|
size: b.1,
|
||||||
children: vec![],
|
children: Vec::default(),
|
||||||
};
|
};
|
||||||
recursively_build_tree(&mut top_parent, n, depth)
|
recursively_build_tree(&mut top_parent, n, depth)
|
||||||
}
|
}
|
||||||
@@ -133,13 +129,16 @@ fn recursively_build_tree(parent_node: &mut Node, new_node: Node, depth: Option<
|
|||||||
Some(0) => return,
|
Some(0) => return,
|
||||||
Some(d) => Some(d - 1),
|
Some(d) => Some(d - 1),
|
||||||
};
|
};
|
||||||
for c in parent_node.children.iter_mut() {
|
if let Some(c) = parent_node
|
||||||
if new_node.name.starts_with(&c.name) {
|
.children
|
||||||
return recursively_build_tree(&mut *c, new_node, new_depth);
|
.iter_mut()
|
||||||
}
|
.find(|c| new_node.name.starts_with(&c.name))
|
||||||
}
|
{
|
||||||
|
recursively_build_tree(&mut *c, new_node, new_depth);
|
||||||
|
} else {
|
||||||
let temp = Box::<Node>::new(new_node);
|
let temp = Box::<Node>::new(new_node);
|
||||||
parent_node.children.push(temp);
|
parent_node.children.push(temp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
+18
-22
@@ -1,13 +1,14 @@
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use jwalk::WalkDir;
|
use jwalk::WalkDir;
|
||||||
|
|
||||||
mod platform;
|
mod platform;
|
||||||
use self::platform::*;
|
use self::platform::*;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Node {
|
pub struct Node {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub size: u64,
|
pub size: u64,
|
||||||
@@ -15,26 +16,25 @@ pub struct Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn simplify_dir_names(filenames: Vec<&str>) -> HashSet<String> {
|
pub fn simplify_dir_names(filenames: Vec<&str>) -> HashSet<String> {
|
||||||
let mut top_level_names: HashSet<String> = HashSet::new();
|
let mut top_level_names: HashSet<String> = HashSet::with_capacity(filenames.len());
|
||||||
|
let mut to_remove: Vec<String> = Vec::with_capacity(filenames.len());
|
||||||
|
|
||||||
for t in filenames {
|
for t in filenames {
|
||||||
let top_level_name = ensure_end_slash(t);
|
let top_level_name = ensure_end_slash(t);
|
||||||
let mut can_add = true;
|
let mut can_add = true;
|
||||||
let mut to_remove: Vec<String> = Vec::new();
|
|
||||||
|
|
||||||
for tt in top_level_names.iter() {
|
for tt in top_level_names.iter() {
|
||||||
let temp = tt.to_string();
|
if top_level_name.starts_with(tt) {
|
||||||
if top_level_name.starts_with(&temp) {
|
|
||||||
can_add = false;
|
can_add = false;
|
||||||
} else if tt.starts_with(&top_level_name) {
|
} else if tt.starts_with(&top_level_name) {
|
||||||
to_remove.push(temp);
|
to_remove.push(tt.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for tr in to_remove {
|
to_remove.sort_unstable();
|
||||||
top_level_names.remove(&tr);
|
top_level_names.retain(|tr| to_remove.binary_search(tr).is_err());
|
||||||
}
|
to_remove.clear();
|
||||||
if can_add {
|
if can_add {
|
||||||
top_level_names.insert(strip_end_slash(t));
|
top_level_names.insert(strip_end_slash(t).to_owned());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,10 +63,9 @@ pub fn ensure_end_slash(s: &str) -> String {
|
|||||||
new_name + "/"
|
new_name + "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn strip_end_slash(s: &str) -> String {
|
pub fn strip_end_slash(mut new_name: &str) -> &str {
|
||||||
let mut new_name = String::from(s);
|
|
||||||
while (new_name.ends_with('/') || new_name.ends_with("/.")) && new_name.len() > 1 {
|
while (new_name.ends_with('/') || new_name.ends_with("/.")) && new_name.len() > 1 {
|
||||||
new_name.pop();
|
new_name = &new_name[..new_name.len() - 1];
|
||||||
}
|
}
|
||||||
new_name
|
new_name
|
||||||
}
|
}
|
||||||
@@ -93,16 +92,13 @@ fn examine_dir(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// This path and all its parent paths have their counter incremented
|
// This path and all its parent paths have their counter incremented
|
||||||
let mut e_path = e.path();
|
for path_name in PathBuf::from(e.path()).ancestors() {
|
||||||
loop {
|
let path_name = path_name.to_string_lossy();
|
||||||
let path_name = e_path.to_string_lossy().to_string();
|
let s = data.entry(path_name.to_string()).or_insert(0);
|
||||||
let s = data.entry(path_name.clone()).or_insert(0);
|
|
||||||
*s += size;
|
*s += size;
|
||||||
if path_name == top_dir || path_name == "/" {
|
if path_name == top_dir {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
assert!(path_name != "");
|
|
||||||
e_path.pop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => *file_count_no_permission += 1,
|
None => *file_count_no_permission += 1,
|
||||||
@@ -124,7 +120,7 @@ pub fn sort_by_size_first_name_second(a: &(String, u64), b: &(String, u64)) -> O
|
|||||||
|
|
||||||
pub fn sort(data: HashMap<String, u64>) -> Vec<(String, u64)> {
|
pub fn sort(data: HashMap<String, u64>) -> Vec<(String, u64)> {
|
||||||
let mut new_l: Vec<(String, u64)> = data.iter().map(|(a, b)| (a.clone(), *b)).collect();
|
let mut new_l: Vec<(String, u64)> = data.iter().map(|(a, b)| (a.clone(), *b)).collect();
|
||||||
new_l.sort_by(|a, b| sort_by_size_first_name_second(&a, &b));
|
new_l.sort_unstable_by(sort_by_size_first_name_second);
|
||||||
new_l
|
new_l
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +137,7 @@ pub fn trim_deep_ones(
|
|||||||
max_depth: u64,
|
max_depth: u64,
|
||||||
top_level_names: &HashSet<String>,
|
top_level_names: &HashSet<String>,
|
||||||
) -> Vec<(String, u64)> {
|
) -> Vec<(String, u64)> {
|
||||||
let mut result: Vec<(String, u64)> = vec![];
|
let mut result: Vec<(String, u64)> = Vec::with_capacity(input.len() * top_level_names.len());
|
||||||
|
|
||||||
for name in top_level_names {
|
for name in top_level_names {
|
||||||
let my_max_depth = name.matches('/').count() + max_depth as usize;
|
let my_max_depth = name.matches('/').count() + max_depth as usize;
|
||||||
|
|||||||
Reference in New Issue
Block a user