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

Commit

Permalink
Merge pull request #578 from erizocosmico/perf/reduce-gc-press
Browse files Browse the repository at this point in the history
packfile: improve performance a little by reducing gc pressure
  • Loading branch information
mcuadros authored Sep 4, 2017
2 parents 770800d + 6a46a7e commit f9879dd
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 6 deletions.
8 changes: 8 additions & 0 deletions plumbing/format/packfile/common.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package packfile

import (
"bytes"
"io"
"sync"

"gopkg.in/src-d/go-git.v4/plumbing/storer"
"gopkg.in/src-d/go-git.v4/utils/ioutil"
Expand Down Expand Up @@ -49,3 +51,9 @@ func writePackfileToObjectStorage(sw storer.PackfileWriter, packfile io.Reader)
_, err = io.Copy(w, packfile)
return err
}

var bufPool = sync.Pool{
New: func() interface{} {
return bytes.NewBuffer(nil)
},
}
4 changes: 3 additions & 1 deletion plumbing/format/packfile/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,8 @@ func (d *Decoder) fillRegularObjectContent(obj plumbing.EncodedObject) (uint32,
}

func (d *Decoder) fillREFDeltaObjectContent(obj plumbing.EncodedObject, ref plumbing.Hash) (uint32, error) {
buf := bytes.NewBuffer(nil)
buf := bufPool.Get().(*bytes.Buffer)
buf.Reset()
_, crc, err := d.s.NextObject(buf)
if err != nil {
return 0, err
Expand All @@ -364,6 +365,7 @@ func (d *Decoder) fillREFDeltaObjectContent(obj plumbing.EncodedObject, ref plum
obj.SetType(base.Type())
err = ApplyDelta(obj, base, buf.Bytes())
d.cachePut(obj)
bufPool.Put(buf)

return crc, err
}
Expand Down
12 changes: 9 additions & 3 deletions plumbing/format/packfile/diff_delta.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,15 @@ func GetDelta(base, target plumbing.EncodedObject) (plumbing.EncodedObject, erro

// DiffDelta returns the delta that transforms src into tgt.
func DiffDelta(src []byte, tgt []byte) []byte {
buf := bytes.NewBuffer(nil)
buf := bufPool.Get().(*bytes.Buffer)
buf.Reset()
buf.Write(deltaEncodeSize(len(src)))
buf.Write(deltaEncodeSize(len(tgt)))

sindex := initMatch(src)

ibuf := bytes.NewBuffer(nil)
ibuf := bufPool.Get().(*bytes.Buffer)
ibuf.Reset()
for i := 0; i < len(tgt); i++ {
offset, l := findMatch(src, tgt, sindex, i)

Expand All @@ -93,8 +95,12 @@ func DiffDelta(src []byte, tgt []byte) []byte {
}

encodeInsertOperation(ibuf, buf)
bytes := buf.Bytes()

bufPool.Put(buf)
bufPool.Put(ibuf)

return buf.Bytes()
return bytes
}

func encodeInsertOperation(ibuf, buf *bytes.Buffer) {
Expand Down
15 changes: 13 additions & 2 deletions plumbing/format/packfile/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"hash/crc32"
"io"
stdioutil "io/ioutil"
"sync"

"gopkg.in/src-d/go-git.v4/plumbing"
"gopkg.in/src-d/go-git.v4/utils/binary"
Expand Down Expand Up @@ -291,10 +292,18 @@ func (s *Scanner) copyObject(w io.Writer) (n int64, err error) {
}

defer ioutil.CheckClose(s.zr, &err)
n, err = io.Copy(w, s.zr)
buf := byteSlicePool.Get().([]byte)
n, err = io.CopyBuffer(w, s.zr, buf)
byteSlicePool.Put(buf)
return
}

var byteSlicePool = sync.Pool{
New: func() interface{} {
return make([]byte, 32*1024)
},
}

// SeekFromStart sets a new offset from start, returns the old position before
// the change.
func (s *Scanner) SeekFromStart(offset int64) (previous int64, err error) {
Expand Down Expand Up @@ -324,7 +333,9 @@ func (s *Scanner) Checksum() (plumbing.Hash, error) {

// Close reads the reader until io.EOF
func (s *Scanner) Close() error {
_, err := io.Copy(stdioutil.Discard, s.r)
buf := byteSlicePool.Get().([]byte)
_, err := io.CopyBuffer(stdioutil.Discard, s.r, buf)
byteSlicePool.Put(buf)
return err
}

Expand Down

0 comments on commit f9879dd

Please sign in to comment.