gitk: Speed up resolution of short SHA1 ids
On large repositories such as the Linux kernel, it can take quite a noticeable time (several seconds) for gitk to resolve short SHA1 IDs to their long form. This speeds up the process by maintaining lists of IDs indexed by the first 4 characters of the SHA1 ID, speeding up the search by a factor of 65536 on large repositories. Signed-off-by: Paul Mackerras <paulus@samba.org>
Paul Mackerras committed
Mar 19, 2012 at 11:21 UTC
22387f2395217beaa7228cb02966cf7b61b0c346
1 file changed
+27
-5
gitk
+27
-5
@@ -641,12 +641,16 @@ proc varcinit {view} {
641
642
proc resetvarcs {view} {
643
global varcid varccommits parents children vseedcount ordertok
644
+ global vshortids
645
646
foreach vid [array names varcid $view,*] {
647
unset varcid($vid)
648
unset children($vid)
649
unset parents($vid)
650
}
651
+ foreach vid [array names vshortids $view,*] {
652
+ unset vshortids($vid)
653
+ }
654
# some commits might have children but haven't been seen yet
655
foreach vid [array names children $view,*] {
656
unset children($vid)
@@ -933,7 +937,7 @@ proc fix_reversal {p a v} {
937
proc insertrow {id p v} {
938
global cmitlisted children parents varcid varctok vtokmod
939
global varccommits ordertok commitidx numcommits curview
936
- global targetid targetrow
940
+ global targetid targetrow vshortids
941
942
readcommit $id
943
set vid $v,$id
@@ -942,6 +946,7 @@ proc insertrow {id p v} {
946
set parents($vid) [list $p]
947
set a [newvarc $v $id]
948
set varcid($vid) $a
949
+ lappend vshortids($v,[string range $id 0 3]) $id
950
if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] < 0} {
951
modify_arc $v $a
952
}
@@ -1397,7 +1402,7 @@ proc getcommitlines {fd inst view updating} {
1402
global commitidx commitdata vdatemode
1403
global parents children curview hlview
1404
global idpending ordertok
1400
- global varccommits varcid varctok vtokmod vfilelimit
1405
+ global varccommits varcid varctok vtokmod vfilelimit vshortids
1406
1407
set stuff [read $fd 500000]
1408
# git log doesn't terminate the last commit with a null...
@@ -1497,6 +1502,8 @@ proc getcommitlines {fd inst view updating} {
1502
set id [lindex $ids 0]
1503
set vid $view,$id
1504
1505
+ lappend vshortids($view,[string range $id 0 3]) $id
1506
+
1507
if {!$listed && $updating && ![info exists varcid($vid)] &&
1508
$vfilelimit($view) ne {}} {
1509
# git log doesn't rewrite parents for unlisted commits
@@ -1719,11 +1726,26 @@ proc getcommit {id} {
1726
# and are present in the current view.
1727
# This is fairly slow...
1728
proc longid {prefix} {
1722
- global varcid curview
1729
+ global varcid curview vshortids
1730
1731
set ids {}
1725
- foreach match [array names varcid "$curview,$prefix*"] {
1726
- lappend ids [lindex [split $match ","] 1]
1732
+ if {[string length $prefix] >= 4} {
1733
+ set vshortid $curview,[string range $prefix 0 3]
1734
+ if {[info exists vshortids($vshortid)]} {
1735
+ foreach id $vshortids($vshortid) {
1736
+ if {[string match "$prefix*" $id]} {
1737
+ if {[lsearch -exact $ids $id] < 0} {
1738
+ lappend ids $id
1739
+ if {[llength $ids] >= 2} break
1740
+ }
1741
+ }
1742
+ }
1743
+ }
1744
+ } else {
1745
+ foreach match [array names varcid "$curview,$prefix*"] {
1746
+ lappend ids [lindex [split $match ","] 1]
1747
+ if {[llength $ids] >= 2} break
1748
+ }
1749
}
1750
return $ids
1751
}