@matheusbsbs / matheus-bagliano / commits / 4db09304f9
Fork 0

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]