aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing/format/packfile
diff options
context:
space:
mode:
authorMiguel Molina <miguel@erizocosmi.co>2018-08-09 10:55:51 +0200
committerMiguel Molina <miguel@erizocosmi.co>2018-08-09 10:55:51 +0200
commit71a3c9161d4d8d2baf16440a86a02e8f5678aef2 (patch)
treeec292c9d738ed7bf2f52a7410872eb9a9ba5df81 /plumbing/format/packfile
parentb3d995f5ca6b544ed8a48fced85ffa94600af302 (diff)
downloadgo-git-71a3c9161d4d8d2baf16440a86a02e8f5678aef2.tar.gz
plumbing: packfile, read object content only once
Signed-off-by: Miguel Molina <miguel@erizocosmi.co>
Diffstat (limited to 'plumbing/format/packfile')
-rw-r--r--plumbing/format/packfile/parser.go22
-rw-r--r--plumbing/format/packfile/parser_test.go25
2 files changed, 40 insertions, 7 deletions
diff --git a/plumbing/format/packfile/parser.go b/plumbing/format/packfile/parser.go
index beb3e27..581c334 100644
--- a/plumbing/format/packfile/parser.go
+++ b/plumbing/format/packfile/parser.go
@@ -280,14 +280,8 @@ func (p *Parser) resolveDeltas() error {
}
if !obj.IsDelta() && len(obj.Children) > 0 {
- var err error
- base, err := p.get(obj)
- if err != nil {
- return err
- }
-
for _, child := range obj.Children {
- if _, err := p.resolveObject(child, base); err != nil {
+ if _, err := p.resolveObject(child, content); err != nil {
return err
}
}
@@ -297,12 +291,18 @@ func (p *Parser) resolveDeltas() error {
delete(p.deltas, obj.Offset)
}
}
+
+ obj.Content = nil
}
return nil
}
func (p *Parser) get(o *objectInfo) ([]byte, error) {
+ if len(o.Content) > 0 {
+ return o.Content, nil
+ }
+
e, ok := p.cache.Get(o.SHA1)
// If it's not on the cache and is not a delta we can try to find it in the
// storage, if there's one.
@@ -460,6 +460,8 @@ type objectInfo struct {
Parent *objectInfo
Children []*objectInfo
SHA1 plumbing.Hash
+
+ Content []byte
}
func newBaseObject(offset, length int64, t plumbing.ObjectType) *objectInfo {
@@ -488,6 +490,12 @@ func newDeltaObject(
return obj
}
+func (o *objectInfo) Write(b []byte) (int, error) {
+ o.Content = make([]byte, len(b))
+ copy(o.Content, b)
+ return o.Hasher.Write(b)
+}
+
func (o *objectInfo) IsDelta() bool {
return o.Type.IsDelta()
}
diff --git a/plumbing/format/packfile/parser_test.go b/plumbing/format/packfile/parser_test.go
index b5d482e..012a140 100644
--- a/plumbing/format/packfile/parser_test.go
+++ b/plumbing/format/packfile/parser_test.go
@@ -168,3 +168,28 @@ func BenchmarkParse(b *testing.B) {
})
}
}
+
+func BenchmarkParseBasic(b *testing.B) {
+ if err := fixtures.Init(); err != nil {
+ b.Fatal(err)
+ }
+
+ defer func() {
+ if err := fixtures.Clean(); err != nil {
+ b.Fatal(err)
+ }
+ }()
+
+ f := fixtures.Basic().One()
+ for i := 0; i < b.N; i++ {
+ parser, err := packfile.NewParser(packfile.NewScanner(f.Packfile()))
+ if err != nil {
+ b.Fatal(err)
+ }
+
+ _, err = parser.Parse()
+ if err != nil {
+ b.Fatal(err)
+ }
+ }
+}