diff options
author | Máximo Cuadros <mcuadros@gmail.com> | 2018-06-07 12:12:57 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-07 12:12:57 +0200 |
commit | a8a12e0edc6af6ea44fe8cce76d7b4658d85a50c (patch) | |
tree | 16d5481342c153023035b3619f9d8814dc156043 | |
parent | 73c775ee2bfcbc6c5870f5551feedebabb63bffa (diff) | |
parent | f01958913fab6e1967c1317b7222d1160212371c (diff) | |
download | go-git-a8a12e0edc6af6ea44fe8cce76d7b4658d85a50c.tar.gz |
Merge pull request #855 from jfontan/improvement/cache-tree-findentry
plumbing: object, adds tree path cache to trees. Fixes #793
-rw-r--r-- | plumbing/object/tree.go | 27 |
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]) |