diff options
author | Eric Wong <e@80x24.org> | 2023-12-29 18:05:14 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2023-12-30 06:44:02 +0000 |
commit | 5aab49f319679cf7912f1abf4914272e5112e247 (patch) | |
tree | feb93cd9b7062e61dd547b96fce91b5231bade88 /lib/PublicInbox/MdirSort.pm | |
parent | cf977e706b07e80f394570a393eb2169b9b9a1a7 (diff) | |
download | public-inbox-5aab49f319679cf7912f1abf4914272e5112e247.tar.gz |
The MH format is widely-supported and used by various MUAs such as mutt and sylpheed, and a MH-like format is used by mlmmj for archives, as well. Locking implementations for writes are inconsistent, so this commit doesn't support writes, yet. inotify|EVFILT_VNODE watches aren't supported, yet, but that'll have to come since MH allows packing unused integers and renaming files.
Diffstat (limited to 'lib/PublicInbox/MdirSort.pm')
-rw-r--r-- | lib/PublicInbox/MdirSort.pm | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/lib/PublicInbox/MdirSort.pm b/lib/PublicInbox/MdirSort.pm new file mode 100644 index 00000000..6bd9fb6c --- /dev/null +++ b/lib/PublicInbox/MdirSort.pm @@ -0,0 +1,46 @@ +# Copyright (C) all contributors <meta@public-inbox.org> +# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt> + +# used for sorting MH (and (TODO) Maildir) names +# TODO: consider sort(1) to parallelize sorting of gigantic directories +package PublicInbox::MdirSort; +use v5.12; +use Time::HiRes (); +use parent qw(Exporter); +use Fcntl qw(S_ISREG); +our @EXPORT = qw(mdir_sort); +my %ST = (sequence => 0, size => 1, atime => 2, mtime => 3, ctime => 4); + +sub mdir_sort ($$;$) { + my ($ent, $sort, $max) = @_; + my @st; + my @ent = map { + @st = Time::HiRes::stat $_; + # name, size, {a,m,c}time + S_ISREG($st[2]) ? [ $_, @st[7..10] ] : (); + } @$ent; + @ent = grep { $_->[1] <= $max } @ent if $max; + use sort 'stable'; + for my $s (@$sort) { + if ($s =~ /\A(\-|\+|)name\z/) { + if ($1 eq '-') { + @ent = sort { $b->[0] cmp $a->[0] } @ent; + } else { + @ent = sort { $a->[0] cmp $b->[0] } @ent; + } + } elsif ($s =~ /\A(\-|\+|) + (sequence|size|ctime|mtime|atime)\z/x) { + my $key = $ST{$2}; + if ($1 eq '-') { + @ent = sort { $b->[$key] <=> $a->[$key] } @ent; + } else { + @ent = sort { $a->[$key] <=> $b->[$key] } @ent; + } + } else { + die "E: unrecognized sort parameter: `$s'"; + } + } + @$ent = map { $_->[0] } @ent; +} + +1; |