X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FSearch.pm;h=ca389e320b2706edacbbd578b33dacc65812dece;hb=7503aeb540af5afd5cb1b554b3c29f35f5fc918d;hp=584a508e45f15d6c80cbdaa46ff8fa466cbc8de9;hpb=821ed7c40b7b50ceb1c942af5e14d168995d514e;p=public-inbox.git diff --git a/lib/PublicInbox/Search.pm b/lib/PublicInbox/Search.pm index 584a508e..ca389e32 100644 --- a/lib/PublicInbox/Search.pm +++ b/lib/PublicInbox/Search.pm @@ -8,17 +8,14 @@ use strict; use warnings; # values for searching -use constant DS => 0; # Date: header in Unix time -use constant NUM => 1; # NNTP article number -use constant BYTES => 2; # :bytes as defined in RFC 3977 -use constant LINES => 3; # :lines as defined in RFC 3977 -use constant TS => 4; # Received: header in Unix time -use constant YYYYMMDD => 5; # for searching in the WWW UI +use constant TS => 0; # Received: header in Unix time +use constant YYYYMMDD => 1; # for searching in the WWW UI +use constant NUM => 2; # NNTP article number use Search::Xapian qw/:standard/; use PublicInbox::SearchMsg; use PublicInbox::MIME; -use PublicInbox::MID qw/mid_clean id_compress/; +use PublicInbox::MID qw/id_compress/; # This is English-only, everything else is non-standard and may be confused as # a prefix common in patch emails @@ -193,9 +190,8 @@ sub query { sub get_thread { my ($self, $mid, $opts) = @_; - my $smsg = retry_reopen($self, sub { lookup_skeleton($self, $mid) }); - - return { total => 0, msgs => [] } unless $smsg; + my $smsg = first_smsg_by_mid($self, $mid) or + return { total => 0, msgs => [] }; my $qtid = Search::Xapian::Query->new('G' . $smsg->thread_id); my $path = $smsg->path; if (defined $path && $path ne '') { @@ -216,18 +212,20 @@ sub get_thread { sub retry_reopen { my ($self, $cb) = @_; my $ret; - for (1..10) { + for my $i (1..10) { eval { $ret = $cb->() }; return $ret unless $@; # Exception: The revision being read has been discarded - # you should call Xapian::Database::reopen() if (ref($@) eq 'Search::Xapian::DatabaseModifiedError') { + warn "reopen try #$i on $@\n"; reopen($self); } else { warn "ref: ", ref($@), "\n"; die; } } + die "Too many Xapian database modifications in progress\n"; } sub _do_enquire { @@ -346,74 +344,37 @@ sub query_ts { _do_enquire($self, $query, $opts); } -sub lookup_skeleton { - my ($self, $mid) = @_; - my $skel = $self->{skel} or return lookup_message($self, $mid); - $mid = mid_clean($mid); - my $term = 'Q' . $mid; - my $smsg; - my $beg = $skel->postlist_begin($term); - if ($beg != $skel->postlist_end($term)) { - my $doc_id = $beg->get_docid; - if (defined $doc_id) { - # raises on error: - my $doc = $skel->get_document($doc_id); - $smsg = PublicInbox::SearchMsg->wrap($doc, $mid); - $smsg->{doc_id} = $doc_id; - } - } - $smsg; -} - -sub lookup_message { +sub first_smsg_by_mid { my ($self, $mid) = @_; - $mid = mid_clean($mid); - - my $doc_id = $self->find_first_doc_id('Q' . $mid); my $smsg; - if (defined $doc_id) { - # raises on error: - my $doc = $self->{xdb}->get_document($doc_id); - $smsg = PublicInbox::SearchMsg->wrap($doc, $mid); - $smsg->{doc_id} = $doc_id; - } - $smsg; -} - -sub lookup_mail { # no ghosts! - my ($self, $mid) = @_; retry_reopen($self, sub { - my $smsg = lookup_skeleton($self, $mid) or return; - $smsg->load_expand; + each_smsg_by_mid($self, $mid, sub { $smsg = $_[0]; undef }); }); + $smsg; } sub lookup_article { my ($self, $num) = @_; my $term = 'XNUM'.$num; - my $smsg; - eval { - retry_reopen($self, sub { - my $db = $self->{skel} || $self->{xdb}; - my $head = $db->postlist_begin($term); - my $tail = $db->postlist_end($term); - return if $head->equal($tail); - my $doc_id = $head->get_docid; - return unless defined $doc_id; - $head->inc; - if ($head->nequal($tail)) { - my $loc= $self->{mainrepo} . - ($self->{skel} ? 'skel' : 'xdb'); - warn "article #$num is not unique in $loc\n"; - } - # raises on error: - my $doc = $db->get_document($doc_id); - $smsg = PublicInbox::SearchMsg->wrap($doc); - $smsg->load_expand; - $smsg->{doc_id} = $doc_id; - }); - }; - $smsg; + my $db = $self->{skel} || $self->{xdb}; + retry_reopen($self, sub { + my $head = $db->postlist_begin($term); + my $tail = $db->postlist_end($term); + return if $head->equal($tail); + my $doc_id = $head->get_docid; + return unless defined $doc_id; + $head->inc; + if ($head->nequal($tail)) { + my $loc= $self->{mainrepo} . + ($self->{skel} ? 'skel' : 'xdb'); + warn "article #$num is not unique in $loc\n"; + } + # raises on error: + my $doc = $db->get_document($doc_id); + my $smsg = PublicInbox::SearchMsg->wrap($doc); + $smsg->{doc_id} = $doc_id; + $smsg->load_expand; + }); } sub each_smsg_by_mid { @@ -439,24 +400,6 @@ sub each_smsg_by_mid { } } -# returns begin and end PostingIterator -sub find_doc_ids { - my ($self, $termval) = @_; - my $db = $self->{xdb}; - - ($db->postlist_begin($termval), $db->postlist_end($termval)); -} - -sub find_first_doc_id { - my ($self, $termval) = @_; - - my ($begin, $end) = $self->find_doc_ids($termval); - - return undef if $begin->equal($end); # not found - - $begin->get_docid; -} - # normalize subjects so they are suitable as pathnames for URLs # XXX: consider for removal sub subject_path {