rewrite the problem code. Clearly I can't debug the old code, the new one is simpler

and should be faster/easier to debug/understand.
This commit is contained in:
kestes%walrus.com 2002-05-07 01:50:48 +00:00
Родитель 9b40073368
Коммит 901e4e4588
1 изменённых файлов: 307 добавлений и 333 удалений

Просмотреть файл

@ -40,8 +40,8 @@
# Contributor(s):
# $Revision: 1.52 $
# $Date: 2002-05-07 00:23:49 $
# $Revision: 1.53 $
# $Date: 2002-05-07 01:50:48 $
# $Author: kestes%walrus.com $
# $Source: /home/jrmuizel/cvs-mirror/mozilla/webtools/tinderbox2/src/lib/TinderDB/VC_Bonsai.pm,v $
# $Name: $
@ -101,7 +101,7 @@ use TreeData;
use VCDisplay;
$VERSION = ( qw $Revision: 1.52 $ )[1];
$VERSION = ( qw $Revision: 1.53 $ )[1];
@ISA = qw(TinderDB::BasicTxtDB);
@ -340,222 +340,67 @@ sub status_table_header {
}
# Return the data which would appear in a cell if we were to render
# it. The checkin data comes back in a datastructure and we return
# the oldest treestate found in this cell.
# clear data structures in preparation for printing a new table
sub status_table_start {
my ($self, $row_times, $tree, ) = @_;
# create an ordered list of all times which any data is stored
# sort numerically descending
@DB_TIMES = sort {$b <=> $a} keys %{ $DATABASE{$tree} };
# NEXT_DB is my index into the list of all times.
# adjust the $NEXT_DB to skip data which came after the first cell
# at the top of the page. We make the first cell bigger then the
# rest to allow for some overlap between pages.
my ($first_cell_seconds) = 2*($row_times->[0] - $row_times->[1]);
my ($earliest_data) = $row_times->[0] + $first_cell_seconds;
$NEXT_DB{$tree} = 0;
while ( ($DB_TIMES[$NEXT_DB{$tree}] > $earliest_data) &&
($NEXT_DB{$tree} < $#DB_TIMES) ) {
$NEXT_DB{$tree}++
}
# we do not store a treestate with every database entry.
# remember the treestate as we travel through the database.
$LAST_TREESTATE{$tree} = '';
# Sometimes our output will span several rows. This will track the
# next row in which we create more HTML.
$NEXT_ROW{$tree} = 0;
return ;
}
# a helper function to determine if we break a large cell symbolizing
# no data.
sub is_break_cell {
my ($tree,$time,$next_time) = @_;
# When building the first row of the status table LAST_TREESTATE
# is not defined. If we can find a treestate in the data
# structure use it.
if (defined($DATABASE{$tree}{$time}{'treestate'})) {
$LAST_TREESTATE{$tree} = $DATABASE{$tree}{$time}{'treestate'};
}
my $is_state1_different =
(
(defined($LAST_TREESTATE{$tree})) &&
(defined($DATABASE{$tree}{$next_time}{'treestate'})) &&
($LAST_TREESTATE{$tree} ne $DATABASE{$tree}{$next_time}{'treestate'}) &&
1);
my $is_state2_different =
(
(defined($LAST_TREESTATE{$tree})) &&
(defined($DATABASE{$tree}{$time}{'treestate'})) &&
($LAST_TREESTATE ne $DATABASE{$tree}{$time}{'treestate'}) &&
1);
my $is_state_different = $is_state1_different || $is_state2_different;
my $is_author_data = ( defined($DATABASE{$tree}{$time}{'author'}) ||
defined($DATABASE{$tree}{$next_time}{'author'}) );
my $is_break_cell = ( ($is_state_different) || ($is_author_data) );
return $is_break_cell;
}
sub status_table_row {
my ($self, $row_times, $row_index, $tree, ) = @_;
my (@outrow) = ();
# skip this column because it is part of a multi-row missing data
# cell?
if ( $NEXT_ROW{$tree} != $row_index ) {
push @outrow, ("\t<!-- VC_Bonsai: skipping. ".
"tree: $tree, ".
"additional_skips: ".
($NEXT_ROW{$tree} - $row_index).", ".
"previous_end: ".localtime($current_rec->{'timenow'}).", ".
" -->\n");
return @outrow;
}
# create a multi-row dummy cell for missing data?
# cell stops if there is author data in the following cell or the
# treestate changes.
# first find out what time the break will occur at.
while (
( $DB_TIMES[$NEXT_DB{$tree}] >= $row_times->[$#{$row_times}] ) &&
(!(
is_break_cell(
$tree,
$DB_TIMES[$NEXT_DB{$tree}],
$DB_TIMES[$NEXT_DB{$tree}+1],
)
))
) {
$NEXT_DB{$tree}++
}
# If there is no treestate, then the tree state has not changed
# since an early time. The earliest time was assigned a state in
# apply_db_updates(). It is possible that there are no treestates at
# all this should not prevent the VC column from being rendered.
if (!($LAST_TREESTATE{$tree})) {
$LAST_TREESTATE{$tree} = $TinderHeader::HEADER2DEFAULT_HTML{'TreeState'};
}
my ($cell_color) = TreeData::TreeState2color($LAST_TREESTATE{$tree});
my ($char) = TreeData::TreeState2char($LAST_TREESTATE{$tree});
my $cell_options;
my $text_browser_color_string;
if ( ($LAST_TREESTATE{$tree}) && ($cell_color) ) {
$cell_options = "bgcolor=$cell_color ";
$text_browser_color_string =
HTMLPopUp::text_browser_color_string($cell_color, $char);
}
# Do we need a multiline empty cell or do we have data?
$next_time = $DB_TIMES[$NEXT_DB{$tree}];
if (
(!(defined($DATABASE{$tree}{$next_time}{'author'}))) ||
($next_time < $row_times->[$row_index] )
) {
# now convert the break time to a rowspan.
my ($rowspan) = 1;
while (
( ($row_index + $rowspan) <= $#{$row_times}) &&
( $next_time <
$row_times->[$row_index + $rowspan] )
) {
$rowspan++ ;
}
my ($cell_options) = ("rowspan=$rowspan ".
"bgcolor=$cell_color ");
my ($lc_time) = localtime($next_time);
push @outrow, ("\t<!-- VC_Bonsai: empty data. ".
"tree: $tree, ".
"Next_End: $lc_time, ".
"-->\n".
"\t\t<td align=center $cell_options>".
"$EMPTY_TABLE_CELL</td>\n");
$NEXT_ROW{$tree} = $row_index + $rowspan;
$NEXT_DB{$tree}++;
return @outrow;
}
# ----Where VC Data gets renderd-----
$NEXT_ROW{$tree} = $row_index + 1;
# we assume that tree states only change rarely so there are very
# few cells which have more then one state associated with them.
# It does not matter what we do with those cells.
# find all the authors who changed code at any point in this cell
# find the tree state for this cell.
sub cell_data {
my ($db_index, $last_time) = @_;
my (%authors) = ();
my $last_treestate;
while (1) {
my ($time) = $DB_TIMES[$NEXT_DB{$tree}];
my ($time) = $DB_TIMES[$db_index];
# find the DB entries which are needed for this cell
($time < $row_times->[$row_index]) && last;
($time < $last_time) && last;
$NEXT_DB{$tree}++;
$db_index++;
if (defined($DATABASE{$tree}{$time}{'treestate'})) {
$LAST_TREESTATE{$tree} = $DATABASE{$tree}{$time}{'treestate'};
$last_treestate = $DATABASE{$tree}{$time}{'treestate'};
}
# Now invert the data structure.
# Inside each cell, we want all the posts by the same author to
# appear together. The previous data structure allowed us to find
# out what data was in each cell.
foreach $author (keys %{ $DATABASE{$tree}{$time}{'author'} }) {
foreach $file (keys %{ $DATABASE{$tree}{$time}{'author'}{$author} }) {
my ($log) = $DATABASE{$tree}{$time}{'author'}{$author}{$file};
my $recs = $DATABASE{$tree}{$time}{'author'};
foreach $author (keys %{ $recs }) {
foreach $file (keys %{ $recs->{'author'}{$author} }) {
my ($log) = $recs->{$author}{$file};
$authors{$author}{$time}{$file} = $log;
}
}
} # while (1)
return ($db_index, $last_treestate, \%authors);
}
# produce the HTML which goes with this data.
sub render_authors {
my ($last_treestate, $authors, $mindate, $maxdate,) = @_;
# Now invert the data structure.
my %authors = %{$authors};
my ($cell_color) = TreeData::TreeState2color($last_treestate);
my ($char) = TreeData::TreeState2char($last_treestate);
my $cell_options;
my $text_browser_color_string;
if ( ($last_treestate) && ($cell_color) ) {
$cell_options = "bgcolor=$cell_color ";
$text_browser_color_string =
HTMLPopUp::text_browser_color_string($cell_color, $char);
}
my $query_links = '';
$query_links.= "\t\t".$text_browser_color_string."\n";
@ -564,19 +409,12 @@ sub status_table_row {
# find the times which bound the cell so that we can set up a
# VC query.
my ($mindate) = $row_times->[$row_index];
my ($maxdate);
if ($row_index > 0){
$maxdate = $row_times->[$row_index - 1];
} else {
$maxdate = $main::TIME;
}
my ($format_maxdate) = HTMLPopUp::timeHTML($maxdate);
my ($format_mindate) = HTMLPopUp::timeHTML($mindate);
my ($time_interval_str) = "$format_maxdate to $format_mindate",
# create a string of all VC data for displaying with the checkin table
# create a string of all VC data for displaying with the
# checkin table
my ($vc_info);
foreach $key ('module','branch',) {
@ -718,7 +556,8 @@ sub status_table_row {
$query_links .= "\t\t".$query_link."\n";
}
} # foreach %author
} # if %authors
$query_links.= "\t\t".$text_browser_color_string."\n";
@ -729,23 +568,158 @@ sub status_table_row {
"\t</td>\n".
"");
} else {
return @outrow;
}
# I should not need to put some arbitrary single empty cell here
# at the bottom, but I think this is prudent to have one.
sub render_empty_cell {
my ($last_treestate, $rowspan) = @_;
push @outrow, ("\t<!-- VC_Bonsai: catchall-skipping, ".
"should not get here. ".
my ($cell_color) = TreeData::TreeState2color($last_treestate);
my ($char) = TreeData::TreeState2char($last_treestate);
my $cell_options;
my $text_browser_color_string;
if ( ($last_treestate) && ($cell_color) ) {
$cell_options = "bgcolor=$cell_color ";
$text_browser_color_string =
HTMLPopUp::text_browser_color_string($cell_color, $char) ;
}
my $cell_contents = $text_browser_color_string || $EMPTY_TABLE_CELL;
return ("\t<!-- VC_Bonsai: empty data. ".
"tree: $tree, ".
"-->\n".
"\t\t<td align=center rowspan=$rowspan $cell_options>".
"$cell_contents</td>\n");
}
# clear data structures in preparation for printing a new table
sub status_table_start {
my ($self, $row_times, $tree, ) = @_;
# create an ordered list of all times which any data is stored
# sort numerically descending
@DB_TIMES = sort {$b <=> $a} keys %{ $DATABASE{$tree} };
# NEXT_DB is my index into the list of all times.
# adjust the $NEXT_DB to skip data which came after the first cell
# at the top of the page. We make the first cell bigger then the
# rest to allow for some overlap between pages.
my ($first_cell_seconds) = 2*($row_times->[0] - $row_times->[1]);
my ($earliest_data) = $row_times->[0] + $first_cell_seconds;
$NEXT_DB{$tree} = 0;
while ( ($DB_TIMES[$NEXT_DB{$tree}] > $earliest_data) &&
($NEXT_DB{$tree} < $#DB_TIMES) ) {
$NEXT_DB{$tree}++
}
# we do not store a treestate with every database entry.
# remember the treestate as we travel through the database.
$LAST_TREESTATE{$tree} = '';
# Sometimes our output will span several rows. This will track the
# next row in which we create more HTML.
$NEXT_ROW{$tree} = 0;
return ;
}
sub status_table_row {
my ($self, $row_times, $row_index, $tree, ) = @_;
my (@outrow) = ();
# skip this column because it is part of a multi-row missing data
# cell?
if ( $NEXT_ROW{$tree} != $row_index ) {
push @outrow, ("\t<!-- VC_Bonsai: skipping. ".
"tree: $tree, ".
"additional_skips: ".
($NEXT_ROW{$tree} - $row_index).", ".
"previous_end: ".localtime($current_rec->{'timenow'}).", ".
" -->\n");
return @outrow;
}
return @outrow;
}
# find all the authors who changed code at any point in this cell
# find the tree state for this cell.
my ($db_index, $last_treestate, $authors) =
cell_data( $NEXT_DB{$tree}, $row_times->[$row_index]);
if (%{$authors}) {
$NEXT_DB{$tree} = $db_index;
$NEXT_ROW{$tree} = $row_index + 1;
$LAST_TREESTATE{$tree} = $last_treestate || $LAST_TREESTATE{$tree};
my ($mindate) = $row_times->[$row_index],
my ($maxdate);
if ($row_index > 0){
$maxdate = $row_times->[$row_index - 1];
} else {
$maxdate = $main::TIME;
}
my @html = render_authors(
$LAST_TREESTATE{$tree},
$authors,
$mindate,
$maxdate,
);
return @html;
} else {
# create a multi-row dummy cell for missing data?
# cell stops if there is author data in the following cell or the
# treestate changes.
my $rowspan = 1;
my ($next_db_index, $next_treestate, $next_authors);
while (
!(%{$next_authors}) &&
(
!defined($next_treestate) ||
($last_treestate eq $next_treestate)
)
) {
($next_db_index, $next_treestate, $next_authors) =
cell_data( $db_index, $row_times->[$row_index+$rowspan]);
$db_index = $next_db_index;
$rowspan++ ;
}
$NEXT_ROW{$tree} = $row_index + $rowspan;
$NEXT_DB{$tree} = $db_index;
$LAST_TREESTATE{$tree} = $last_treestate || $LAST_TREESTATE{$tree};
my @html= render_empty_cell($LAST_TREESTATE{$tree}, $rowspan);
return @html;
}
# not reached
}
1;