]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/Search.pm
miscsearch: a new Xapian sub-DB for extindex
[public-inbox.git] / lib / PublicInbox / Search.pm
index 0321ca9352944d720a0962df8e3d1097ca9de68f..05d5a13320d230c2b60ca6f3990b856cd52d1437 100644 (file)
@@ -6,7 +6,7 @@
 package PublicInbox::Search;
 use strict;
 use parent qw(Exporter);
-our @EXPORT_OK = qw(mdocid);
+our @EXPORT_OK = qw(mdocid retry_reopen);
 use List::Util qw(max);
 
 # values for searching, changing the numeric value breaks
@@ -54,11 +54,11 @@ use constant {
 
 use PublicInbox::Smsg;
 use PublicInbox::Over;
-my $QP_FLAGS;
+our $QP_FLAGS;
 our %X = map { $_ => 0 } qw(BoolWeight Database Enquire QueryParser Stem);
 our $Xap; # 'Search::Xapian' or 'Xapian'
-my $NVRP; # '$Xap::'.('NumberValueRangeProcessor' or 'NumberRangeProcessor')
-my $ENQ_ASCENDING;
+our $NVRP; # '$Xap::'.('NumberValueRangeProcessor' or 'NumberRangeProcessor')
+our $ENQ_ASCENDING;
 
 sub load_xapian () {
        return 1 if defined $Xap;
@@ -190,38 +190,42 @@ sub xdir ($;$) {
        }
 }
 
-sub _xdb ($) {
+sub xdb_sharded {
+       my ($self) = @_;
+       opendir(my $dh, $self->{xpfx}) or return; # not initialized yet
+
+       # We need numeric sorting so shard[0] is first for reading
+       # Xapian metadata, if needed
+       my $last = max(grep(/\A[0-9]+\z/, readdir($dh)));
+       return if !defined($last);
+       my (@xdb, $slow_phrase);
+       for (0..$last) {
+               my $shard_dir = "$self->{xpfx}/$_";
+               if (-d $shard_dir && -r _) {
+                       push @xdb, $X{Database}->new($shard_dir);
+                       $slow_phrase ||= -f "$shard_dir/iamchert";
+               } else { # gaps from missing epochs throw off mdocid()
+                       warn "E: $shard_dir missing or unreadable\n";
+                       return;
+               }
+       }
+       $self->{qp_flags} |= FLAG_PHRASE() if !$slow_phrase;
+       $self->{nshard} = scalar(@xdb);
+       my $xdb = shift @xdb;
+       $xdb->add_database($_) for @xdb;
+       $xdb;
+}
+
+sub _xdb {
        my ($self) = @_;
        my $dir = xdir($self, 1);
-       my ($xdb, $slow_phrase);
-       my $qpf = \($self->{qp_flags} ||= $QP_FLAGS);
+       $self->{qp_flags} //= $QP_FLAGS;
        if ($self->{ibx_ver} >= 2) {
-               my @xdb;
-               opendir(my $dh, $dir) or return; # not initialized yet
-
-               # We need numeric sorting so shard[0] is first for reading
-               # Xapian metadata, if needed
-               my $last = max(grep(/\A[0-9]+\z/, readdir($dh)));
-               return if !defined($last);
-               for (0..$last) {
-                       my $shard_dir = "$dir/$_";
-                       if (-d $shard_dir && -r _) {
-                               push @xdb, $X{Database}->new($shard_dir);
-                               $slow_phrase ||= -f "$shard_dir/iamchert";
-                       } else { # gaps from missing epochs throw off mdocid()
-                               warn "E: $shard_dir missing or unreadable\n";
-                               return;
-                       }
-               }
-               $self->{nshard} = scalar(@xdb);
-               $xdb = shift @xdb;
-               $xdb->add_database($_) for @xdb;
+               xdb_sharded($self);
        } else {
-               $slow_phrase = -f "$dir/iamchert";
-               $xdb = $X{Database}->new($dir);
+               $self->{qp_flags} |= FLAG_PHRASE() if !-f "$dir/iamchert";
+               $X{Database}->new($dir);
        }
-       $$qpf |= FLAG_PHRASE() unless $slow_phrase;
-       $xdb;
 }
 
 # v2 Xapian docids don't conflict, so they're identical to
@@ -241,9 +245,9 @@ sub mset_to_artnums {
 
 sub xdb ($) {
        my ($self) = @_;
-       $self->{xdb} ||= do {
+       $self->{xdb} //= do {
                load_xapian();
-               _xdb($self);
+               $self->_xdb;
        };
 }