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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines