]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/SearchIdx.pm
searchidxshard: use add_xapian directly for v2
[public-inbox.git] / lib / PublicInbox / SearchIdx.pm
index 548f2114b80174cfd1569c319e4a1daa1a7bc8e8..adced0762b41487d5bdaa69517db157901bf3076 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2015-2020 all contributors <meta@public-inbox.org>
+# Copyright (C) 2015-2021 all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 # based on notmuch, but with no concept of folders, files
 #
@@ -22,7 +22,7 @@ use PublicInbox::OverIdx;
 use PublicInbox::Spawn qw(spawn nodatacow_dir);
 use PublicInbox::Git qw(git_unquote);
 use PublicInbox::MsgTime qw(msg_timestamp msg_datestamp);
-our @EXPORT_OK = qw(crlf_adjust log2stack is_ancestor check_size prepare_stack
+our @EXPORT_OK = qw(log2stack is_ancestor check_size prepare_stack
        index_text term_generator add_val is_bad_blob);
 my $X = \%PublicInbox::Search::X;
 our ($DB_CREATE_OR_OPEN, $DB_OPEN);
@@ -54,20 +54,16 @@ sub new {
                }
        }
        $ibx = PublicInbox::InboxWritable->new($ibx);
-       my $self = bless {
-               ibx => $ibx,
-               xpfx => $inboxdir, # for xpfx_init
-               -altid => $altid,
-               ibx_ver => $version,
-               indexlevel => $indexlevel,
-       }, $class;
-       $self->xpfx_init;
+       my $self = PublicInbox::Search->new($ibx);
+       bless $self, $class;
+       $self->{ibx} = $ibx;
+       $self->{-altid} = $altid;
+       $self->{indexlevel} = $indexlevel;
        $self->{-set_indexlevel_once} = 1 if $indexlevel eq 'medium';
        if ($ibx->{-skip_docdata}) {
                $self->{-set_skip_docdata_once} = 1;
                $self->{-skip_docdata} = 1;
        }
