]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/Inbox.pm
isearch: emulate per-inbox search with ->ALL
[public-inbox.git] / lib / PublicInbox / Inbox.pm
index 55e546e104f538109b95f804efb53e5a556c95ad..52aece7c9db73b7efd10c61e57c838ddc36821b0 100644 (file)
@@ -70,7 +70,7 @@ sub _cleanup_later ($) {
        my ($self) = @_;
        $cleanup_avail = cleanup_possible() if $cleanup_avail < 0;
        return if $cleanup_avail != 1;
-       $cleanup_timer ||= PublicInbox::DS::later(*cleanup_task);
+       $cleanup_timer //= PublicInbox::DS::later(\&cleanup_task);
        $CLEANUP->{"$self"} = $self;
 }
 
@@ -133,10 +133,10 @@ sub new {
 sub version { $_[0]->{version} // 1 }
 
 sub git_epoch {
-       my ($self, $epoch) = @_;
-       $self->version == 2 or return;
+       my ($self, $epoch) = @_; # v2-only, callers always supply $epoch
        $self->{"$epoch.git"} ||= do {
                my $git_dir = "$self->{inboxdir}/git/$epoch.git";
+               return unless -d $git_dir;
                my $g = PublicInbox::Git->new($git_dir);
                $g->{-httpbackend_limiter} = $self->{-httpbackend_limiter};
                # no cleanup needed, we never cat-file off this, only clone
@@ -191,30 +191,33 @@ sub mm {
        };
 }
 
-sub search ($;$$) {
-       my ($self, $over_only, $ctx) = @_;
-       my $srch = $self->{search} ||= eval {
+sub search {
+       my ($self) = @_;
+       my $srch = $self->{search} //= eval {
                _cleanup_later($self);
                require PublicInbox::Search;
                PublicInbox::Search->new($self);
        };
-       ($over_only || eval { $srch->xdb }) ? $srch : do {
-               $ctx and $ctx->{env}->{'psgi.errors'}->print(<<EOF);
-`$self->{name}' search went away unexpectedly
-EOF
-               undef;
+       (eval { $srch->xdb }) ? $srch : undef;
+}
+
+# isrch is preferred for read-only interfaces if available since it
+# reduces kernel cache and FD overhead
+sub isrch { $_[0]->{isrch} // search($_[0]) }
+
+sub over {
+       $_[0]->{over} //= eval {
+               my $srch = $_[0]->{search} //= eval {
+                       _cleanup_later($_[0]);
+                       require PublicInbox::Search;
+                       PublicInbox::Search->new($_[0]);
+               };
+               my $over = PublicInbox::Over->new("$srch->{xpfx}/over.sqlite3");
+               $over->dbh; # may fail
+               $over;
        };
 }
 
-sub over ($) {
-       my ($self) = @_;
-       my $srch = search($self, 1) or return;
-       $self->{over} //= eval {
-               my $over = $srch->{over_ro};
-               $over->connect; # may fail
-               $over;
-       }
-}
 
 sub try_cat {
        my ($path) = @_;
@@ -226,16 +229,19 @@ sub try_cat {
        $rv;
 }
 
+sub cat_desc ($) {
+       my $desc = try_cat($_[0]);
+       local $/ = "\n";
+       chomp $desc;
+       utf8::decode($desc);
+       $desc =~ s/\s+/ /smg;
+       $desc eq '' ? undef : $desc;
+}
+
 sub description {
        my ($self) = @_;
-       ($self->{description} //= do {
-               my $desc = try_cat("$self->{inboxdir}/description");
-               local $/ = "\n";
-               chomp $desc;
-               utf8::decode($desc);
-               $desc =~ s/\s+/ /smg;
-               $desc eq '' ? undef : $desc;
-       }) // '($INBOX_DIR/description missing)';
+       ($self->{description} //= cat_desc("$self->{inboxdir}/description")) //
+               '($INBOX_DIR/description missing)';
 }
 
 sub cloneurl {
@@ -332,7 +338,7 @@ sub msg_by_smsg ($$) {
        return unless defined $smsg;
        defined(my $blob = $smsg->{blob}) or return;
 
-       git($self)->cat_file($blob);
+       $self->git->cat_file($blob);
 }
 
 sub smsg_eml {
@@ -343,39 +349,35 @@ sub smsg_eml {
        $eml;
 }
 
-sub mid2num($$) {
-       my ($self, $mid) = @_;
-       my $mm = mm($self) or return;
-       $mm->num_for($mid);
-}
-
 sub smsg_by_mid ($$) {
        my ($self, $mid) = @_;
-       my $over = over($self) or return;
-       # favor the Message-ID we used for the NNTP article number:
-       defined(my $num = mid2num($self, $mid)) or return;
-       my $smsg = $over->get_art($num) or return;
-       PublicInbox::Smsg::psgi_cull($smsg);
+       my $over = $self->over or return;
+       my $smsg;
+       if (my $mm = $self->mm) {
+               # favor the Message-ID we used for the NNTP article number:
+               defined(my $num = $mm->num_for($mid)) or return;
+               $smsg = $over->get_art($num);
+       } else {
+               my ($id, $prev);
+               $smsg = $over->next_by_mid($mid, \$id, \$prev);
+       }
+       $smsg ? PublicInbox::Smsg::psgi_cull($smsg) : undef;
 }
 
 sub msg_by_mid ($$) {
        my ($self, $mid) = @_;
-
-       over($self) or
-               return msg_by_path($self, mid2path($mid));
-
        my $smsg = smsg_by_mid($self, $mid);
-       $smsg ? msg_by_smsg($self, $smsg) : undef;
+       $smsg ? msg_by_smsg($self, $smsg) : msg_by_path($self, mid2path($mid));
 }
 
 sub recent {
        my ($self, $opts, $after, $before) = @_;
-       over($self)->recent($opts, $after, $before);
+       $self->over->recent($opts, $after, $before);
 }
 
 sub modified {
        my ($self) = @_;
-       if (my $over = over($self)) {
+       if (my $over = $self->over) {
                my $msgs = $over->recent({limit => 1});
                if (my $smsg = $msgs->[0]) {
                        return $smsg->{ts};
@@ -429,4 +431,8 @@ sub on_unlock {
        }
 }
 
+sub uidvalidity  { $_[0]->{uidvalidity} //= $_[0]->mm->created_at }
+
+sub eidx_key { $_[0]->{newsgroup} // $_[0]->{inboxdir} }
+
 1;