From: Brandon L Black Date: Sat, 21 Apr 2007 16:58:44 +0000 (+0000) Subject: even better, 1 stack, but no arrayref X-Git-Tag: 0.07~1 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=719de54bf16aad530ef6c3603fda34f45849c795;p=gitmo%2FAlgorithm-C3.git even better, 1 stack, but no arrayref --- diff --git a/lib/Algorithm/C3.pm b/lib/Algorithm/C3.pm index 73ede8e..ce473c7 100644 --- a/lib/Algorithm/C3.pm +++ b/lib/Algorithm/C3.pm @@ -13,11 +13,7 @@ sub merge { $cache ||= {}; - # stacks for simulating recursion - my @RSTACK; - my @PSTACK; - my @MSTACK; - my @ISTACK; + my @STACK; # stack for simulating recursion my $pfetcher_is_coderef = ref($parent_fetcher) eq 'CODE'; @@ -37,13 +33,14 @@ sub merge { $new_root = $current_parents->[$i++]; if($seen{$new_root}) { - my @isastack = ( - @RSTACK, - $current_root, - $new_root - ); - shift @isastack while $isastack[0] ne $new_root; - my $isastack = join(q{ -> }, @isastack); + my @isastack; + my $reached; + for(my $i = 0; $i < $#STACK; $i += 4) { + if($reached || ($reached = ($STACK[$i] eq $new_root))) { + push(@isastack, $STACK[$i]); + } + } + my $isastack = join(q{ -> }, @isastack, $current_root, $new_root); die "Infinite loop detected in parents of '$root': $isastack"; } $seen{$new_root} = 1; @@ -52,10 +49,7 @@ sub merge { confess "Could not find method $parent_fetcher in $new_root"; } - push(@RSTACK, $current_root); - push(@PSTACK, $current_parents); - push(@MSTACK, $recurse_mergeout); - push(@ISTACK, $i); + push(@STACK, $current_root, $current_parents, $recurse_mergeout, $i); $current_root = $new_root; $current_parents = $cache->{pfetch}->{$current_root} ||= [ $current_root->$parent_fetcher ]; @@ -120,12 +114,12 @@ sub merge { \@res; }; - return @$mergeout if !@ISTACK; + return @$mergeout if !@STACK; - $current_root = pop(@RSTACK); - $current_parents = pop(@PSTACK); - $recurse_mergeout = pop(@MSTACK); - $i = pop(@ISTACK); + $i = pop(@STACK); + $recurse_mergeout = pop(@STACK); + $current_parents = pop(@STACK); + $current_root = pop(@STACK); push(@$recurse_mergeout, $mergeout) if @$mergeout; }