From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 5BE4F1FA0E for ; Wed, 10 Jun 2020 07:05:20 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 06/82] msgmap: split ->max into its own method Date: Wed, 10 Jun 2020 07:04:03 +0000 Message-Id: <20200610070519.18252-7-e@yhbt.net> In-Reply-To: <20200610070519.18252-1-e@yhbt.net> References: <20200610070519.18252-1-e@yhbt.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: There's enough places where we only care about the max NNTP article number to warrant avoiding a call into SQLite. Using ->num_highwater in read-only packages such as PublicInbox::IMAP is also incorrect, since that memoizes and won't pick up changes made by other processes. --- lib/PublicInbox/IMAP.pm | 10 +++++----- lib/PublicInbox/Msgmap.pm | 20 +++++++++++--------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/lib/PublicInbox/IMAP.pm b/lib/PublicInbox/IMAP.pm index 99c6c817fd7..4a43185c512 100644 --- a/lib/PublicInbox/IMAP.pm +++ b/lib/PublicInbox/IMAP.pm @@ -146,7 +146,7 @@ sub cmd_noop ($$) { "$_[1] OK NOOP completed\r\n" } # called by PublicInbox::InboxIdle sub on_inbox_unlock { my ($self, $ibx) = @_; - my $new = ($ibx->mm->minmax)[1]; + my $new = $ibx->mm->max; defined(my $old = $self->{-idle_max}) or die 'BUG: -idle_max unset'; if ($new > $old) { $self->{-idle_max} = $new; @@ -161,7 +161,7 @@ sub cmd_idle ($$) { my $ibx = $self->{ibx} or return "$tag BAD no mailbox selected\r\n"; $ibx->subscribe_unlock(fileno($self->{sock}), $self); $self->{-idle_tag} = $tag; - $self->{-idle_max} = ($ibx->mm->minmax)[1] // 0; + $self->{-idle_max} = $ibx->mm->max // 0; "+ idling\r\n" } @@ -182,7 +182,7 @@ sub cmd_examine ($$$) { my $ibx = $self->{imapd}->{groups}->{$mailbox} or return "$tag NO Mailbox doesn't exist: $mailbox\r\n"; my $mm = $ibx->mm; - my $max = $mm->num_highwater // 0; + my $max = $mm->max // 0; # RFC 3501 2.3.1.1 - "A good UIDVALIDITY value to use in # this case is a 32-bit representation of the creation # date/time of the mailbox" @@ -320,7 +320,7 @@ sub cmd_uid_fetch ($$$;@) { if ($range =~ /\A([0-9]+):([0-9]+)\z/s) { ($beg, $end) = ($1, $2); } elsif ($range =~ /\A([0-9]+):\*\z/s) { - ($beg, $end) = ($1, $ibx->mm->num_highwater // 0); + ($beg, $end) = ($1, $ibx->mm->max // 0); } elsif ($range =~ /\A[0-9]+\z/) { my $smsg = $ibx->over->get_art($range) or return "$tag OK\r\n"; push @$msgs, $smsg; @@ -365,7 +365,7 @@ sub cmd_uid_search ($$$;) { } elsif ($arg eq 'UID' && scalar(@rest) == 1) { if ($rest[0] =~ /\A([0-9]+):([0-9]+|\*)\z/s) { my ($beg, $end) = ($1, $2); - $end = ($ibx->mm->minmax)[1] if $end eq '*'; + $end = $ibx->mm->max if $end eq '*'; $self->msg_more('* SEARCH'); long_response($self, \&uid_search_uid_range, $tag, $ibx, \$beg, $end); diff --git a/lib/PublicInbox/Msgmap.pm b/lib/PublicInbox/Msgmap.pm index a2ffe7203e7..d115cbce352 100644 --- a/lib/PublicInbox/Msgmap.pm +++ b/lib/PublicInbox/Msgmap.pm @@ -55,8 +55,7 @@ sub new_file { $dbh->begin_work; $self->created_at(time) unless $self->created_at; - my (undef, $max) = $self->minmax(); - $max ||= 0; + my $max = $self->max // 0; $self->num_highwater($max); $dbh->commit; } @@ -159,17 +158,20 @@ sub num_for { $sth->fetchrow_array; } +sub max { + my $sth = $_[0]->{dbh}->prepare_cached('SELECT MAX(num) FROM msgmap', + undef, 1); + $sth->execute; + $sth->fetchrow_array; +} + sub minmax { - my ($self) = @_; - my $dbh = $self->{dbh}; # breaking MIN and MAX into separate queries speeds up from 250ms # to around 700us with 2.7million messages. - my $sth = $dbh->prepare_cached('SELECT MIN(num) FROM msgmap', undef, 1); - $sth->execute; - my $min = $sth->fetchrow_array; - $sth = $dbh->prepare_cached('SELECT MAX(num) FROM msgmap', undef, 1); + my $sth = $_[0]->{dbh}->prepare_cached('SELECT MIN(num) FROM msgmap', + undef, 1); $sth->execute; - ($min, $sth->fetchrow_array); + ($sth->fetchrow_array, max($_[0])); } sub mid_delete {