X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FIsearch.pm;h=df940e76156d0f162d179f99352e4f7091ba6cc4;hb=23af251dd607c4e75ab1e68063f2c885c48cc035;hp=0ab3b19a64966a7ebad8f4d3df5fbb102d94f766;hpb=525555d14118f92f86be54c683f797089c52a78d;p=public-inbox.git diff --git a/lib/PublicInbox/Isearch.pm b/lib/PublicInbox/Isearch.pm index 0ab3b19a..df940e76 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,58 @@ 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; + } + my $rows = $self->{es}->over->dbh-> + selectall_arrayref(<<"", undef, $ibx_id, @$docids, @r); +SELECT xnum FROM xref3 WHERE ibx_id = ? AND docid IN ($qmarks) $range +ORDER BY xnum ASC + + return [ map { $_->[0] } @$rows ]; + } + 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 +90,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 +114,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"; }