diff options
author | Eric Wong <e@80x24.org> | 2021-03-20 19:04:04 +0900 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2021-03-21 09:45:47 +0000 |
commit | b6829bbfd86f5d22a8ffb80fd7bfe59299fe6b55 (patch) | |
tree | 97a6e0a9bb519c24fdbef52776312861990af9b5 /lib/PublicInbox/LeiSearch.pm | |
parent | 7d2e572aca7297ea2015d2b6e7c71b672521ec82 (diff) | |
download | public-inbox-b6829bbfd86f5d22a8ffb80fd7bfe59299fe6b55.tar.gz |
"lei q" now preserves changes per-message keywords across invocations when it's --output (Maildir or mbox) is reused (with or without --augment). In the future, these changes will be monitored via inotify, EVFILT_VNODE or IMAP IDLE, too. Unfortunately, this currently prevents "lei import" from ever importing a message that's in an external. That will be fixed in a future change.
Diffstat (limited to 'lib/PublicInbox/LeiSearch.pm')
-rw-r--r-- | lib/PublicInbox/LeiSearch.pm | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/lib/PublicInbox/LeiSearch.pm b/lib/PublicInbox/LeiSearch.pm index 2e3f10fd..360a37e5 100644 --- a/lib/PublicInbox/LeiSearch.pm +++ b/lib/PublicInbox/LeiSearch.pm @@ -27,6 +27,20 @@ sub msg_keywords { wantarray ? sort(keys(%$kw)) : $kw; } +sub xsmsg_vmd { + my ($self, $smsg) = @_; + return if $smsg->{kw}; + my $xdb = $self->xdb; # set {nshard}; + my %kw; + $kw{flagged} = 1 if delete($smsg->{lei_q_tt_flagged}); + my @num = $self->over->blob_exists($smsg->{blob}); + for my $num (@num) { # there should only be one... + my $kw = xap_terms('K', $xdb, num2docid($self, $num)); + %kw = (%kw, %$kw); + } + $smsg->{kw} = [ sort keys %kw ] if scalar(keys(%kw)); +} + # when a message has no Message-IDs at all, this is needed for # unsent Draft messages, at least sub content_key ($) { @@ -43,41 +57,42 @@ sub content_key ($) { } sub _cmp_1st { # git->cat_async callback - my ($bref, $oid, $type, $size, $cmp) = @_; # cmp: [chash, found, smsg] - if (content_hash(PublicInbox::Eml->new($bref)) eq $cmp->[0]) { + my ($bref, $oid, $type, $size, $cmp) = @_; # cmp: [chash, xoids, smsg] + if ($bref && content_hash(PublicInbox::Eml->new($bref)) eq $cmp->[0]) { $cmp->[1]->{$oid} = $cmp->[2]->{num}; } } -sub xids_for { # returns { OID => docid } mapping for $eml matches +sub xoids_for { # returns { OID => docid } mapping for $eml matches my ($self, $eml, $min) = @_; my ($chash, $mids) = content_key($eml); my @overs = ($self->over // $self->overs_all); my $git = $self->git; - my $found = {}; + my $xoids = {}; for my $mid (@$mids) { for my $o (@overs) { my ($id, $prev); while (my $cur = $o->next_by_mid($mid, \$id, \$prev)) { - next if $found->{$cur->{blob}}; + next if $cur->{bytes} == 0 || + $xoids->{$cur->{blob}}; $git->cat_async($cur->{blob}, \&_cmp_1st, - [ $chash, $found, $cur ]); - if ($min && scalar(keys %$found) >= $min) { + [ $chash, $xoids, $cur ]); + if ($min && scalar(keys %$xoids) >= $min) { $git->cat_async_wait; - return $found; + return $xoids; } } } } $git->cat_async_wait; - scalar(keys %$found) ? $found : undef; + scalar(keys %$xoids) ? $xoids : undef; } # returns true if $eml is indexed by lei/store and keywords don't match sub kw_changed { my ($self, $eml, $new_kw_sorted) = @_; - my $found = xids_for($self, $eml, 1) // return; - my ($num) = values %$found; + my $xoids = xoids_for($self, $eml, 1) // return; + my ($num) = values %$xoids; my @cur_kw = msg_keywords($self, $num); join("\0", @$new_kw_sorted) eq join("\0", @cur_kw) ? 0 : 1; } |