ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/IO-AIO/bin/treescan
Revision: 1.10
Committed: Tue Oct 4 18:22:37 2011 UTC (12 years, 7 months ago) by root
Branch: MAIN
Changes since 1.9: +25 -7 lines
Log Message:
*** empty log message ***

File Contents

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