X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FIMAP.pm;h=2d0d005e6f8b71239a342669a03645c0600f82ef;hb=3d83cc1dae085b0bc2044cb82aa86e35a8b5172a;hp=e0602143835baed35dcc164b63da0d514acb3f55;hpb=94096cab6cd5e00c8a36a4a2667bdb9acf43d01f;p=public-inbox.git diff --git a/lib/PublicInbox/IMAP.pm b/lib/PublicInbox/IMAP.pm index e0602143..2d0d005e 100644 --- a/lib/PublicInbox/IMAP.pm +++ b/lib/PublicInbox/IMAP.pm @@ -40,9 +40,7 @@ use PublicInbox::Syscall qw(EPOLLIN EPOLLONESHOT); use PublicInbox::GitAsyncCat; use Text::ParseWords qw(parse_line); use Errno qw(EAGAIN); -use PublicInbox::Search; use PublicInbox::IMAPsearchqp; -*mdocid = \&PublicInbox::Search::mdocid; my $Address; for my $mod (qw(Email::Address::XS Mail::Address)) { @@ -246,6 +244,7 @@ sub uo2m_extend ($$;$) { my $base = $self->{uid_base}; ++$beg; my $uids = $self->{ibx}->over->uid_range($beg, $base + UID_SLICE); + return $uo2m if !scalar(@$uids); my @tmp; # [$UID_OFFSET] => $MSN my $write_method = $_[2] // 'msg_more'; if (ref($uo2m)) { @@ -620,12 +619,18 @@ sub fetch_blob_cb { # called by git->cat_async via git_async_cat if (!defined($oid)) { # it's possible to have TOCTOU if an admin runs # public-inbox-(edit|purge), just move onto the next message + warn "E: $smsg->{blob} missing in $self->{ibx}->{inboxdir}\n"; return requeue_once($self); } else { $smsg->{blob} eq $oid or die "BUG: $smsg->{blob} != $oid"; } + my $pre; + if (!$self->{wbuf} && (my $nxt = $msgs->[0])) { + $pre = $self->{ibx}->git->async_prefetch($nxt->{blob}, + \&fetch_blob_cb, $fetch_arg); + } fetch_run_ops($self, $smsg, $bref, $ops, $partial); - requeue_once($self); + $pre ? $self->zflush : requeue_once($self); } sub emit_rfc822 { @@ -1104,67 +1109,6 @@ sub search_uid_range { # long_response 1; # more } -sub date_search { - my ($q, $k, $d) = @_; - my $sql = $q->{sql}; - - # Date: header - if ($k eq 'SENTON') { - my $end = $d + 86399; # no leap day... - my $da = strftime('%Y%m%d%H%M%S', gmtime($d)); - my $db = strftime('%Y%m%d%H%M%S', gmtime($end)); - $q->{xap} .= " dt:$da..$db"; - $$sql .= " AND ds >= $d AND ds <= $end" if defined($sql); - } elsif ($k eq 'SENTBEFORE') { - $q->{xap} .= ' d:..'.strftime('%Y%m%d', gmtime($d)); - $$sql .= " AND ds <= $d" if defined($sql); - } elsif ($k eq 'SENTSINCE') { - $q->{xap} .= ' d:'.strftime('%Y%m%d', gmtime($d)).'..'; - $$sql .= " AND ds >= $d" if defined($sql); - - # INTERNALDATE (Received) - } elsif ($k eq 'ON') { - my $end = $d + 86399; # no leap day... - $q->{xap} .= " ts:$d..$end"; - $$sql .= " AND ts >= $d AND ts <= $end" if defined($sql); - } elsif ($k eq 'BEFORE') { - $q->{xap} .= " ts:..$d"; - $$sql .= " AND ts <= $d" if defined($sql); - } elsif ($k eq 'SINCE') { - $q->{xap} .= " ts:$d.."; - $$sql .= " AND ts >= $d" if defined($sql); - } else { - die "BUG: $k not recognized"; - } -} - -# IMAP to Xapian search key mapping -my %I2X = ( - SUBJECT => 's:', - BODY => 'b:', - FROM => 'f:', - TEXT => '', # n.b. does not include all headers - TO => 't:', - CC => 'c:', - # BCC => 'bcc:', # TODO - # KEYWORD # TODO ? dfpre,dfpost,... -); - -# IMAP allows searching arbitrary headers via "HEADER $HDR_NAME $HDR_VAL" -# which gets silly expensive. We only allow the headers we already index. -my %H2X = (%I2X, 'MESSAGE-ID' => 'm:', 'LIST-ID' => 'l:'); - -sub xap_append ($$$$) { - my ($q, $rest, $k, $xk) = @_; - delete $q->{sql}; # can't use over.sqlite3 - defined(my $arg = shift @$rest) or return "BAD $k no arg"; - - # AFAIK Xapian can't handle [*"] in probabilistic terms - $arg =~ tr/*"//d; - ${$q->{xap}} .= qq[ $xk"$arg"]; - undef; -} - sub parse_query ($$) { my ($self, $query) = @_; my $q = PublicInbox::IMAPsearchqp::parse($self, $query); @@ -1182,9 +1126,8 @@ sub refill_xap ($$$$) { my ($beg, $end) = @$range_info; my $srch = $self->{ibx}->search; my $opt = { mset => 2, limit => 1000 }; - my $nshard = $srch->{nshard} // 1; - my $mset = $srch->query("$q uid:$beg..$end", $opt); - @$uids = map { mdocid($nshard, $_) } $mset->items; + my $mset = $srch->mset("$q uid:$beg..$end", $opt); + @$uids = @{$srch->mset_to_artnums($mset)}; if (@$uids) { $range_info->[0] = $uids->[-1] + 1; # update $beg return; # possibly more