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>
This commit is contained in:

committed by
Paul Mackerras

parent
09c7029dfa
commit
4db09304f9
35
gitk
35
gitk
@ -6531,6 +6531,7 @@ proc gettreediffline {gdtf ids} {
|
|||||||
global cmitmode vfilelimit curview limitdiffs
|
global cmitmode vfilelimit curview limitdiffs
|
||||||
|
|
||||||
set nr 0
|
set nr 0
|
||||||
|
set sublist {}
|
||||||
while {[incr nr] <= 1000 && [gets $gdtf line] >= 0} {
|
while {[incr nr] <= 1000 && [gets $gdtf line] >= 0} {
|
||||||
set i [string first "\t" $line]
|
set i [string first "\t" $line]
|
||||||
if {$i >= 0} {
|
if {$i >= 0} {
|
||||||
@ -6540,8 +6541,10 @@ proc gettreediffline {gdtf ids} {
|
|||||||
}
|
}
|
||||||
set file [encoding convertfrom $file]
|
set file [encoding convertfrom $file]
|
||||||
lappend treediff $file
|
lappend treediff $file
|
||||||
|
lappend sublist $file
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cache_gitattr encoding $sublist
|
||||||
if {![eof $gdtf]} {
|
if {![eof $gdtf]} {
|
||||||
return [expr {$nr >= 1000? 2: 1}]
|
return [expr {$nr >= 1000? 2: 1}]
|
||||||
}
|
}
|
||||||
@ -9816,18 +9819,48 @@ proc tcl_encoding {enc} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proc gitattr {path attr default} {
|
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
|
set r unspecified
|
||||||
} else {
|
} else {
|
||||||
set r [join [lrange [split $r :] 2 end] :]
|
set r [join [lrange [split $r :] 2 end] :]
|
||||||
regsub {^ } $r {} r
|
regsub {^ } $r {} r
|
||||||
}
|
}
|
||||||
|
set path_attr_cache($attr,$path) $r
|
||||||
if {$r eq {unspecified}} {
|
if {$r eq {unspecified}} {
|
||||||
return $default
|
return $default
|
||||||
}
|
}
|
||||||
return $r
|
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} {
|
proc get_path_encoding {path} {
|
||||||
global gui_encoding
|
global gui_encoding
|
||||||
set tcl_enc [tcl_encoding $gui_encoding]
|
set tcl_enc [tcl_encoding $gui_encoding]
|
||||||
|
Reference in New Issue
Block a user