ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/IO-AIO/bin/treescan
(Generate patch)

Comparing IO-AIO/bin/treescan (file contents):
Revision 1.3 by root, Sun Jun 7 22:28:05 2009 UTC vs.
Revision 1.13 by root, Tue Oct 4 18:29:04 2011 UTC

3# inspired by treescan by Jamie Lokier <jamie@imbolc.ucc.ie> 3# inspired by treescan by Jamie Lokier <jamie@imbolc.ucc.ie>
4# about 40% faster than the original version (on my fs and raid :) 4# about 40% faster than the original version (on my fs and raid :)
5 5
6use strict; 6use strict;
7use Getopt::Long; 7use Getopt::Long;
8use Time::HiRes ();
8use IO::AIO; 9use IO::AIO;
9 10
10our $VERSION = $IO::AIO::VERSION; 11our $VERSION = $IO::AIO::VERSION;
11 12
12Getopt::Long::Configure ("bundling", "no_ignore_case", "require_order", "auto_help", "auto_version"); 13Getopt::Long::Configure ("bundling", "no_ignore_case", "require_order", "auto_help", "auto_version");
13 14
14my ($opt_silent, $opt_print0, $opt_stat, $opt_nodirs, $opt_nofiles); 15my ($opt_silent, $opt_print0, $opt_stat, $opt_nodirs,
16 $opt_nofiles, $opt_grep, $opt_progress);
15 17
16GetOptions 18GetOptions
17 "quiet|q" => \$opt_silent, 19 "quiet|q" => \$opt_silent,
18 "print0|0" => \$opt_print0, 20 "print0|0" => \$opt_print0,
19 "stat|s" => \$opt_stat, 21 "stat|s" => \$opt_stat,
20 "dirs|d" => \$opt_nofiles, 22 "dirs|d" => \$opt_nofiles,
21 "files|f" => \$opt_nodirs, 23 "files|f" => \$opt_nodirs,
24 "grep|g=s" => \$opt_grep,
25 "progress|p" => \$opt_progress,
22 or die "Usage: try $0 --help"; 26 or die "Usage: try $0 --help";
23 27
24@ARGV = "." unless @ARGV; 28@ARGV = "." unless @ARGV;
25 29
30$opt_grep &&= qr{$opt_grep}s;
31
32my ($n_dirs, $n_files, $n_stats) = (0, 0, 0);
33my ($n_last, $n_start) = (Time::HiRes::time) x 2;
34
26sub printfn { 35sub printfn {
27 my ($prefix, $files, $suffix) = @_; 36 my ($prefix, $files, $suffix) = @_;
28 37
38 if ($opt_grep) {
39 @$files = grep "$prefix$_" =~ $opt_grep, @$files;
40 }
41
29 if ($opt_print0) { 42 if ($opt_print0) {
30 print map "$prefix$_$suffix\0", @$files; 43 print map "$prefix$_$suffix\0", @$files;
31 } elsif (!$opt_silent) { 44 } elsif (!$opt_silent) {
32 print map "$prefix$_$suffix\n", @$files; 45 print map "$prefix$_$suffix\n", @$files;
33 } 46 }
36sub scan { 49sub scan {
37 my ($path) = @_; 50 my ($path) = @_;
38 51
39 $path .= "/"; 52 $path .= "/";
40 53
54 IO::AIO::poll_cb;
55
56 if ($opt_progress and $n_last + 1 < Time::HiRes::time) {
57 $n_last = Time::HiRes::time;
58 printf STDERR "\r%d dirs %d files %d stats %g stats/s ", $n_dirs, $n_files, $n_stats, $n_stats / ($n_last - $n_start)
59 if $opt_progress;
60 }
61
41 aioreq_pri -1; 62 aioreq_pri -1;
63 ++$n_dirs;
42 aio_scandir $path, 8, sub { 64 aio_scandir $path, 8, sub {
43 my ($dirs, $files) = @_; 65 my ($dirs, $files) = @_
66 or warn "$path: $!\n";
44 67
45 printfn "", [$path] unless $opt_nodirs; 68 printfn "", [$path] unless $opt_nodirs;
46 printfn $path, $files unless $opt_nofiles; 69 printfn $path, $files unless $opt_nofiles;
47 70
71 $n_files += @$files;
72
48 if ($opt_stat) { 73 if ($opt_stat) {
74 aio_wd $path, sub {
75 my $wd = shift;
76
49 aio_lstat "$path$_" for @$files; 77 aio_lstat [$wd, $_] for @$files;
78 $n_stats += @$files;
79 };
50 } 80 }
51 81
52 &scan ("$path$_") for @$dirs; 82 &scan ("$path$_") for @$dirs;
53 }; 83 };
54} 84}
55 85
56IO::AIO::max_outstanding 64; 86IO::AIO::max_outstanding 100; # two fds per directory, so limit accordingly
57IO::AIO::min_parallel 32; 87IO::AIO::min_parallel 20;
58 88
59for my $seed (@ARGV) { 89for my $seed (@ARGV) {
60 $seed =~ s/\/+$//; 90 $seed =~ s/\/+$//;
91 ++$n_stats;
61 aio_lstat "$seed/.", sub { 92 aio_lstat "$seed/.", sub {
93 if ($_[0]) {
94 print STDERR "$seed: $!\n";
62 if (-d _) { 95 } elsif (-d _) {
63 scan $seed; 96 scan $seed;
64 } else { 97 } else {
65 printfn "", $seed, "/"; 98 printfn "", $seed, "/";
66 } 99 }
67 }; 100 };

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines