gitk: Implement batch lookup and caching of encoding attrs
When the diff contains thousands of files, calling git-check-attr once per file is very slow. With this patch gitk does attribute lookup in batches of 30 files while reading the diff file list, which leads to a very noticeable speedup. It may be possible to reimplement this even more efficiently, if git-check-attr is modified to support a --stdin-paths option. Additionally, it should quote the ':' character in file paths, or provide a more robust way of column separation. Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com> Tested-by: Johannes Sixt <johannes.sixt@telecom.at> Signed-off-by: Paul Mackerras <paulus@samba.org>
Alexander Gavrilov committed
Oct 13, 2008 at 12:12 UTC
4db09304f97b12d7db5d199eebb1f24c74e12d17
1 file changed
+34
-1
gitk
+34
-1
@@ -6531,6 +6531,7 @@ proc gettreediffline {gdtf ids} {
6531
global cmitmode vfilelimit curview limitdiffs
6532
6533
set nr 0
6534
+ set sublist {}
6535
while {[incr nr] <= 1000 && [gets $gdtf line] >= 0} {
6536
set i [string first "\t" $line]
6537
if {$i >= 0} {
@@ -6540,8 +6541,10 @@ proc gettreediffline {gdtf ids} {
6541
}
6542
set file [encoding convertfrom $file]
6543
lappend treediff $file
6544
+ lappend sublist $file
6545
}
6546
}
6547
+ cache_gitattr encoding $sublist
6548
if {![eof $gdtf]} {
6549
return [expr {$nr >= 1000? 2: 1}]
6550
}
@@ -9816,18 +9819,48 @@ proc tcl_encoding {enc} {
9819
}
9820
9821
proc gitattr {path attr default} {
9819
- if {[catch {set r [exec git check-attr $attr -- $path]}]} {
9822
+ global path_attr_cache
9823
+ if {[info exists path_attr_cache($attr,$path)]} {
9824
+ set r $path_attr_cache($attr,$path)
9825
+ } elseif {[catch {set r [exec git check-attr $attr -- $path]}]} {
9826
set r unspecified
9827
} else {
9828
set r [join [lrange [split $r :] 2 end] :]
9829
regsub {^ } $r {} r
9830
}
9831
+ set path_attr_cache($attr,$path) $r
9832
if {$r eq {unspecified}} {
9833
return $default
9834
}
9835
return $r
9836
}
9837
9838
+proc cache_gitattr {attr pathlist} {
9839
+ global path_attr_cache
9840
+ set newlist {}
9841
+ foreach path $pathlist {
9842
+ if {[info exists path_attr_cache($attr,$path)]} continue
9843
+ lappend newlist $path
9844
+ }
9845
+ while {$newlist ne {}} {
9846
+ set head [lrange $newlist 0 29]
9847
+ set newlist [lrange $newlist 30 end]
9848
+ if {![catch {set rlist [eval exec git check-attr $attr -- $head]}]} {
9849
+ foreach row [split $rlist "\n"] {
9850
+ set cols [split $row :]
9851
+ set path [lindex $cols 0]
9852
+ set value [join [lrange $cols 2 end] :]
9853
+ if {[string index $path 0] eq "\""} {
9854
+ set path [encoding convertfrom [lindex $path 0]]
9855
+ }
9856
+ regsub {^ } $value {} value
9857
+ set path_attr_cache($attr,$path) $value
9858
+ }
9859
+ }
9860
+ update
9861
+ }
9862
+}
9863
+
9864
proc get_path_encoding {path} {
9865
global gui_encoding
9866
set tcl_enc [tcl_encoding $gui_encoding]