From: Eric Wong <e@yhbt.net>
Date: Wed, 10 Jun 2020 07:04:03 +0000 (+0000)
Subject: msgmap: split ->max into its own method
X-Git-Tag: v1.6.0~461
X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=eab4dfdda4eeea9a54aa674510fa11789c5f91c8;p=public-inbox.git

msgmap: split ->max into its own method

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.
---

diff --git a/lib/PublicInbox/IMAP.pm b/lib/PublicInbox/IMAP.pm
index 99c6c817..4a43185c 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 a2ffe720..d115cbce 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 {