diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2008-10-13 12:12:33 +0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-10-14 22:25:54 +1100 |
commit | 4db09304f97b12d7db5d199eebb1f24c74e12d17 (patch) | |
tree | bc4a946acb3943e861bbc487721e93d30024bc63 | |
parent | 09c7029dfa58748268a6306bfe764456a65a22bf (diff) | |
download | git-4db09304f97b12d7db5d199eebb1f24c74e12d17.tar.gz git-4db09304f97b12d7db5d199eebb1f24c74e12d17.tar.xz |
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>
-rwxr-xr-x | gitk | 35 |
1 files changed, 34 insertions, 1 deletions
@@ -6531,6 +6531,7 @@ proc gettreediffline {gdtf ids} { global cmitmode vfilelimit curview limitdiffs set nr 0 + set sublist {} while {[incr nr] <= 1000 && [gets $gdtf line] >= 0} { set i [string first "\t" $line] if {$i >= 0} { @@ -6540,8 +6541,10 @@ proc gettreediffline {gdtf ids} { } set file [encoding convertfrom $file] lappend treediff $file + lappend sublist $file } } + cache_gitattr encoding $sublist if {![eof $gdtf]} { return [expr {$nr >= 1000? 2: 1}] } @@ -9816,18 +9819,48 @@ proc tcl_encoding {enc} { } proc gitattr {path attr default} { - if {[catch {set r [exec git check-attr $attr -- $path]}]} { + global path_attr_cache + if {[info exists path_attr_cache($attr,$path)]} { + set r $path_attr_cache($attr,$path) + } elseif {[catch {set r [exec git check-attr $attr -- $path]}]} { set r unspecified } else { set r [join [lrange [split $r :] 2 end] :] regsub {^ } $r {} r } + set path_attr_cache($attr,$path) $r if {$r eq {unspecified}} { return $default } return $r } +proc cache_gitattr {attr pathlist} { + global path_attr_cache + set newlist {} + foreach path $pathlist { + if {[info exists path_attr_cache($attr,$path)]} continue + lappend newlist $path + } + while {$newlist ne {}} { + set head [lrange $newlist 0 29] + set newlist [lrange $newlist 30 end] + if {![catch {set rlist [eval exec git check-attr $attr -- $head]}]} { + foreach row [split $rlist "\n"] { + set cols [split $row :] + set path [lindex $cols 0] + set value [join [lrange $cols 2 end] :] + if {[string index $path 0] eq "\""} { + set path [encoding convertfrom [lindex $path 0]] + } + regsub {^ } $value {} value + set path_attr_cache($attr,$path) $value + } + } + update + } +} + proc get_path_encoding {path} { global gui_encoding set tcl_enc [tcl_encoding $gui_encoding] |