gitk: replace parent and children arrays with lists

This will make it easier to switch between views efficiently, and
turns out to be slightly faster as well.

Signed-off-by: Paul Mackerras <paulus@samba.org>
maint
Paul Mackerras 2006-04-02 20:47:40 +10:00
parent 879e8b1aad
commit 79b2c75e04
1 changed files with 95 additions and 93 deletions

168
gitk
View File

@ -75,6 +75,7 @@ proc getcommitlines {commfd} {
global commitlisted nextupdate global commitlisted nextupdate
global leftover global leftover
global displayorder commitidx commitrow commitdata global displayorder commitidx commitrow commitdata
global parentlist childlist children


set stuff [read $commfd] set stuff [read $commfd]
if {$stuff == {}} { if {$stuff == {}} {
@ -140,15 +141,26 @@ proc getcommitlines {commfd} {
set id [lindex $ids 0] set id [lindex $ids 0]
if {$listed} { if {$listed} {
set olds [lrange $ids 1 end] set olds [lrange $ids 1 end]
set commitlisted($id) 1 if {[llength $olds] > 1} {
set olds [lsort -unique $olds]
}
foreach p $olds {
lappend children($p) $id
}
} else { } else {
set olds {} set olds {}
} }
updatechildren $id $olds lappend parentlist $olds
if {[info exists children($id)]} {
lappend childlist $children($id)
} else {
lappend childlist {}
}
set commitdata($id) [string range $cmit [expr {$j + 1}] end] set commitdata($id) [string range $cmit [expr {$j + 1}] end]
set commitrow($id) $commitidx set commitrow($id) $commitidx
incr commitidx incr commitidx
lappend displayorder $id lappend displayorder $id
lappend commitlisted $listed
set gotsome 1 set gotsome 1
} }
if {$gotsome} { if {$gotsome} {
@ -181,14 +193,12 @@ proc doupdate {reading} {


proc readcommit {id} { proc readcommit {id} {
if {[catch {set contents [exec git-cat-file commit $id]}]} return if {[catch {set contents [exec git-cat-file commit $id]}]} return
updatechildren $id {}
parsecommit $id $contents 0 parsecommit $id $contents 0
} }


proc updatecommits {rargs} { proc updatecommits {rargs} {
stopfindproc stopfindproc
foreach v {children nchildren parents nparents commitlisted foreach v {colormap selectedline matchinglines treediffs
colormap selectedline matchinglines treediffs
mergefilelist currentid rowtextx commitrow mergefilelist currentid rowtextx commitrow
rowidlist rowoffsets idrowranges idrangedrawn iddrawn rowidlist rowoffsets idrowranges idrangedrawn iddrawn
linesegends crossings cornercrossings} { linesegends crossings cornercrossings} {
@ -200,26 +210,6 @@ proc updatecommits {rargs} {
getcommits $rargs getcommits $rargs
} }


proc updatechildren {id olds} {
global children nchildren parents nparents

if {![info exists nchildren($id)]} {
set children($id) {}
set nchildren($id) 0
}
set parents($id) $olds
set nparents($id) [llength $olds]
foreach p $olds {
if {![info exists nchildren($p)]} {
set children($p) [list $id]
set nchildren($p) 1
} elseif {[lsearch -exact $children($p) $id] < 0} {
lappend children($p) $id
incr nchildren($p)
}
}
}

proc parsecommit {id contents listed} { proc parsecommit {id contents listed} {
global commitinfo cdate global commitinfo cdate


@ -274,7 +264,7 @@ proc parsecommit {id contents listed} {
} }


proc getcommit {id} { proc getcommit {id} {
global commitdata commitinfo nparents global commitdata commitinfo


if {[info exists commitdata($id)]} { if {[info exists commitdata($id)]} {
parsecommit $id $commitdata($id) 1 parsecommit $id $commitdata($id) 1
@ -282,7 +272,6 @@ proc getcommit {id} {
readcommit $id readcommit $id
if {![info exists commitinfo($id)]} { if {![info exists commitinfo($id)]} {
set commitinfo($id) {"No commit information available"} set commitinfo($id) {"No commit information available"}
set nparents($id) 0
} }
} }
return 1 return 1
@ -843,15 +832,20 @@ proc makeuparrow {oid x y z} {
} }


proc initlayout {} { proc initlayout {} {
global rowidlist rowoffsets displayorder global rowidlist rowoffsets displayorder commitlisted
global rowlaidout rowoptim global rowlaidout rowoptim
global idinlist rowchk global idinlist rowchk
global commitidx numcommits canvxmax canv global commitidx numcommits canvxmax canv
global nextcolor global nextcolor
global parentlist childlist children


set commitidx 0 set commitidx 0
set numcommits 0 set numcommits 0
set displayorder {} set displayorder {}
set commitlisted {}
set parentlist {}
set childlist {}
catch {unset children}
set nextcolor 0 set nextcolor 0
set rowidlist {{}} set rowidlist {{}}
set rowoffsets {{}} set rowoffsets {{}}
@ -950,7 +944,7 @@ proc showstuff {canshow} {
proc layoutrows {row endrow last} { proc layoutrows {row endrow last} {
global rowidlist rowoffsets displayorder global rowidlist rowoffsets displayorder
global uparrowlen downarrowlen maxwidth mingaplen global uparrowlen downarrowlen maxwidth mingaplen
global nchildren parents nparents global childlist parentlist
global idrowranges linesegends global idrowranges linesegends
global commitidx global commitidx
global idinlist rowchk global idinlist rowchk
@ -961,7 +955,7 @@ proc layoutrows {row endrow last} {
set id [lindex $displayorder $row] set id [lindex $displayorder $row]
set oldolds {} set oldolds {}
set newolds {} set newolds {}
foreach p $parents($id) { foreach p [lindex $parentlist $row] {
if {![info exists idinlist($p)]} { if {![info exists idinlist($p)]} {
lappend newolds $p lappend newolds $p
} elseif {!$idinlist($p)} { } elseif {!$idinlist($p)} {
@ -1000,7 +994,7 @@ proc layoutrows {row endrow last} {
lappend idlist $id lappend idlist $id
lset rowidlist $row $idlist lset rowidlist $row $idlist
set z {} set z {}
if {$nchildren($id) > 0} { if {[lindex $childlist $row] ne {}} {
set z [expr {[llength [lindex $rowidlist [expr {$row-1}]]] - $col}] set z [expr {[llength [lindex $rowidlist [expr {$row-1}]]] - $col}]
unset idinlist($id) unset idinlist($id)
} }
@ -1053,16 +1047,22 @@ proc layoutrows {row endrow last} {
} }


proc addextraid {id row} { proc addextraid {id row} {
global displayorder commitrow commitinfo nparents global displayorder commitrow commitinfo
global commitidx global commitidx
global parentlist childlist children


incr commitidx incr commitidx
lappend displayorder $id lappend displayorder $id
lappend parentlist {}
set commitrow($id) $row set commitrow($id) $row
readcommit $id readcommit $id
if {![info exists commitinfo($id)]} { if {![info exists commitinfo($id)]} {
set commitinfo($id) {"No commit information available"} set commitinfo($id) {"No commit information available"}
set nparents($id) 0 }
if {[info exists children($id)]} {
lappend childlist $children($id)
} else {
lappend childlist {}
} }
} }


@ -1365,7 +1365,7 @@ proc drawparentlinks {id row col olds} {
proc drawlines {id} { proc drawlines {id} {
global colormap canv global colormap canv
global idrowranges idrangedrawn global idrowranges idrangedrawn
global children iddrawn commitrow rowidlist global childlist iddrawn commitrow rowidlist


$canv delete lines.$id $canv delete lines.$id
set nr [expr {[llength $idrowranges($id)] / 2}] set nr [expr {[llength $idrowranges($id)] / 2}]
@ -1374,8 +1374,7 @@ proc drawlines {id} {
drawlineseg $id $i drawlineseg $id $i
} }
} }
if {[info exists children($id)]} { foreach child [lindex $childlist $commitrow($id)] {
foreach child $children($id) {
if {[info exists iddrawn($child)]} { if {[info exists iddrawn($child)]} {
set row $commitrow($child) set row $commitrow($child)
set col [lsearch -exact [lindex $rowidlist $row] $child] set col [lsearch -exact [lindex $rowidlist $row] $child]
@ -1385,7 +1384,6 @@ proc drawlines {id} {
} }
} }
} }
}


proc drawcmittext {id row col rmx} { proc drawcmittext {id row col rmx} {
global linespc canv canv2 canv3 canvy0 global linespc canv canv2 canv3 canvy0
@ -1394,7 +1392,7 @@ proc drawcmittext {id row col rmx} {
global linehtag linentag linedtag global linehtag linentag linedtag
global mainfont namefont canvxmax global mainfont namefont canvxmax


set ofill [expr {[info exists commitlisted($id)]? "blue": "white"}] set ofill [expr {[lindex $commitlisted $row]? "blue": "white"}]
set x [xc $row $col] set x [xc $row $col]
set y [yc $row] set y [yc $row]
set orad [expr {$linespc / 3}] set orad [expr {$linespc / 3}]
@ -1434,7 +1432,7 @@ proc drawcmittext {id row col rmx} {
proc drawcmitrow {row} { proc drawcmitrow {row} {
global displayorder rowidlist global displayorder rowidlist
global idrowranges idrangedrawn iddrawn global idrowranges idrangedrawn iddrawn
global commitinfo commitlisted parents numcommits global commitinfo commitlisted parentlist numcommits


if {$row >= $numcommits} return if {$row >= $numcommits} return
foreach id [lindex $rowidlist $row] { foreach id [lindex $rowidlist $row] {
@ -1465,9 +1463,9 @@ proc drawcmitrow {row} {
getcommit $id getcommit $id
} }
assigncolor $id assigncolor $id
if {[info exists commitlisted($id)] && [info exists parents($id)] set olds [lindex $parentlist $row]
&& $parents($id) ne {}} { if {$olds ne {}} {
set rmx [drawparentlinks $id $row $col $parents($id)] set rmx [drawparentlinks $id $row $col $olds]
} else { } else {
set rmx 0 set rmx 0
} }
@ -1511,15 +1509,22 @@ proc clear_display {} {


proc assigncolor {id} { proc assigncolor {id} {
global colormap colors nextcolor global colormap colors nextcolor
global parents nparents children nchildren global commitrow parentlist children childlist
global cornercrossings crossings global cornercrossings crossings


if {[info exists colormap($id)]} return if {[info exists colormap($id)]} return
set ncolors [llength $colors] set ncolors [llength $colors]
if {$nchildren($id) == 1} { if {[info exists commitrow($id)]} {
set child [lindex $children($id) 0] set kids [lindex $childlist $commitrow($id)]
} elseif {[info exists children($id)]} {
set kids $children($id)
} else {
set kids {}
}
if {[llength $kids] == 1} {
set child [lindex $kids 0]
if {[info exists colormap($child)] if {[info exists colormap($child)]
&& $nparents($child) == 1} { && [llength [lindex $parentlist $commitrow($child)]] == 1} {
set colormap($id) $colormap($child) set colormap($id) $colormap($child)
return return
} }
@ -1552,20 +1557,18 @@ proc assigncolor {id} {
set origbad $badcolors set origbad $badcolors
} }
if {[llength $badcolors] < $ncolors - 1} { if {[llength $badcolors] < $ncolors - 1} {
foreach child $children($id) { foreach child $kids {
if {[info exists colormap($child)] if {[info exists colormap($child)]
&& [lsearch -exact $badcolors $colormap($child)] < 0} { && [lsearch -exact $badcolors $colormap($child)] < 0} {
lappend badcolors $colormap($child) lappend badcolors $colormap($child)
} }
if {[info exists parents($child)]} { foreach p [lindex $parentlist $commitrow($child)] {
foreach p $parents($child) {
if {[info exists colormap($p)] if {[info exists colormap($p)]
&& [lsearch -exact $badcolors $colormap($p)] < 0} { && [lsearch -exact $badcolors $colormap($p)] < 0} {
lappend badcolors $colormap($p) lappend badcolors $colormap($p)
} }
} }
} }
}
if {[llength $badcolors] >= $ncolors} { if {[llength $badcolors] >= $ncolors} {
set badcolors $origbad set badcolors $origbad
} }
@ -1657,14 +1660,14 @@ proc drawtags {id x xt y1} {
} }


proc checkcrossings {row endrow} { proc checkcrossings {row endrow} {
global displayorder parents rowidlist global displayorder parentlist rowidlist


for {} {$row < $endrow} {incr row} { for {} {$row < $endrow} {incr row} {
set id [lindex $displayorder $row] set id [lindex $displayorder $row]
set i [lsearch -exact [lindex $rowidlist $row] $id] set i [lsearch -exact [lindex $rowidlist $row] $id]
if {$i < 0} continue if {$i < 0} continue
set idlist [lindex $rowidlist [expr {$row+1}]] set idlist [lindex $rowidlist [expr {$row+1}]]
foreach p $parents($id) { foreach p [lindex $parentlist $row] {
set j [lsearch -exact $idlist $p] set j [lsearch -exact $idlist $p]
if {$j > 0} { if {$j > 0} {
if {$j < $i - 1} { if {$j < $i - 1} {
@ -1760,7 +1763,7 @@ proc drawrest {} {
showstuff $commitidx showstuff $commitidx


set drawmsecs [expr {[clock clicks -milliseconds] - $startmsecs}] set drawmsecs [expr {[clock clicks -milliseconds] - $startmsecs}]
#puts "overall $drawmsecs ms for $numcommits commits" puts "overall $drawmsecs ms for $numcommits commits"
} }


proc findmatches {f} { proc findmatches {f} {
@ -2046,7 +2049,7 @@ proc insertmatch {l id} {


proc findfiles {} { proc findfiles {} {
global selectedline numcommits displayorder ctext global selectedline numcommits displayorder ctext
global ffileline finddidsel parents nparents global ffileline finddidsel parentlist
global findinprogress findstartline findinsertpos global findinprogress findstartline findinsertpos
global treediffs fdiffid fdiffsneeded fdiffpos global treediffs fdiffid fdiffsneeded fdiffpos
global findmergefiles global findmergefiles
@ -2064,7 +2067,7 @@ proc findfiles {} {
set fdiffsneeded {} set fdiffsneeded {}
while 1 { while 1 {
set id [lindex $displayorder $l] set id [lindex $displayorder $l]
if {$findmergefiles || $nparents($id) == 1} { if {$findmergefiles || [llength [lindex $parentlist $l]] == 1} {
if {![info exists treediffs($id)]} { if {![info exists treediffs($id)]} {
append diffsneeded "$id\n" append diffsneeded "$id\n"
lappend fdiffsneeded $id lappend fdiffsneeded $id
@ -2096,7 +2099,7 @@ proc findfiles {} {
. config -cursor watch . config -cursor watch
settextcursor watch settextcursor watch
set findinprogress 1 set findinprogress 1
findcont $id findcont
update update
} }


@ -2143,7 +2146,7 @@ proc donefilediff {} {
set treediffs($nullid) {} set treediffs($nullid) {}
if {[info exists findid] && $nullid eq $findid} { if {[info exists findid] && $nullid eq $findid} {
unset findid unset findid
findcont $nullid findcont
} }
incr fdiffpos incr fdiffpos
} }
@ -2154,20 +2157,21 @@ proc donefilediff {} {
} }
if {[info exists findid] && $fdiffid eq $findid} { if {[info exists findid] && $fdiffid eq $findid} {
unset findid unset findid
findcont $fdiffid findcont
} }
} }
} }


proc findcont {id} { proc findcont {id} {
global findid treediffs parents nparents global findid treediffs parentlist
global ffileline findstartline finddidsel global ffileline findstartline finddidsel
global displayorder numcommits matchinglines findinprogress global displayorder numcommits matchinglines findinprogress
global findmergefiles global findmergefiles


set l $ffileline set l $ffileline
while 1 { while {1} {
if {$findmergefiles || $nparents($id) == 1} { set id [lindex $displayorder $l]
if {$findmergefiles || [llength [lindex $parentlist $l]] == 1} {
if {![info exists treediffs($id)]} { if {![info exists treediffs($id)]} {
set findid $id set findid $id
set ffileline $l set ffileline $l
@ -2189,7 +2193,6 @@ proc findcont {id} {
set l 0 set l 0
} }
if {$l == $findstartline} break if {$l == $findstartline} break
set id [lindex $displayorder $l]
} }
stopfindproc stopfindproc
if {!$finddidsel} { if {!$finddidsel} {
@ -2289,7 +2292,7 @@ proc appendwithlinks {text} {
proc selectline {l isnew} { proc selectline {l isnew} {
global canv canv2 canv3 ctext commitinfo selectedline global canv canv2 canv3 ctext commitinfo selectedline
global displayorder linehtag linentag linedtag global displayorder linehtag linentag linedtag
global canvy0 linespc parents nparents children global canvy0 linespc parentlist childlist
global cflist currentid sha1entry global cflist currentid sha1entry
global commentend idtags linknum global commentend idtags linknum
global mergemax numcommits global mergemax numcommits
@ -2379,9 +2382,10 @@ proc selectline {l isnew} {
} }
set comment {} set comment {}
if {$nparents($id) > 1} { set olds [lindex $parentlist $l]
if {[llength $olds] > 1} {
set np 0 set np 0
foreach p $parents($id) { foreach p $olds {
if {$np >= $mergemax} { if {$np >= $mergemax} {
set tag mmax set tag mmax
} else { } else {
@ -2392,18 +2396,14 @@ proc selectline {l isnew} {
incr np incr np
} }
} else { } else {
if {[info exists parents($id)]} { foreach p $olds {
foreach p $parents($id) {
append comment "Parent: [commit_descriptor $p]\n" append comment "Parent: [commit_descriptor $p]\n"
} }
} }
}


if {[info exists children($id)]} { foreach c [lindex $childlist $l] {
foreach c $children($id) {
append comment "Child: [commit_descriptor $c]\n" append comment "Child: [commit_descriptor $c]\n"
} }
}
append comment "\n" append comment "\n"
append comment [lindex $info 5] append comment [lindex $info 5]


@ -2417,10 +2417,10 @@ proc selectline {l isnew} {


$cflist delete 0 end $cflist delete 0 end
$cflist insert end "Comments" $cflist insert end "Comments"
if {$nparents($id) <= 1} { if {[llength $olds] <= 1} {
startdiff $id startdiff $id
} else { } else {
mergediff $id mergediff $id $l
} }
} }


@ -2489,9 +2489,10 @@ proc goforw {} {
} }
} }


proc mergediff {id} { proc mergediff {id l} {
global parents diffmergeid diffopts mdifffd global diffmergeid diffopts mdifffd
global difffilestart diffids global difffilestart diffids
global parentlist


set diffmergeid $id set diffmergeid $id
set diffids $id set diffids $id
@ -2505,12 +2506,13 @@ proc mergediff {id} {
} }
fconfigure $mdf -blocking 0 fconfigure $mdf -blocking 0
set mdifffd($id) $mdf set mdifffd($id) $mdf
fileevent $mdf readable [list getmergediffline $mdf $id] set np [llength [lindex $parentlist $l]]
fileevent $mdf readable [list getmergediffline $mdf $id $np]
set nextupdate [expr {[clock clicks -milliseconds] + 100}] set nextupdate [expr {[clock clicks -milliseconds] + 100}]
} }


proc getmergediffline {mdf id} { proc getmergediffline {mdf id np} {
global diffmergeid ctext cflist nextupdate nparents mergemax global diffmergeid ctext cflist nextupdate mergemax
global difffilestart mdifffd global difffilestart mdifffd


set n [gets $mdf line] set n [gets $mdf line]
@ -2543,7 +2545,6 @@ proc getmergediffline {mdf id} {
# do nothing # do nothing
} else { } else {
# parse the prefix - one ' ', '-' or '+' for each parent # parse the prefix - one ' ', '-' or '+' for each parent
set np $nparents($id)
set spaces {} set spaces {}
set minuses {} set minuses {}
set pluses {} set pluses {}
@ -2611,7 +2612,7 @@ proc addtocflist {ids} {
} }


proc gettreediffs {ids} { proc gettreediffs {ids} {
global treediff parents treepending global treediff treepending
set treepending $ids set treepending $ids
set treediff {} set treediff {}
if {[catch \ if {[catch \
@ -2979,7 +2980,7 @@ proc arrowjump {id n y} {
} }


proc lineclick {x y id isnew} { proc lineclick {x y id isnew} {
global ctext commitinfo children cflist canv thickerline global ctext commitinfo childlist commitrow cflist canv thickerline


if {![info exists commitinfo($id)] && ![getcommit $id]} return if {![info exists commitinfo($id)] && ![getcommit $id]} return
unmarkmatches unmarkmatches
@ -3018,10 +3019,11 @@ proc lineclick {x y id isnew} {
$ctext insert end "\tAuthor:\t[lindex $info 1]\n" $ctext insert end "\tAuthor:\t[lindex $info 1]\n"
set date [formatdate [lindex $info 2]] set date [formatdate [lindex $info 2]]
$ctext insert end "\tDate:\t$date\n" $ctext insert end "\tDate:\t$date\n"
if {[info exists children($id)]} { set kids [lindex $childlist $commitrow($id)]
if {$kids ne {}} {
$ctext insert end "\nChildren:" $ctext insert end "\nChildren:"
set i 0 set i 0
foreach child $children($id) { foreach child $kids {
incr i incr i
if {![info exists commitinfo($child)] && ![getcommit $child]} continue if {![info exists commitinfo($child)] && ![getcommit $child]} continue
set info $commitinfo($child) set info $commitinfo($child)