diff options
author | Javi Fontan <jfontan@gmail.com> | 2018-06-06 15:18:57 +0200 |
---|---|---|
committer | Javi Fontan <jfontan@gmail.com> | 2018-06-06 15:25:57 +0200 |
commit | f01958913fab6e1967c1317b7222d1160212371c (patch) | |
tree | 16d5481342c153023035b3619f9d8814dc156043 | |
parent | 73c775ee2bfcbc6c5870f5551feedebabb63bffa (diff) | |
download | go-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.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]) |