]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/ExtMsg.pm
isearch: emulate per-inbox search with ->ALL
[public-inbox.git] / lib / PublicInbox / ExtMsg.pm
index ce1a47bb84fd70da06e617dd0d1ee34a2e409b99..2a579c1b9d1c934624edca9e6fdfc73e51019290 100644 (file)
@@ -32,7 +32,7 @@ sub PARTIAL_MAX () { 100 }
 sub search_partial ($$) {
        my ($ibx, $mid) = @_;
        return if length($mid) < $MIN_PARTIAL_LEN;
-       my $srch = $ibx->search or return;
+       my $srch = $ibx->search or return; # NOT ->isrch, we already try ->ALL
        my $opt = { limit => PARTIAL_MAX, mset => 2 };
        my @try = ("m:$mid*");
        my $chop = $mid;
@@ -103,9 +103,37 @@ sub ext_msg_step {
        }
 }
 
+sub ext_msg_ALL ($) {
+       my ($ctx) = @_;
+       my $ALL = $ctx->{www}->{pi_config}->ALL or return;
+       my $by_eidx_key = $ctx->{www}->{pi_config}->{-by_eidx_key};
+       my $cur_key = $ctx->{-inbox}->eidx_key;
+       my %seen = ($cur_key => 1);
+       my ($id, $prev);
+       while (my $x = $ALL->over->next_by_mid($ctx->{mid}, \$id, \$prev)) {
+               my $xr3 = $ALL->over->get_xref3($x->{num});
+               for my $k (@$xr3) {
+                       $k =~ s/:[0-9]+:$x->{blob}\z// or next;
+                       next if $k eq $cur_key;
+                       my $ibx = $by_eidx_key->{$k} // next;
+                       my $url = $ibx->base_url or next;
+                       push(@{$ctx->{found}}, $ibx) unless $seen{$k}++;
+               }
+       }
+       return exact($ctx) if $ctx->{found};
+
+       # fall back to partial MID matching
+       for my $ibxish ($ctx->{-inbox}, $ALL) {
+               my $mids = search_partial($ibxish, $ctx->{mid}) or next;
+               push @{$ctx->{partial}}, [ $ibxish, $mids ];
+               last if ($ctx->{n_partial} += scalar(@$mids)) >= PARTIAL_MAX;
+       }
+       partial_response($ctx);
+}
+
 sub ext_msg {
        my ($ctx) = @_;
-       sub {
+       ext_msg_ALL($ctx) // sub {
                $ctx->{-wcb} = $_[0]; # HTTP server write callback
 
                if ($ctx->{env}->{'pi-httpd.async'}) {
@@ -125,12 +153,12 @@ sub ext_msg {
 sub event_step {
        my ($ctx, $sync) = @_;
        # can't find a partial match in current inbox, try the others:
-       my $ibx = shift @{$ctx->{again}} or goto \&finalize_partial;
+       my $ibx = shift @{$ctx->{again}} or return finalize_partial($ctx);
        my $mids = search_partial($ibx, $ctx->{mid}) or
                        return ($sync ? undef : PublicInbox::DS::requeue($ctx));
        $ctx->{n_partial} += scalar(@$mids);
        push @{$ctx->{partial}}, [ $ibx, $mids ];
-       $ctx->{n_partial} >= PARTIAL_MAX ? goto(\&finalize_partial)
+       $ctx->{n_partial} >= PARTIAL_MAX ? finalize_partial($ctx)
                        : ($sync ? undef : PublicInbox::DS::requeue($ctx));
 }
 
@@ -156,10 +184,10 @@ sub finalize_exact {
                # synchronous fall-through
                $ctx->event_step while @{$ctx->{again}};
        }
-       goto \&finalize_partial;
+       finalize_partial($ctx);
 }
 
-sub finalize_partial {
+sub partial_response ($) {
        my ($ctx) = @_;
        my $mid = $ctx->{mid};
        my $code = 404;
@@ -192,9 +220,11 @@ sub finalize_partial {
        $ctx->{-html_tip} = $s .= '</pre>';
        $ctx->{-title_html} = $title;
        $ctx->{-upfx} = '../';
-       $ctx->{-wcb}->(html_oneshot($ctx, $code));
+       html_oneshot($ctx, $code);
 }
 
+sub finalize_partial ($) { $_[0]->{-wcb}->(partial_response($_[0])) }
+
 sub ext_urls {
        my ($ctx, $mid, $href, $html) = @_;