Skip to content

Commit 4db0930

Browse files
angavrilovpaulusmack
authored andcommitted
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 <[email protected]> Tested-by: Johannes Sixt <[email protected]> Signed-off-by: Paul Mackerras <[email protected]>
1 parent 09c7029 commit 4db0930

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

gitk

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6531,6 +6531,7 @@ proc gettreediffline {gdtf ids} {
65316531
global cmitmode vfilelimit curview limitdiffs
65326532

65336533
set nr 0
6534+
set sublist {}
65346535
while {[incr nr] <= 1000 && [gets $gdtf line] >= 0} {
65356536
set i [string first "\t" $line]
65366537
if {$i >= 0} {
@@ -6540,8 +6541,10 @@ proc gettreediffline {gdtf ids} {
65406541
}
65416542
set file [encoding convertfrom $file]
65426543
lappend treediff $file
6544+
lappend sublist $file
65436545
}
65446546
}
6547+
cache_gitattr encoding $sublist
65456548
if {![eof $gdtf]} {
65466549
return [expr {$nr >= 1000? 2: 1}]
65476550
}
@@ -9816,18 +9819,48 @@ proc tcl_encoding {enc} {
98169819
}
98179820

98189821
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]}]} {
98209826
set r unspecified
98219827
} else {
98229828
set r [join [lrange [split $r :] 2 end] :]
98239829
regsub {^ } $r {} r
98249830
}
9831+
set path_attr_cache($attr,$path) $r
98259832
if {$r eq {unspecified}} {
98269833
return $default
98279834
}
98289835
return $r
98299836
}
98309837

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+
98319864
proc get_path_encoding {path} {
98329865
global gui_encoding
98339866
set tcl_enc [tcl_encoding $gui_encoding]

0 commit comments

Comments
 (0)