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.1 by root, Mon Sep 10 11:24:20 2007 UTC vs.
Revision 1.14 by root, Tue Oct 4 18:33:26 2011 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines