Thread (44 messages) flat view 44 messages, 6 authors, 2016-06-15

Re: [PATCH (GIT-GUI,GITK) 6/8] gitk: Port new encoding logic from git-gui.

From: Alexander Gavrilov <hidden>
Date: 2016-06-15 22:45:23
Subsystem: the rest · Maintainer: Linus Torvalds

On Friday 19 September 2008 17:04:54 Johannes Sixt wrote:
Alexander Gavrilov schrieb:
quoted
Also, it should work in the patch mode as well: it reads the patch as
binary, and decodes each line separately, based on the encoding
determined for the current file.
This is great. But we'll have to see how this works on a multi-file diff
on Windows. (I sense slowness.)
Yes, yesterday I noticed that when the patch is very big, like when the
index has got out of sync, and gitk claims local changes in all of the git-gui
repository (>1000 files), first view is slow even on Linux.

I made a patch to optimize attribute lookup. I'm afraid that further optimization
is impossible without interface changes in git-check-attr, or reimplementing
the attribute parser in Tcl.
--- >8 ---
From: Alexander Gavrilov <redacted>
Subject: [PATCH] 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.

Signed-off-by: Alexander Gavrilov <redacted>
---
 gitk |   34 +++++++++++++++++++++++++++++++++-
 1 files changed, 33 insertions(+), 1 deletions(-)
diff --git a/gitk b/gitk
index 1355aa2..6fc1e90 100755
--- a/gitk
+++ b/gitk
@@ -6530,6 +6530,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} {
@@ -6539,8 +6540,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}]
     }
@@ -9839,18 +9842,47 @@ 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]]
+				}
+				set path_attr_cache($attr,$path) $value
+			}
+		}
+		update
+	}
+}
+
 proc get_path_encoding {path} {
 	global gui_encoding
 	set tcl_enc [tcl_encoding $gui_encoding]
-- 
1.6.0.20.g6148bc
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help