Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

plumbing: object, adds tree path cache to trees. Fixes #793 #855

Merged
merged 1 commit into from
Jun 7, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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