1 | use List::Util qw(sum); |
1 | use List::Util qw(sum); |
2 | |
2 | |
|
|
3 | use Coro::AIO (); |
3 | use Storable (); |
4 | use Storable (); |
4 | |
5 | |
5 | my $SD_VERSION = 1; |
6 | my $SD_VERSION = 1; |
6 | |
7 | |
7 | my $ignore = qr/ ^(?:robots.txt$|\.) /x; |
8 | my $ignore = qr/ ^(?:robots.txt$|\.) /x; |
… | |
… | |
30 | $prefix .= "$_/"; |
31 | $prefix .= "$_/"; |
31 | } |
32 | } |
32 | $data->{path} = $path; |
33 | $data->{path} = $path; |
33 | } |
34 | } |
34 | |
35 | |
35 | sub read_file { |
|
|
36 | local $/; |
|
|
37 | my $fh; |
|
|
38 | (open $fh, "<$_[0]\x00") ? <$fh> : () |
|
|
39 | } |
|
|
40 | |
|
|
41 | { |
36 | { |
42 | my $path = $self->{path}; |
37 | my $path = $self->{path}; |
43 | do { |
38 | do { |
44 | $data->{top} ||= read_file "$path.dols/top"; |
39 | Coro::AIO::aio_load "$path.dols/top", $data->{top} |
45 | $data->{bot} ||= read_file "$path.dols/bot"; |
40 | unless Coro::AIO::aio_stat "$path.dols/top"; |
|
|
41 | Coro::AIO::aio_load "$path.dols/top", $data->{bot} |
|
|
42 | unless Coro::AIO::aio_stat "$path.dols/bot"; |
46 | $path =~ s/[^\/]*\/+$// |
43 | $path =~ s/[^\/]*\/+$// |
47 | or die "malformed path: $path"; |
44 | or die "malformed path: $path"; |
48 | } while $path ne ""; |
45 | } while $path ne ""; |
49 | } |
46 | } |
50 | |
47 | |
51 | if (opendir my $dir, $self->{path}) { |
48 | my $entries = Coro::AIO::aio_readdir $self->{path}; |
|
|
49 | |
|
|
50 | { |
52 | my $dlen = 0; |
51 | my $dlen = 0; |
53 | my $flen = 0; |
52 | my $flen = 0; |
54 | my $slen = 0; |
53 | my $slen = 0; |
55 | for (sort readdir $dir) { |
54 | |
|
|
55 | for (sort @$entries) { |
56 | next if /$ignore/; |
56 | next if /$ignore/; |
|
|
57 | |
57 | stat "$self->{path}$_"; |
58 | Coro::AIO::aio_stat "$self->{path}$_"; |
58 | if (-d _) { |
59 | if (-d _) { |
59 | next unless 0555 == ((stat _)[2] & 0555); |
60 | next unless 0555 == ((stat _)[2] & 0555); |
60 | $dlen = length $_ if length $_ > $dlen; |
61 | $dlen = length $_ if length $_ > $dlen; |
61 | push @{$data->{d}}, $_; |
62 | push @{$data->{d}}, $_; |
62 | } else { |
63 | } else { |
… | |
… | |
70 | $data->{dlen} = $dlen; |
71 | $data->{dlen} = $dlen; |
71 | $data->{flen} = $flen; |
72 | $data->{flen} = $flen; |
72 | $data->{slen} = $slen; |
73 | $data->{slen} = $slen; |
73 | } |
74 | } |
74 | |
75 | |
75 | $data; |
76 | $data |
76 | } |
77 | } |
77 | |
78 | |
78 | sub conn::get_statdata { |
79 | sub conn::get_statdata { |
79 | my $self = shift; |
80 | my $self = shift; |
80 | |
81 | |
81 | my $mtime = $self->{stat}[9]; |
82 | my $mtime = $self->{stat}[9]; |
|
|
83 | my $statdata; |
82 | |
84 | |
83 | $statdata = $diridx{$self->{path}}; |
85 | # $statdata = $diridx{$self->{path}}; |
84 | |
86 | # |
85 | if (defined $statdata) { |
87 | # if (defined $statdata) { |
86 | $$statdata = Storable::thaw $statdata; |
88 | # $$statdata = Storable::thaw $statdata; |
87 | return $$statdata |
89 | # return $$statdata |
88 | if $$statdata->{version} == $SD_VERSION |
90 | # if $$statdata->{version} == $SD_VERSION |
89 | && $$statdata->{mtime} == $mtime; |
91 | # && $$statdata->{mtime} == $mtime; |
90 | } |
92 | # } |
91 | |
93 | |
92 | $self->slog(8, "creating index cache for $self->{path}"); |
94 | # $self->slog(8, "creating index cache for $self->{path}"); |
93 | |
95 | |
94 | $$statdata = $self->gen_statdata; |
96 | $$statdata = $self->gen_statdata; |
95 | $$statdata->{version} = $SD_VERSION; |
97 | $$statdata->{version} = $SD_VERSION; |
96 | $$statdata->{mtime} = $mtime; |
98 | $$statdata->{mtime} = $mtime; |
97 | |
99 | |
98 | $diridx{$self->{path}} = Storable::freeze $$statdata; |
100 | # $diridx{$self->{path}} = Storable::freeze $$statdata; |
99 | (tied %diridx)->db_sync; |
101 | # (tied %diridx)->db_sync; |
100 | |
102 | |
101 | $$statdata; |
103 | $$statdata |
102 | } |
104 | } |
103 | |
105 | |
104 | sub handle_redirect { # unused |
106 | sub handle_redirect { # unused |
105 | if (-f ".redirect") { |
107 | if (-f ".redirect") { |
106 | if (open my $fh, "<.redirect") { |
108 | if (open my $fh, "<.redirect") { |