summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorsharkdp <davidpeter@web.de>2018-11-01 17:47:33 +0100
committersharkdp <davidpeter@web.de>2018-11-01 17:52:30 +0100
commitc602b8581d8edc6391b85292295fe01e482ea934 (patch)
tree1edcfb0303399718423ee0d5e4b8f5570b41d6dd /src
Initial commit
Diffstat (limited to 'src')
-rw-r--r--src/main.rs75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..62fd088
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,75 @@
+extern crate humansize;
+extern crate ignore;
+extern crate num_cpus;
+
+use std::collections::HashSet;
+use std::os::unix::fs::MetadataExt;
+use std::sync::mpsc::channel;
+use std::thread;
+
+use humansize::{file_size_opts, FileSize};
+use ignore::WalkBuilder;
+
+fn main() {
+ let mut builder = WalkBuilder::new("./");
+ builder.hidden(false);
+ builder.parents(false);
+ builder.ignore(false);
+ builder.git_global(false);
+ builder.git_ignore(false);
+ builder.git_exclude(false);
+ builder.follow_links(false);
+
+ builder.threads(num_cpus::get());
+
+ let walker = builder.build_parallel();
+
+ let (tx, rx) = channel();
+
+ let receiver_thread = thread::spawn(move || {
+ let mut total = 0;
+ let mut ids = HashSet::new();
+ for (unique_id, size) in rx {
+ if let Some(unique_id) = unique_id {
+ // Only count this entry if the ID has not been seen
+ if ids.insert(unique_id) {
+ total += size;
+ }
+ } else {
+ total += size;
+ }
+ }
+ println!(
+ "{} ({} bytes)",
+ total.file_size(file_size_opts::DECIMAL).unwrap(),
+ total
+ );
+ });
+
+ walker.run(|| {
+ let tx = tx.clone();
+ Box::new(move |result| {
+ if let Ok(entry) = result {
+ let metadata = entry.metadata().unwrap();
+
+ // If the entry has more than one hard link, generate
+ // a unique ID consisting of device and inode in order
+ // not to count this entry twice.
+ let unique_id = if metadata.is_file() && metadata.nlink() > 1 {
+ Some((metadata.dev(), metadata.ino()))
+ } else {
+ None
+ };
+
+ let size = metadata.len();
+
+ tx.send((unique_id, size)).unwrap();
+ }
+
+ return ignore::WalkState::Continue;
+ })
+ });
+
+ drop(tx);
+ receiver_thread.join().unwrap();
+}