From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: 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.0 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 590912018E for ; Tue, 21 Jun 2016 03:12:03 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 4/7] view: remove recursion from expanded thread view Date: Tue, 21 Jun 2016 03:11:58 +0000 Message-Id: <20160621031201.28089-5-e@80x24.org> In-Reply-To: <20160621031201.28089-1-e@80x24.org> References: <20160621031201.28089-1-e@80x24.org> List-Id: This should let us generate HTML for arbitrarily deep threads without blowing the stack. How it renders on the client side is another matter... --- lib/PublicInbox/View.pm | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/PublicInbox/View.pm b/lib/PublicInbox/View.pm index e09fbd5..bc4a443 100644 --- a/lib/PublicInbox/View.pm +++ b/lib/PublicInbox/View.pm @@ -177,8 +177,13 @@ sub emit_thread_html { pre_anchor_entry($seen, $_) for (@$msgs); __thread_entry($state, $_, 0) for (@$msgs); } else { - my $th = thread_results($msgs); - thread_entry($state, $_, 0) for $th->rootset; + my @q = map { (0, $_) } thread_results($msgs)->rootset; + while (@q) { + my $level = shift @q; + my $node = shift @q or next; + thread_entry($state, $level, $node); + unshift @q, $level+1, $node->child, $level, $node->next; + } if (my $max = $state->{cur_level}) { $state->{fh}->write( ('' x ($max - 1)) . ''); @@ -618,8 +623,7 @@ sub __ghost_prepare { } sub thread_entry { - my ($state, $node, $level) = @_; - return unless $node; + my ($state, $level, $node) = @_; if (my $mime = $node->message) { unless (__thread_entry($state, $mime, $level)) { __ghost_prepare($state, $node, $level); @@ -627,9 +631,6 @@ sub thread_entry { } else { __ghost_prepare($state, $node, $level); } - - thread_entry($state, $node->child, $level + 1); - thread_entry($state, $node->next, $level); } sub load_results {