X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FMiscSearch.pm;h=f2e3144303d39fdc02c1cfbed172529ed955078b;hb=0d38f65c490466837ae091afa7a7b6f59d04ce7c;hp=8beb8349fea839a4a132298ec9001a6c1758fb52;hpb=58e764d179131b0fba8590915e2528248be26329;p=public-inbox.git diff --git a/lib/PublicInbox/MiscSearch.pm b/lib/PublicInbox/MiscSearch.pm index 8beb8349..f2e31443 100644 --- a/lib/PublicInbox/MiscSearch.pm +++ b/lib/PublicInbox/MiscSearch.pm @@ -50,7 +50,7 @@ sub mi_qp_new ($) { } sub misc_enquire_once { # retry_reopen callback - my ($self, $qr, $opt) = @{$_[0]}; + my ($self, $qr, $opt) = @_; my $eq = $PublicInbox::Search::X{Enquire}->new($self->{xdb}); $eq->set_query($qr); my $desc = !$opt->{asc}; @@ -73,7 +73,66 @@ sub mset { $qs = 'type:inbox' if $qs eq ''; my $qr = $qp->parse_query($qs, $PublicInbox::Search::QP_FLAGS); $opt->{relevance} = 1 unless exists $opt->{relevance}; - retry_reopen($self, \&misc_enquire_once, [ $self, $qr, $opt ]); + retry_reopen($self, \&misc_enquire_once, $qr, $opt); +} + +sub ibx_matches_once { # retry_reopen callback + my ($self, $qr, $by_newsgroup) = @_; + # double in case no newsgroups are configured: + my $limit = scalar(keys %$by_newsgroup) * 2; + my $opt = { limit => $limit, offset => 0, relevance => -1 }; + my $ret = {}; # newsgroup => $ibx of matches + while (1) { + my $mset = misc_enquire_once($self, $qr, $opt); + for my $mi ($mset->items) { + my $doc = $mi->get_document; + my $end = $doc->termlist_end; + my $cur = $doc->termlist_begin; + $cur->skip_to('Q'); + if ($cur != $end) { + my $ng = $cur->get_termname; # eidx_key + $ng =~ s/\AQ// or warn "BUG: no `Q': $ng"; + if (my $ibx = $by_newsgroup->{$ng}) { + $ret->{$ng} = $ibx; + } + } else { + warn <get_docid} has no `Q' (eidx_key) term +EOF + } + } + my $nr = $mset->size; + return $ret if $nr < $limit; + $opt->{offset} += $nr; + } +} + +# returns a newsgroup => PublicInbox::Inbox mapping +sub newsgroup_matches { + my ($self, $qs, $pi_cfg) = @_; + my $qp = $self->{qp} //= mi_qp_new($self); + $qs .= ' type:inbox'; + my $qr = $qp->parse_query($qs, $PublicInbox::Search::QP_FLAGS); + retry_reopen($self, \&ibx_matches_once, $qr, $pi_cfg->{-by_newsgroup}); +} + +sub ibx_data_once { + my ($self, $ibx) = @_; + my $xdb = $self->{xdb}; + my $eidx_key = $ibx->eidx_key; # may be {inboxdir}, so private + my $head = $xdb->postlist_begin('Q'.$eidx_key); + my $tail = $xdb->postlist_end('Q'.$eidx_key); + if ($head != $tail) { + my $doc = $xdb->get_document($head->get_docid); + $doc->get_data; + } else { + undef; + } +} + +sub inbox_data { + my ($self, $ibx) = @_; + retry_reopen($self, \&ibx_data_once, $ibx); } 1;