-       $ibx->umask_prepare;
        if ($version == 1) {
                $self->{lock_path} = "$inboxdir/ssoma.lock";
                my $dir = $self->xdir;
@@ -106,7 +102,6 @@ sub load_xapian_writable () {
        }
        eval 'require '.$X->{WritableDatabase} or die;
        *sortable_serialise = $xap.'::sortable_serialise';
-       *sortable_unserialise = $xap.'::sortable_unserialise';
        $DB_CREATE_OR_OPEN = eval($xap.'::DB_CREATE_OR_OPEN()');
        $DB_OPEN = eval($xap.'::DB_OPEN()');
        my $ver = (eval($xap.'::major_version()') << 16) |
@@ -402,13 +397,14 @@ sub eml2doc ($$$;$) {
 
 sub add_xapian ($$$$) {
        my ($self, $eml, $smsg, $mids) = @_;
+       begin_txn_lazy($self);
        my $doc = eml2doc($self, $eml, $smsg, $mids);
        $self->{xdb}->replace_document($smsg->{num}, $doc);
 }
 
 sub _msgmap_init ($) {
        my ($self) = @_;
-       die "BUG: _msgmap_init is only for v1\n" if $self->{ibx_ver} != 1;
+       die "BUG: _msgmap_init is only for v1\n" if $self->{ibx}->version != 1;
        $self->{mm} //= eval {
                require PublicInbox::Msgmap;
                my $rw = $self->{ibx}->{-no_fsync} ? 2 : 1;
@@ -419,6 +415,7 @@ sub _msgmap_init ($) {
 sub add_message {
        # mime = PublicInbox::Eml or Email::MIME object
        my ($self, $mime, $smsg, $sync) = @_;
+       begin_txn_lazy($self);
        my $mids = mids_for_index($mime);
        $smsg //= bless { blob => '' }, 'PublicInbox::Smsg'; # test-only compat
        $smsg->{mid} //= $mids->[0]; # v1 compatibility
@@ -542,17 +539,12 @@ sub remove_keywords {
        $self->{xdb}->replace_document($docid, $doc) if $replace;
 }
 
-sub get_val ($$) {
-       my ($doc, $col) = @_;
-       sortable_unserialise($doc->get_value($col));
-}
-
 sub smsg_from_doc ($) {
        my ($doc) = @_;
        my $data = $doc->get_data or return;
        my $smsg = bless {}, 'PublicInbox::Smsg';
-       $smsg->{ts} = get_val($doc, PublicInbox::Search::TS());
-       my $dt = get_val($doc, PublicInbox::Search::DT());
+       $smsg->{ts} = int_val($doc, PublicInbox::Search::TS());
+       my $dt = int_val($doc, PublicInbox::Search::DT());
        my ($yyyy, $mon, $dd, $hh, $mm, $ss) = unpack('A4A2A2A2A2A2', $dt);
        $smsg->{ds} = timegm($ss, $mm, $hh, $dd, $mon - 1, $yyyy);
        $smsg->load_from_data($data);
@@ -561,6 +553,7 @@ sub smsg_from_doc ($) {
 
 sub xdb_remove {
        my ($self, @docids) = @_;
+       $self->begin_txn_lazy;
        my $xdb = $self->{xdb} or return;
        for my $docid (@docids) {
                eval { $xdb->delete_document($docid) };
@@ -568,13 +561,6 @@ sub xdb_remove {
        }
 }
 
-sub remove_by_docid {
-       my ($self, $num) = @_;
-       die "BUG: remove_by_docid is v2-only\n" if $self->{oidx};
-       $self->begin_txn_lazy;
-       xdb_remove($self, $num) if need_xapian($self);
-}
-
 sub index_git_blob_id {
        my ($doc, $pfx, $objid) = @_;
 
@@ -628,17 +614,6 @@ sub index_mm {
        }
 }
 
-# returns the number of bytes to add if given a non-CRLF arg
-sub crlf_adjust ($) {
-       if (index($_[0], "\r\n") < 0) {
-               # common case is LF-only, every \n needs an \r;
-               # so favor a cheap tr// over an expensive m//g
-               $_[0] =~ tr/\n/\n/;
-       } else { # count number of '\n' w/o '\r', expensive:
-               scalar(my @n = ($_[0] =~ m/(?<!\r)\n/g));
-       }
-}
-
 sub is_bad_blob ($$$$) {
        my ($oid, $type, $size, $expect_oid) = @_;
        if ($type ne 'blob') {
@@ -655,14 +630,15 @@ sub index_both { # git->cat_async callback
        my ($nr, $max) = @$sync{qw(nr max)};
        ++$$nr;
        $$max -= $size;
-       $size += crlf_adjust($$bref);
-       my $smsg = bless { bytes => $size, blob => $oid }, 'PublicInbox::Smsg';
+       my $smsg = bless { blob => $oid }, 'PublicInbox::Smsg';
+       $smsg->set_bytes($$bref, $size);
        my $self = $sync->{sidx};
        local $self->{current_info} = "$self->{current_info}: $oid";
        my $eml = PublicInbox::Eml->new($bref);
        $smsg->{num} = index_mm($self, $eml, $oid, $sync) or
                die "E: could not generate NNTP article number for $oid";
        add_message($self, $eml, $smsg, $sync);
+       ++$self->{nidx};
        my $cur_cmt = $sync->{cur_cmt} // die 'BUG: {cur_cmt} missing';
        ${$sync->{latest_cmt}} = $cur_cmt;
 }
@@ -677,6 +653,7 @@ sub unindex_both { # git->cat_async callback
        if (defined(my $cur_cmt = $sync->{cur_cmt})) {
                ${$sync->{latest_cmt}} = $cur_cmt;
        }
+       ++$self->{nidx};
 }
 
 sub with_umask {
@@ -1010,14 +987,6 @@ sub commit_txn_lazy {
                $self->with_umask(\&_commit_txn, $self);
 }
 
-sub worker_done {
-       my ($self) = @_;
-       if (need_xapian($self)) {
-               die "$$ $0 xdb not released\n" if $self->{xdb};
-       }
-       die "$$ $0 still in transaction\n" if $self->{txn};
-}
-
 sub eidx_shard_new {
        my ($class, $eidx, $shard) = @_;
        my $self = bless {