Skip to content

Commit

Permalink
plumbing: object, adds tree path cache to trees. Fixes src-d#793
Browse files Browse the repository at this point in the history
The cache is used in Tree.FindEntry for faster path search.

Signed-off-by: Javi Fontan <jfontan@gmail.com>
  • Loading branch information
jfontan committed Jun 6, 2018
1 parent 73c775e commit f019589
Showing 1 changed file with 26 additions and 1 deletion.
27 changes: 26 additions & 1 deletion plumbing/object/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"io"
"path"
"path/filepath"
"strings"

"gopkg.in/src-d/go-git.v4/plumbing"
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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])
Expand Down

0 comments on commit f019589

Please sign in to comment.