]> Sergey Matveev's repositories - public-inbox.git/commitdiff
www: discard multipart parent on iteration
authorEric Wong <e@yhbt.net>
Sat, 11 Jan 2020 06:28:16 +0000 (06:28 +0000)
committerEric Wong <e@yhbt.net>
Sun, 12 Jan 2020 21:26:42 +0000 (21:26 +0000)
We're often iterating through messages while writing to another
buffer in our WWW interface, causing memory usage to multiply.
Since we know we won't need to keep the MIME object around in
some cases, and can tell msg_iter to clobber the on-stack
variable while it operates on subparts of multipart messages.

With xt/mem-msgview.t switched to multipart from the previous
commit, this shows a 13 MB memory reduction on that test.

lib/PublicInbox/MsgIter.pm
lib/PublicInbox/SolverGit.pm
lib/PublicInbox/View.pm
lib/PublicInbox/WwwAtomStream.pm
lib/PublicInbox/WwwAttach.pm

index cdd78b39b2afaf75dea36062c40354afab2c1e18..f238954bcdd5b7a04c8f631c8308d067f3146945 100644 (file)
@@ -12,10 +12,11 @@ use PublicInbox::MIME;
 # Like Email::MIME::walk_parts, but this is:
 # * non-recursive
 # * passes depth and indices to the iterator callback
-sub msg_iter ($$;$) {
-       my ($mime, $cb, $cb_arg) = @_;
+sub msg_iter ($$;$$) {
+       my ($mime, $cb, $cb_arg, $do_undef) = @_;
        my @parts = $mime->subparts;
        if (@parts) {
+               $mime = $_[0] = undef if $do_undef; # saves some memory
                my $i = 0;
                @parts = map { [ $_, 1, ++$i ] } @parts;
                while (my $p = shift @parts) {
index 8629f0dafeb4216b41ac2c0951c866c8e76c2dcf..b48e8ac429e8676687ad97919a1bcfb373b17f7e 100644 (file)
@@ -233,9 +233,8 @@ sub find_extract_diffs ($$$) {
        my $diffs = [];
        foreach my $smsg (@$msgs) {
                $ibx->smsg_mime($smsg) or next;
-               my $mime = delete $smsg->{mime};
-               msg_iter($mime, \&extract_diff,
-                               [$self, $diffs, $pre, $post, $ibx, $smsg]);
+               msg_iter(delete $smsg->{mime}, \&extract_diff,
+                               [$self, $diffs, $pre, $post, $ibx, $smsg], 1);
        }
        @$diffs ? $diffs : undef;
 }
index 405da2a930a9fe104983cfec75ea20ea45d8bb72..d88b34da431f0975282993f885a6ab0ee44fa443 100644 (file)
@@ -275,7 +275,7 @@ sub index_entry {
        # scan through all parts, looking for displayable text
        $ctx->{mhref} = $mhref;
        $ctx->{rv} = \$rv;
-       msg_iter($mime, \&add_text_body, $ctx);
+       msg_iter($mime, \&add_text_body, $ctx, 1);
        delete $ctx->{rv};
 
        # add the footer
@@ -506,12 +506,12 @@ sub thread_html_i { # PublicInbox::WwwStream::getline callback
 }
 
 sub multipart_text_as_html {
-       my ($mime, $mhref, $ctx) = @_;
+       my (undef, $mhref, $ctx) = @_; # $mime = $_[0]
        $ctx->{mhref} = $mhref;
        $ctx->{rv} = \(my $rv = '');
 
        # scan through all parts, looking for displayable text
-       msg_iter($mime, \&add_text_body, $ctx);
+       msg_iter($_[0], \&add_text_body, $ctx, 1);
        ${delete $ctx->{rv}};
 }
 
index 9430dd97679eed5049d65de63bc96129b8159b27..9ec1383dada276b101a35df7ea3809692609567e 100644 (file)
@@ -101,9 +101,9 @@ sub atom_header {
 sub feed_entry {
        my ($self, $smsg) = @_;
        my $ctx = $self->{ctx};
-       my $mime = $smsg->{mime};
+       my $mid = $smsg->mid; # may extract Message-ID from {mime}
+       my $mime = delete $smsg->{mime};
        my $hdr = $mime->header_obj;
-       my $mid = $smsg->mid;
        my $irt = PublicInbox::View::in_reply_to($hdr);
        my $uuid = to_uuid($mid);
        my $base = $ctx->{feed_base_url};
index cda1c6c8db3a0745e8ad28a1cffaad05e10de6cf..92f47e4913ae7b006da939e612969f3fdf1ad1a4 100644 (file)
@@ -40,7 +40,7 @@ sub get_attach ($$$) {
        my $mime = $ctx->{-inbox}->msg_by_mid($ctx->{mid}) or return $res;
        $mime = PublicInbox::MIME->new($mime);
        $res->[3] = $idx;
-       msg_iter($mime, \&get_attach_i, $res);
+       msg_iter($mime, \&get_attach_i, $res, 1);
        pop @$res; # cleanup before letting PSGI server see it
        $res
 }