pop3: reduce memory use while generating the mailbox cache
authorEric Wong <e@80x24.org>
Sat, 23 Jul 2022 06:12:16 +0000 (06:12 +0000)
committerEric Wong <e@80x24.org>
Sat, 23 Jul 2022 14:22:35 +0000 (14:22 +0000)
While the cache itself is relatively compact for 50K messages,
generating it was inefficient due to our schema and Over.pm APIs
being designed for NNTP.  While we won't change our schema for
now, we can choose better DBI APIs to use and limit our ephemeral
memory use.

This amounts to a 60% reduction in memory usage and a 5-10%
speedup against org.kernel.vger.git.0:

{
echo 'USER '$(uuidgen)'@org.kernel.vger.git.0'
echo PASS anonymous
echo STAT
echo QUIT
} | nc $HOST $PORT

lib/PublicInbox/POP3.pm

index 60eedea761dace658a8b77f1ca6bb167c321b9e7..203c91a6b3cff4f1697ffc8677b997d7a7fd3caf 100644 (file)
@@ -148,12 +148,21 @@ sub _stat_cache ($) {
        my ($self) = @_;
        my ($beg, $end) = (($self->{uid_dele} // -1) + 1, $self->{uid_max});
        PublicInbox::IMAP::uid_clamp($self, \$beg, \$end);
-       my $opt = { limit => PublicInbox::IMAP::UID_SLICE };
-       my $m = $self->{ibx}->over(1)->do_get(<<'', $opt, $beg, $end);
+       my (@cache, $m);
+       my $sth = $self->{ibx}->over(1)->dbh->prepare_cached(<<'', undef, 1);
 SELECT num,ddd FROM over WHERE num >= ? AND num <= ?
 ORDER BY num ASC
 
-       [ map { ($_->{num}, $_->{bytes} + 0, $_->{blob}) } @$m ];
+       $sth->execute($beg, $end);
+       do {
+               $m = $sth->fetchall_arrayref({}, 1000);
+               for my $x (@$m) {
+                       PublicInbox::Over::load_from_row($x);
+                       push(@cache, $x->{num}, $x->{bytes} + 0, $x->{blob});
+                       undef $x; # saves ~1.5M memory w/ 50k messages
+               }
+       } while (scalar(@$m) && ($beg = $cache[-3] + 1));
+       \@cache;
 }
 
 sub cmd_stat {