X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FIsearch.pm;h=2b45e08e8447b67d8234852f0f7290f84c907b26;hb=refs%2Fheads%2Fmaster;hp=0ab3b19a64966a7ebad8f4d3df5fbb102d94f766;hpb=525555d14118f92f86be54c683f797089c52a78d;p=public-inbox.git
diff --git a/lib/PublicInbox/Isearch.pm b/lib/PublicInbox/Isearch.pm
index 0ab3b19a..2b45e08e 100644
--- a/lib/PublicInbox/Isearch.pm
+++ b/lib/PublicInbox/Isearch.pm
@@ -1,4 +1,4 @@
-# Copyright (C) 2020 all contributors
+# Copyright (C) 2020-2021 all contributors
# License: AGPL-3.0+
# Provides everything the PublicInbox::Search object does;
@@ -15,12 +15,6 @@ sub new {
bless { es => $es, eidx_key => $ibx->eidx_key }, __PACKAGE__;
}
-sub mset {
- my ($self, $str, $opt) = @_;
- $self->{es}->mset($str, { $opt ? %$opt : (),
- eidx_key => $self->{eidx_key} });
-}
-
sub _ibx_id ($) {
my ($self) = @_;
my $sth = $self->{es}->over->dbh->prepare_cached(<<'', undef, 1);
@@ -31,11 +25,57 @@ SELECT ibx_id FROM inboxes WHERE eidx_key = ? LIMIT 1
die "E: `$self->{eidx_key}' not in $self->{es}->{topdir}\n";
}
+sub query_approxidate { $_[0]->{es}->query_approxidate($_[1], $_[2]) }
+
+sub mset {
+ my ($self, $str, $opt) = @_;
+ my %opt = $opt ? %$opt : ();
+ $opt{eidx_key} = $self->{eidx_key};
+ if (my $uid_range = $opt{uid_range}) {
+ my ($beg, $end) = @$uid_range;
+ my $ibx_id = $self->{-ibx_id} //= _ibx_id($self);
+ my $dbh = $self->{es}->over->dbh;
+ my $sth = $dbh->prepare_cached(<<'', undef, 1);
+SELECT MIN(docid) FROM xref3 WHERE ibx_id = ? AND xnum >= ? AND xnum <= ?
+
+ $sth->execute($ibx_id, $beg, $end);
+ my @r = ($sth->fetchrow_array);
+
+ $sth = $dbh->prepare_cached(<<'', undef, 1);
+SELECT MAX(docid) FROM xref3 WHERE ibx_id = ? AND xnum >= ? AND xnum <= ?
+
+ $sth->execute($ibx_id, $beg, $end);
+ $r[1] = $sth->fetchrow_array;
+ if (defined($r[1]) && defined($r[0])) {
+ $opt{limit} = $r[1] - $r[0] + 1;
+ } else {
+ $r[1] //= 0xffffffff;
+ $r[0] //= 0;
+ }
+ $opt{uid_range} = \@r;
+ }
+ $self->{es}->mset($str, \%opt);
+}
+
sub mset_to_artnums {
- my ($self, $mset) = @_;
+ my ($self, $mset, $opt) = @_;
my $docids = PublicInbox::Search::mset_to_artnums($self->{es}, $mset);
my $ibx_id = $self->{-ibx_id} //= _ibx_id($self);
my $qmarks = join(',', map { '?' } @$docids);
+ if ($opt && ($opt->{relevance} // 0) == -1) { # -1 => ENQ_ASCENDING
+ my $range = '';
+ my @r;
+ if (my $r = $opt->{uid_range}) {
+ $range = 'AND xnum >= ? AND xnum <= ?';
+ @r = @$r;
+ }
+ return $self->{es}->over->dbh->
+ selectcol_arrayref(<<"", undef, $ibx_id, @$docids, @r);
+SELECT xnum FROM xref3 WHERE ibx_id = ? AND docid IN ($qmarks) $range
+ORDER BY xnum ASC
+
+ }
+
my $rows = $self->{es}->over->dbh->
selectall_arrayref(<<"", undef, $ibx_id, @$docids);
SELECT docid,xnum FROM xref3 WHERE ibx_id = ? AND docid IN ($qmarks)
@@ -49,7 +89,7 @@ SELECT docid,xnum FROM xref3 WHERE ibx_id = ? AND docid IN ($qmarks)
}
if (scalar keys %order) {
warn "W: $self->{es}->{topdir} #",
- join(', #', sort keys %order),
+ join(', ', sort { $a <=> $b } keys %order),
" not mapped to `$self->{eidx_key}'\n";
warn "W: $self->{es}->{topdir} may need to be reindexed\n";
@xnums = grep { defined } @xnums;
@@ -73,7 +113,7 @@ sub mset_to_smsg {
}
if (scalar keys %order) {
warn "W: $ibx->{inboxdir} #",
- join(', #', sort keys %order),
+ join(', ', sort { $a <=> $b } keys %order),
" no longer valid\n";
warn "W: $self->{es}->{topdir} may need to be reindexed\n";
}