From 0bb4497fbe72da582640fdbf3b3db9fa88534a0e Mon Sep 17 00:00:00 2001 From: Daniel Nichter Date: Sun, 11 Sep 2011 12:32:26 -0600 Subject: [PATCH] Avoid recursion in main NibbleIterator loop. --- lib/NibbleIterator.pm | 81 +++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/lib/NibbleIterator.pm b/lib/NibbleIterator.pm index 2fe5301b..c9863307 100644 --- a/lib/NibbleIterator.pm +++ b/lib/NibbleIterator.pm @@ -181,19 +181,47 @@ sub next { } } - # Return rows in nibble. sth->{Active} is always true with DBD::mysql v3, - # so we track the status manually. have_rows will be true if a previous - # call got a nibble with rows. When there's no more rows in this nibble, - # try to get the next nibble. - if ( $self->{have_rows} ) { - my $row = $self->{nibble_sth}->fetchrow_arrayref(); - if ( $row ) { - $self->{rowno}++; - MKDEBUG && _d('Row', $self->{rowno}, 'in nibble', $self->{nibbleno}); - # fetchrow_arraryref re-uses its internal arrayref, so we must copy. - return [ @$row ]; + # If there's another boundary, fetch the rows within it. + BOUNDARY: + while ( $self->{have_rows} || $self->_next_boundaries() ) { + # If no rows, then we just got the next boundaries, which start + # the next nibble. + if ( !$self->{have_rows} ) { + $self->{nibbleno}++; + MKDEBUG && _d($self->{nibble_sth}->{Statement}, 'params:', + join(', ', (@{$self->{lb}}, @{$self->{ub}}))); + if ( my $callback = $self->{callbacks}->{exec_nibble} ) { + $self->{have_rows} = $callback->( + dbh => $self->{dbh}, + tbl => $self->{tbl}, + sth => $self->{nibble_sth}, + lb => $self->{lb}, + ub => $self->{ub}, + nibbleno => $self->{nibbleno}, + explain_sth => $self->{explain_sth}, + ); + } + else { + $self->{nibble_sth}->execute(@{$self->{lb}}, @{$self->{ub}}); + $self->{have_rows} = $self->{nibble_sth}->rows(); + } } - MKDEBUG && _d('No more rows in nibble', $self->{nibbleno}); + + # Return rows in this nibble. + if ( $self->{have_rows} ) { + MKDEBUG && _d($self->{have_rows}, 'rows in nibble', $self->{nibbleno}); + # Return rows in nibble. sth->{Active} is always true with + # DBD::mysql v3, so we track the status manually. + my $row = $self->{nibble_sth}->fetchrow_arrayref(); + if ( $row ) { + $self->{rowno}++; + MKDEBUG && _d('Row', $self->{rowno}, 'in nibble',$self->{nibbleno}); + # fetchrow_arraryref re-uses an internal arrayref, so we must copy. + return [ @$row ]; + } + } + + MKDEBUG && _d('No rows in nibble or nibble skipped'); if ( my $callback = $self->{callbacks}->{after_nibble} ) { $callback->( dbh => $self->{dbh}, @@ -206,35 +234,6 @@ sub next { $self->{have_rows} = 0; } - # If there's another boundary, fetch the rows within it. - BOUNDARY: - while ( $self->_next_boundaries() ) { - $self->{nibbleno}++; - MKDEBUG && _d($self->{nibble_sth}->{Statement}, 'params:', - join(', ', (@{$self->{lb}}, @{$self->{ub}}))); - if ( my $callback = $self->{callbacks}->{exec_nibble} ) { - $self->{have_rows} = $callback->( - dbh => $self->{dbh}, - tbl => $self->{tbl}, - sth => $self->{nibble_sth}, - lb => $self->{lb}, - ub => $self->{ub}, - nibbleno => $self->{nibbleno}, - explain_sth => $self->{explain_sth}, - ); - } - else { - $self->{nibble_sth}->execute(@{$self->{lb}}, @{$self->{ub}}); - $self->{have_rows} = $self->{nibble_sth}->rows(); - } - if ( $self->{have_rows} ) { - MKDEBUG && _d($self->{have_rows}, 'rows in nibble', $self->{nibbleno}); - return $self->next(); - } - MKDEBUG && _d('No rows in nibble or nibble skipped'); - next BOUNDARY; - } - MKDEBUG && _d('Done nibbling'); if ( my $callback = $self->{callbacks}->{done} ) { $callback->(