diff options
author | Eric Wong <e@yhbt.net> | 2020-06-10 07:04:57 +0000 |
---|---|---|
committer | Eric Wong <e@yhbt.net> | 2020-06-13 07:55:45 +0000 |
commit | e2d88cc7ee7f71d014a2be1a35e06dcb7fc77fd9 (patch) | |
tree | bcc57f635d6b9b5d038ff3d4cd8df40bcaf114ec | |
parent | 86c9cf7328b9e48501dabd1fb464b5e763e8f4b4 (diff) | |
download | public-inbox-e2d88cc7ee7f71d014a2be1a35e06dcb7fc77fd9.tar.gz |
We can speed up this common mutt request by another 2-3x by not loading the entire smsg from SQLite, just the UID.
-rw-r--r-- | lib/PublicInbox/IMAP.pm | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/lib/PublicInbox/IMAP.pm b/lib/PublicInbox/IMAP.pm index 0fe31a77..0d553da9 100644 --- a/lib/PublicInbox/IMAP.pm +++ b/lib/PublicInbox/IMAP.pm @@ -41,8 +41,9 @@ sub LINE_MAX () { 512 } # does RFC 3501 have a limit like RFC 977? sub UID_BLOCK () { 50_000 } # these values area also used for sorting -sub NEED_BLOB () { 1 } -sub NEED_EML () { NEED_BLOB|2 } +sub NEED_SMSG () { 1 } +sub NEED_BLOB () { NEED_SMSG|2 } +sub NEED_EML () { NEED_BLOB|4 } my $OP_EML_NEW = [ NEED_EML - 1, \&op_eml_new ]; my %FETCH_NEED = ( @@ -57,7 +58,7 @@ my %FETCH_NEED = ( BODYSTRUCTURE => [ NEED_EML, \&emit_bodystructure ], ENVELOPE => [ NEED_EML, \&emit_envelope ], FLAGS => [ 0, \&emit_flags ], - INTERNALDATE => [ 0, \&emit_internaldate ], + INTERNALDATE => [ NEED_SMSG, \&emit_internaldate ], ); my %FETCH_ATT = map { $_ => [ $_ ] } keys %FETCH_NEED; @@ -578,6 +579,38 @@ sub uid_fetch_smsg { # long_response 1; # more } +sub uid_fetch_uid { # long_response + my ($self, $tag, $uids, $range_info, $ops) = @_; + while (!@$uids) { # rare + my ($beg, $end, $range_csv) = @$range_info; + if (scalar(@$uids = @{$self->{ibx}->over-> + uid_range($beg, $end)})) { + $range_info->[0] = $uids->[-1] + 1; + } elsif (!$range_csv) { + $self->write(\"$tag OK Fetch done\r\n"); + return; + } else { + my $next_range = range_step($self, \$range_csv); + if (!ref($next_range)) { # error + $self->write(\"$tag $next_range\r\n"); + return; + } + @$range_info = @$next_range; + } + # continue looping + } + for (@$uids) { + $self->msg_more("* $_ FETCH (UID $_"); + for (my $i = 0; $i < @$ops;) { + my $k = $ops->[$i++]; + $ops->[$i++]->($self, $k); + } + $self->msg_more(")\r\n"); + } + @$uids = (); + 1; # more +} + sub cmd_status ($$$;@) { my ($self, $tag, $mailbox, @items) = @_; return "$tag BAD no items\r\n" if !scalar(@items); @@ -794,7 +827,8 @@ sub fetch_compile ($) { $r[2] = [ map { [ $_, @{$partial{$_}} ] } sort keys %partial ]; } - $r[0] = $need ? \&uid_fetch_msg : \&uid_fetch_smsg; + $r[0] = $need & NEED_BLOB ? \&uid_fetch_msg : + ($need & NEED_SMSG ? \&uid_fetch_smsg : \&uid_fetch_uid); # r[1] = [ $key1, $cb1, $key2, $cb2, ... ] use sort 'stable'; # makes output more consistent |