about summary refs log tree commit homepage
path: root/lib/PublicInbox/View.pm
diff options
context:
space:
mode:
authorEric Wong <e@yhbt.net>2020-07-05 23:27:45 +0000
committerEric Wong <e@yhbt.net>2020-07-06 20:01:15 +0000
commit8d3f4751eacbad29e24da26aafacfe9b6bad22a3 (patch)
tree55e9a9974ebf32e554099eb6edf47e96e1a51a3c /lib/PublicInbox/View.pm
parent0179230221231f8f5a3edc2f2836cc7c7e089dda (diff)
downloadpublic-inbox-8d3f4751eacbad29e24da26aafacfe9b6bad22a3.tar.gz
Once again, this shows a ~10% speedup with multi-message
threads in xt/httpd-async-stream.t regardless of whether
TEST_JOBS is 1 or 100.
Diffstat (limited to 'lib/PublicInbox/View.pm')
-rw-r--r--lib/PublicInbox/View.pm44
1 files changed, 27 insertions, 17 deletions
diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm
index 98445f0e..117257a6 100644
--- a/lib/PublicInbox/View.pm
+++ b/lib/PublicInbox/View.pm
@@ -375,7 +375,7 @@ sub thread_eml_entry {
         $beg . '<pre>' . eml_entry($ctx, $smsg, $eml, 0) . '</pre>' . $end;
 }
 
-sub next_in_queue ($;$) {
+sub next_in_queue ($$) {
         my ($q, $ghost_ok) = @_;
         while (@$q) {
                 my ($level, $smsg) = splice(@$q, 0, 2);
@@ -387,29 +387,39 @@ sub next_in_queue ($;$) {
 }
 
 sub stream_thread_i { # PublicInbox::WwwStream::getline callback
-        my ($ctx) = @_;
-        return unless exists($ctx->{skel});
-        my $nr = $ctx->{nr}++;
-        my ($level, $smsg) = next_in_queue($ctx->{-queue}, $nr);
-
-        $smsg or return
-                join('', thread_adj_level($ctx, 0)) . ${delete $ctx->{skel}};
-
-        my $eml = $ctx->{-inbox}->smsg_eml($smsg) or return
-                ghost_index_entry($ctx, $level, $smsg);
+        my ($ctx, $eml) = @_;
 
-        if ($nr == 0) {
-                $ctx->{-title_html} = ascii_html($smsg->{subject});
-                $ctx->html_top . thread_eml_entry($ctx, $level, $smsg, $eml);
-        } else {
-                thread_eml_entry($ctx, $level, $smsg, $eml);
+        if ($eml) {
+                my ($level, $smsg) = delete @$ctx{qw(level smsg)};
+                if ($ctx->{nr} == 1) {
+                        $ctx->{-title_html} = ascii_html($smsg->{subject});
+                        $ctx->zmore($ctx->html_top);
+                }
+                return thread_eml_entry($ctx, $level, $smsg, $eml);
+        }
+        return unless exists($ctx->{skel});
+        my $ghost_ok = $ctx->{nr}++;
+        while (1) {
+                my ($lvl, $smsg) = next_in_queue($ctx->{-queue}, $ghost_ok);
+                if ($smsg) {
+                        if (exists $smsg->{blob}) { # next message for cat-file
+                                $ctx->{level} = $lvl;
+                                return $smsg;
+                        }
+                        # buffer the ghost entry and loop
+                        $ctx->zmore(ghost_index_entry($ctx, $lvl, $smsg));
+                } else { # all done
+                        $ctx->zmore(join('', thread_adj_level($ctx, 0)));
+                        $ctx->zmore(${delete($ctx->{skel})});
+                        return;
+                }
         }
 }
 
 sub stream_thread ($$) {
         my ($rootset, $ctx) = @_;
         $ctx->{-queue} = [ map { (0, $_) } @$rootset ];
-        PublicInbox::WwwStream::response($ctx, 200, \&stream_thread_i);
+        PublicInbox::WwwStream::aresponse($ctx, 200, \&stream_thread_i);
 }
 
 # /$INBOX/$MESSAGE_ID/t/