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

Commit 57f7a36

Browse files
committed
TreeWalker optimization
1 parent 89f8bda commit 57f7a36

File tree

4 files changed

+35
-16
lines changed

4 files changed

+35
-16
lines changed

file.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,23 +53,31 @@ func (f *File) Lines() ([]string, error) {
5353
}
5454

5555
type FileIter struct {
56+
r *Repository
5657
w TreeWalker
5758
}
5859

5960
func NewFileIter(r *Repository, t *Tree) *FileIter {
60-
return &FileIter{w: *NewTreeWalker(r, t)}
61+
return &FileIter{r: r, w: *NewTreeWalker(r, t)}
6162
}
6263

6364
func (iter *FileIter) Next() (*File, error) {
6465
for {
65-
name, entry, obj, err := iter.w.Next()
66+
name, entry, err := iter.w.Next()
6667
if err != nil {
6768
return nil, err
6869
}
6970

70-
if blob, ok := obj.(*Blob); ok {
71-
return newFile(name, entry.Mode, blob), nil
71+
if entry.Mode.IsDir() {
72+
continue
7273
}
74+
75+
blob, err := iter.r.Blob(entry.Hash)
76+
if err != nil {
77+
return nil, err
78+
}
79+
80+
return newFile(name, entry.Mode, blob), nil
7381
}
7482
}
7583

tree.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,27 +269,31 @@ func (iter *treeEntryIter) Next() (TreeEntry, error) {
269269
// TreeEntryIter facilitates iterating through the descendent subtrees of a
270270
// Tree.
271271
type TreeIter struct {
272+
r *Repository
272273
w TreeWalker
273274
}
274275

275276
// NewTreeIter returns a new TreeIter instance
276277
func NewTreeIter(r *Repository, t *Tree) *TreeIter {
277278
return &TreeIter{
279+
r: r,
278280
w: *NewTreeWalker(r, t),
279281
}
280282
}
281283

282284
// Next returns the next Tree from the tree.
283285
func (iter *TreeIter) Next() (*Tree, error) {
284286
for {
285-
_, _, obj, err := iter.w.Next()
287+
_, entry, err := iter.w.Next()
286288
if err != nil {
287289
return nil, err
288290
}
289291

290-
if tree, ok := obj.(*Tree); ok {
291-
return tree, nil
292+
if !entry.Mode.IsDir() {
293+
continue
292294
}
295+
296+
return iter.r.Tree(entry.Hash)
293297
}
294298
}
295299

tree_walker.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,16 @@ func NewTreeWalker(r *Repository, t *Tree) *TreeWalker {
4343
// In the current implementation any objects which cannot be found in the
4444
// underlying repository will be skipped automatically. It is possible that this
4545
// may change in future versions.
46-
func (w *TreeWalker) Next() (name string, entry TreeEntry, obj Object, err error) {
46+
func (w *TreeWalker) Next() (name string, entry TreeEntry, err error) {
47+
var obj Object
4748
for {
4849
current := len(w.stack) - 1
4950
if current < 0 {
5051
// Nothing left on the stack so we're finished
5152
err = io.EOF
5253
return
5354
}
55+
5456
if current > maxTreeDepth {
5557
// We're probably following bad data or some self-referencing tree
5658
err = ErrMaxTreeDepth
@@ -65,6 +67,7 @@ func (w *TreeWalker) Next() (name string, entry TreeEntry, obj Object, err error
6567
w.base = path.Clean(w.base) // Remove trailing slash
6668
continue
6769
}
70+
6871
if err != nil {
6972
return
7073
}
@@ -73,10 +76,9 @@ func (w *TreeWalker) Next() (name string, entry TreeEntry, obj Object, err error
7376
err = nil
7477
continue
7578
}
79+
7680
if entry.Mode.IsDir() {
7781
obj, err = w.r.Tree(entry.Hash)
78-
} else {
79-
obj, err = w.r.Blob(entry.Hash)
8082
}
8183

8284
name = path.Join(w.base, entry.Name)

tree_walker_test.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,20 @@ func (s *SuiteTreeWalker) TestNext(c *C) {
104104
for k := 0; k < len(t.objs); k++ {
105105
info := t.objs[k]
106106
c.Assert(err, IsNil)
107-
name, entry, obj, err := walker.Next()
107+
name, entry, err := walker.Next()
108108

109109
c.Assert(err, IsNil, Commentf("subtest %d, iter %d, err=%v", i, k, err))
110-
c.Assert(name, Equals, info.Name, Commentf("subtest %d, iter %d, name=%v, expected=%s, stack=%v, base=%v", i, k, name, info.Name, walker.stack, walker.base))
111-
c.Assert(obj.Type(), Equals, info.Kind, Commentf("subtest %d, iter %d, obj.Type()=%v expected=%v", i, k, obj.Type(), info.Kind))
112-
c.Assert(entry.Hash.String(), Equals, info.Hash, Commentf("subtest %d, iter %d, entry.Hash=%v, expected=%s", i, k, entry.Hash, info.Hash))
113-
c.Assert(obj.ID().String(), Equals, info.Hash, Commentf("subtest %d, iter %d, obj.ID()=%v, expected=%s", i, k, obj.ID(), info.Hash))
110+
c.Assert(name, Equals, info.Name,
111+
Commentf("subtest %d, iter %d, name=%v, expected=%s, stack=%v, base=%v", i, k, name, info.Name, walker.stack, walker.base))
112+
113+
c.Assert(entry.Hash.String(), Equals, info.Hash,
114+
Commentf("subtest %d, iter %d, entry.Hash=%v, expected=%s", i, k, entry.Hash, info.Hash))
115+
116+
c.Assert(entry.Hash.String(), Equals, info.Hash,
117+
Commentf("subtest %d, iter %d, obj.ID()=%v, expected=%s", i, k, entry.Hash.String(), info.Hash))
114118
}
115-
_, _, _, err = walker.Next()
119+
120+
_, _, err = walker.Next()
116121
c.Assert(err, Equals, io.EOF)
117122
}
118123
}

0 commit comments

Comments
 (0)