1
1
extern crate humansize;
2
2
extern crate ignore;
3
3
extern crate num_cpus;
4
+ #[ macro_use]
5
+ extern crate clap;
4
6
5
7
use std:: collections:: HashSet ;
6
8
use std:: os:: unix:: fs:: MetadataExt ;
9
+ use std:: path:: Path ;
7
10
use std:: sync:: mpsc:: channel;
8
11
use std:: thread;
9
12
13
+ use clap:: { App , AppSettings , Arg } ;
10
14
use humansize:: { file_size_opts, FileSize } ;
11
15
use ignore:: WalkBuilder ;
12
16
13
- fn main ( ) {
14
- let mut builder = WalkBuilder :: new ( "./" ) ;
17
+ fn get_size < P : AsRef < Path > > ( p : P , num_threads : usize ) -> u64 {
18
+ let mut builder = WalkBuilder :: new ( p ) ;
15
19
builder. hidden ( false ) ;
16
20
builder. parents ( false ) ;
17
21
builder. ignore ( false ) ;
@@ -20,12 +24,7 @@ fn main() {
20
24
builder. git_exclude ( false ) ;
21
25
builder. follow_links ( false ) ;
22
26
23
- // Setting the number of threads to 3x the number of cores is a good tradeoff between
24
- // cold-cache and warm-cache runs. For a cold disk cache, we are limited by disk IO and
25
- // therefore want the number of threads to be rather large in order for the IO scheduler to
26
- // plan ahead. On the other hand, the number of threads shouldn't be too high for warm disk
27
- // caches where we would otherwise pay a higher synchronization overhead.
28
- builder. threads ( 3 * num_cpus:: get ( ) ) ;
27
+ builder. threads ( num_threads) ;
29
28
30
29
let walker = builder. build_parallel ( ) ;
31
30
@@ -44,11 +43,8 @@ fn main() {
44
43
total += size;
45
44
}
46
45
}
47
- println ! (
48
- "{} ({} bytes)" ,
49
- total. file_size( file_size_opts:: DECIMAL ) . unwrap( ) ,
50
- total
51
- ) ;
46
+
47
+ total
52
48
} ) ;
53
49
54
50
walker. run ( || {
@@ -86,5 +82,46 @@ fn main() {
86
82
} ) ;
87
83
88
84
drop ( tx) ;
89
- receiver_thread. join ( ) . ok ( ) ;
85
+ receiver_thread. join ( ) . unwrap ( )
86
+ }
87
+
88
+ fn print_result ( size : u64 ) {
89
+ println ! (
90
+ "{} ({} bytes)" ,
91
+ size. file_size( file_size_opts:: DECIMAL ) . unwrap( ) ,
92
+ size
93
+ ) ;
94
+ }
95
+
96
+ fn main ( ) {
97
+ let app = App :: new ( crate_name ! ( ) )
98
+ . setting ( AppSettings :: ColorAuto )
99
+ . setting ( AppSettings :: ColoredHelp )
100
+ . setting ( AppSettings :: DeriveDisplayOrder )
101
+ . setting ( AppSettings :: UnifiedHelpMessage )
102
+ . version ( crate_version ! ( ) )
103
+ . about ( "Compute disk usage for the current directory" )
104
+ . arg (
105
+ Arg :: with_name ( "threads" )
106
+ . long ( "threads" )
107
+ . short ( "j" )
108
+ . value_name ( "N" )
109
+ . takes_value ( true )
110
+ . help ( "Set the number of threads (default: 3 x num cores)" ) ,
111
+ ) ;
112
+
113
+ let matches = app. get_matches ( ) ;
114
+
115
+ // Setting the number of threads to 3x the number of cores is a good tradeoff between
116
+ // cold-cache and warm-cache runs. For a cold disk cache, we are limited by disk IO and
117
+ // therefore want the number of threads to be rather large in order for the IO scheduler to
118
+ // plan ahead. On the other hand, the number of threads shouldn't be too high for warm disk
119
+ // caches where we would otherwise pay a higher synchronization overhead.
120
+ let num_threads = matches
121
+ . value_of ( "threads" )
122
+ . and_then ( |t| t. parse ( ) . ok ( ) )
123
+ . unwrap_or ( 3 * num_cpus:: get ( ) ) ;
124
+
125
+ let size = get_size ( "." , num_threads) ;
126
+ print_result ( size) ;
90
127
}
0 commit comments