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

Commit 6d4408a

Browse files
authored
Merge pull request #1125 from saracen/tree-walk-optimization
plumbing: TreeWalker performance improvement, bufio pool for objects
2 parents 78092a2 + 936f65d commit 6d4408a

File tree

4 files changed

+34
-9
lines changed

4 files changed

+34
-9
lines changed

plumbing/object/commit.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,9 @@ func (c *Commit) Decode(o plumbing.EncodedObject) (err error) {
171171
}
172172
defer ioutil.CheckClose(reader, &err)
173173

174-
r := bufio.NewReader(reader)
174+
r := bufPool.Get().(*bufio.Reader)
175+
defer bufPool.Put(r)
176+
r.Reset(reader)
175177

176178
var message bool
177179
var pgpsig bool

plumbing/object/common.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package object
2+
3+
import (
4+
"bufio"
5+
"sync"
6+
)
7+
8+
var bufPool = sync.Pool{
9+
New: func() interface{} {
10+
return bufio.NewReader(nil)
11+
},
12+
}

plumbing/object/tag.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,9 @@ func (t *Tag) Decode(o plumbing.EncodedObject) (err error) {
9393
}
9494
defer ioutil.CheckClose(reader, &err)
9595

96-
r := bufio.NewReader(reader)
96+
r := bufPool.Get().(*bufio.Reader)
97+
defer bufPool.Put(r)
98+
r.Reset(reader)
9799
for {
98100
var line []byte
99101
line, err = r.ReadBytes('\n')

plumbing/object/tree.go

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,9 @@ func (t *Tree) Decode(o plumbing.EncodedObject) (err error) {
230230
}
231231
defer ioutil.CheckClose(reader, &err)
232232

233-
r := bufio.NewReader(reader)
233+
r := bufPool.Get().(*bufio.Reader)
234+
defer bufPool.Put(r)
235+
r.Reset(reader)
234236
for {
235237
str, err := r.ReadString(' ')
236238
if err != nil {
@@ -383,7 +385,7 @@ func NewTreeWalker(t *Tree, recursive bool, seen map[plumbing.Hash]bool) *TreeWa
383385
// underlying repository will be skipped automatically. It is possible that this
384386
// may change in future versions.
385387
func (w *TreeWalker) Next() (name string, entry TreeEntry, err error) {
386-
var obj Object
388+
var obj *Tree
387389
for {
388390
current := len(w.stack) - 1
389391
if current < 0 {
@@ -403,7 +405,7 @@ func (w *TreeWalker) Next() (name string, entry TreeEntry, err error) {
403405
// Finished with the current tree, move back up to the parent
404406
w.stack = w.stack[:current]
405407
w.base, _ = path.Split(w.base)
406-
w.base = path.Clean(w.base) // Remove trailing slash
408+
w.base = strings.TrimSuffix(w.base, "/")
407409
continue
408410
}
409411

@@ -419,7 +421,7 @@ func (w *TreeWalker) Next() (name string, entry TreeEntry, err error) {
419421
obj, err = GetTree(w.s, entry.Hash)
420422
}
421423

422-
name = path.Join(w.base, entry.Name)
424+
name = simpleJoin(w.base, entry.Name)
423425

424426
if err != nil {
425427
err = io.EOF
@@ -433,9 +435,9 @@ func (w *TreeWalker) Next() (name string, entry TreeEntry, err error) {
433435
return
434436
}
435437

436-
if t, ok := obj.(*Tree); ok {
437-
w.stack = append(w.stack, &treeEntryIter{t, 0})
438-
w.base = path.Join(w.base, entry.Name)
438+
if obj != nil {
439+
w.stack = append(w.stack, &treeEntryIter{obj, 0})
440+
w.base = simpleJoin(w.base, entry.Name)
439441
}
440442

441443
return
@@ -509,3 +511,10 @@ func (iter *TreeIter) ForEach(cb func(*Tree) error) error {
509511
return cb(t)
510512
})
511513
}
514+
515+
func simpleJoin(parent, child string) string {
516+
if len(parent) > 0 {
517+
return parent + "/" + child
518+
}
519+
return child
520+
}

0 commit comments

Comments
 (0)