aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavi Fontan <jfontan@gmail.com>2018-06-06 15:18:57 +0200
committerJavi Fontan <jfontan@gmail.com>2018-06-06 15:25:57 +0200
commitf01958913fab6e1967c1317b7222d1160212371c (patch)
tree16d5481342c153023035b3619f9d8814dc156043
parent73c775ee2bfcbc6c5870f5551feedebabb63bffa (diff)
downloadgo-git-f01958913fab6e1967c1317b7222d1160212371c.tar.gz
plumbing: object, adds tree path cache to trees. Fixes #793
The cache is used in Tree.FindEntry for faster path search. Signed-off-by: Javi Fontan <jfontan@gmail.com>
-rw-r--r--plumbing/object/tree.go27
1 files changed, 26 insertions, 1 deletions
diff --git a/plumbing/object/tree.go b/plumbing/object/tree.go
index c2399f8..30bbcb0 100644
--- a/plumbing/object/tree.go
+++ b/plumbing/object/tree.go
@@ -6,6 +6,7 @@ import (
"fmt"
"io"
"path"
+ "path/filepath"
"strings"
"gopkg.in/src-d/go-git.v4/plumbing"
@@ -34,6 +35,7 @@ type Tree struct {
s storer.EncodedObjectStorer
m map[string]*TreeEntry
+ t map[string]*Tree // tree path cache
}
// GetTree gets a tree from an object storer and decodes it.
@@ -111,14 +113,37 @@ func (t *Tree) TreeEntryFile(e *TreeEntry) (*File, error) {
// FindEntry search a TreeEntry in this tree or any subtree.
func (t *Tree) FindEntry(path string) (*TreeEntry, error) {
+ if t.t == nil {
+ t.t = make(map[string]*Tree)
+ }
+
pathParts := strings.Split(path, "/")
+ startingTree := t
+ pathCurrent := ""
+
+ // search for the longest path in the tree path cache
+ for i := len(pathParts); i > 1; i-- {
+ path := filepath.Join(pathParts[:i]...)
+
+ tree, ok := t.t[path]
+ if ok {
+ startingTree = tree
+ pathParts = pathParts[i:]
+ pathCurrent = path
+
+ break
+ }
+ }
var tree *Tree
var err error
- for tree = t; len(pathParts) > 1; pathParts = pathParts[1:] {
+ for tree = startingTree; len(pathParts) > 1; pathParts = pathParts[1:] {
if tree, err = tree.dir(pathParts[0]); err != nil {
return nil, err
}
+
+ pathCurrent = filepath.Join(pathCurrent, pathParts[0])
+ t.t[pathCurrent] = tree
}
return tree.entry(pathParts[0])