Skip to content

Commit

Permalink
Cache RawData for Commit, Tag, & Tree, fixes #6
Browse files Browse the repository at this point in the history
  • Loading branch information
sameer committed Dec 18, 2018
1 parent 479420c commit 17f1dfc
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 57 deletions.
70 changes: 39 additions & 31 deletions commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ import (
"errors"
"fmt"
"strconv"
"sync"

cid "github.com/ipfs/go-cid"
node "github.com/ipfs/go-ipld-format"
)

type Commit struct {
DataSize string `json:"-"`
GitTree cid.Cid `json:"tree"`
Parents []cid.Cid `json:"parents"`
GitTree cid.Cid `json:"tree"`
Parents []cid.Cid `json:"parents"`
Message string `json:"message"`
Author *PersonInfo `json:"author"`
Committer *PersonInfo `json:"committer"`
Expand All @@ -27,6 +28,9 @@ type Commit struct {
Other []string `json:"other,omitempty"`

cid cid.Cid

rawData []byte
rawDataOnce sync.Once
}

type PersonInfo struct {
Expand Down Expand Up @@ -80,7 +84,7 @@ func (pi *PersonInfo) resolve(p []string) (interface{}, []string, error) {
}

type MergeTag struct {
Object cid.Cid `json:"object"`
Object cid.Cid `json:"object"`
Type string `json:"type"`
Tag string `json:"tag"`
Tagger *PersonInfo `json:"tagger"`
Expand Down Expand Up @@ -118,34 +122,38 @@ func (c *Commit) Loggable() map[string]interface{} {
}

func (c *Commit) RawData() []byte {
buf := new(bytes.Buffer)
fmt.Fprintf(buf, "commit %s\x00", c.DataSize)
fmt.Fprintf(buf, "tree %s\n", hex.EncodeToString(cidToSha(c.GitTree)))
for _, p := range c.Parents {
fmt.Fprintf(buf, "parent %s\n", hex.EncodeToString(cidToSha(p)))
}
fmt.Fprintf(buf, "author %s\n", c.Author.String())
fmt.Fprintf(buf, "committer %s\n", c.Committer.String())
if len(c.Encoding) > 0 {
fmt.Fprintf(buf, "encoding %s\n", c.Encoding)
}
for _, mtag := range c.MergeTag {
fmt.Fprintf(buf, "mergetag object %s\n", hex.EncodeToString(cidToSha(mtag.Object)))
fmt.Fprintf(buf, " type %s\n", mtag.Type)
fmt.Fprintf(buf, " tag %s\n", mtag.Tag)
fmt.Fprintf(buf, " tagger %s\n \n", mtag.Tagger.String())
fmt.Fprintf(buf, "%s", mtag.Text)
}
if c.Sig != nil {
fmt.Fprintln(buf, "gpgsig -----BEGIN PGP SIGNATURE-----")
fmt.Fprint(buf, c.Sig.Text)
fmt.Fprintln(buf, " -----END PGP SIGNATURE-----")
}
for _, line := range c.Other {
fmt.Fprintln(buf, line)
}
fmt.Fprintf(buf, "\n%s", c.Message)
return buf.Bytes()
c.rawDataOnce.Do(func() {
buf := new(bytes.Buffer)
fmt.Fprintf(buf, "commit %s\x00", c.DataSize)
fmt.Fprintf(buf, "tree %s\n", hex.EncodeToString(cidToSha(c.GitTree)))
for _, p := range c.Parents {
fmt.Fprintf(buf, "parent %s\n", hex.EncodeToString(cidToSha(p)))
}
fmt.Fprintf(buf, "author %s\n", c.Author.String())
fmt.Fprintf(buf, "committer %s\n", c.Committer.String())
if len(c.Encoding) > 0 {
fmt.Fprintf(buf, "encoding %s\n", c.Encoding)
}
for _, mtag := range c.MergeTag {
fmt.Fprintf(buf, "mergetag object %s\n", hex.EncodeToString(cidToSha(mtag.Object)))
fmt.Fprintf(buf, " type %s\n", mtag.Type)
fmt.Fprintf(buf, " tag %s\n", mtag.Tag)
fmt.Fprintf(buf, " tagger %s\n \n", mtag.Tagger.String())
fmt.Fprintf(buf, "%s", mtag.Text)
}
if c.Sig != nil {
fmt.Fprintln(buf, "gpgsig -----BEGIN PGP SIGNATURE-----")
fmt.Fprint(buf, c.Sig.Text)
fmt.Fprintln(buf, " -----END PGP SIGNATURE-----")
}
for _, line := range c.Other {
fmt.Fprintln(buf, line)
}
fmt.Fprintf(buf, "\n%s", c.Message)
c.rawData = buf.Bytes()
})

return c.rawData
}

func (c *Commit) Resolve(path []string) (interface{}, []string, error) {
Expand Down
4 changes: 4 additions & 0 deletions git_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io"
"os"
"path/filepath"
"reflect"
"strings"
"testing"

Expand Down Expand Up @@ -171,6 +172,7 @@ func testNode(t *testing.T, nd node.Node) error {

/*s, _ := commit.Size()
assert.Equal(t, len(commit.RawData()), int(s))*/ //TODO: Known breakage
assert(t, reflect.DeepEqual(commit.RawData(), commit.RawData()))
assert(t, commit.GitTree.Defined())
assert(t, commit.Links() != nil)
assert(t, commit.Loggable()["type"] == "git_commit")
Expand Down Expand Up @@ -228,6 +230,7 @@ func testNode(t *testing.T, nd node.Node) error {
}

assert(t, tag.Type == "commit" || tag.Type == "tree" || tag.Type == "blob" || tag.Type == "tag")
assert(t, reflect.DeepEqual(tag.RawData(), tag.RawData()))
assert(t, tag.Object.Defined())
assert(t, tag.Loggable()["type"] == "git_tag")
assert(t, tag.Tree("", -1) != nil)
Expand All @@ -243,6 +246,7 @@ func testNode(t *testing.T, nd node.Node) error {
t.Fatalf("Tree is not a tree")
}

assert(t, reflect.DeepEqual(tree.RawData(), tree.RawData()))
assert(t, tree.entries != nil)
assert(t, tree.Tree("", 0) == nil)
}
Expand Down
36 changes: 22 additions & 14 deletions tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,26 @@ package ipldgit
import (
"bytes"
"encoding/hex"
"errors"
"fmt"
"sync"

"errors"
cid "github.com/ipfs/go-cid"
node "github.com/ipfs/go-ipld-format"
)

type Tag struct {
Object cid.Cid `json:"object"`
Object cid.Cid `json:"object"`
Type string `json:"type"`
Tag string `json:"tag"`
Tagger *PersonInfo `json:"tagger"`
Message string `json:"message"`
dataSize string

cid cid.Cid

rawData []byte
rawDataOnce sync.Once
}

func (t *Tag) Cid() cid.Cid {
Expand All @@ -41,18 +45,22 @@ func (t *Tag) Loggable() map[string]interface{} {
}

func (t *Tag) RawData() []byte {
buf := new(bytes.Buffer)
fmt.Fprintf(buf, "tag %s\x00", t.dataSize)
fmt.Fprintf(buf, "object %s\n", hex.EncodeToString(cidToSha(t.Object)))
fmt.Fprintf(buf, "type %s\n", t.Type)
fmt.Fprintf(buf, "tag %s\n", t.Tag)
if t.Tagger != nil {
fmt.Fprintf(buf, "tagger %s\n", t.Tagger.String())
}
if t.Message != "" {
fmt.Fprintf(buf, "\n%s", t.Message)
}
return buf.Bytes()
t.rawDataOnce.Do(func() {
buf := new(bytes.Buffer)
fmt.Fprintf(buf, "tag %s\x00", t.dataSize)
fmt.Fprintf(buf, "object %s\n", hex.EncodeToString(cidToSha(t.Object)))
fmt.Fprintf(buf, "type %s\n", t.Type)
fmt.Fprintf(buf, "tag %s\n", t.Tag)
if t.Tagger != nil {
fmt.Fprintf(buf, "tagger %s\n", t.Tagger.String())
}
if t.Message != "" {
fmt.Fprintf(buf, "\n%s", t.Message)
}
t.rawData = buf.Bytes()
})

return t.rawData
}

func (t *Tag) Resolve(path []string) (interface{}, []string, error) {
Expand Down
31 changes: 19 additions & 12 deletions tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,27 @@ package ipldgit
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"sync"

"errors"
cid "github.com/ipfs/go-cid"
node "github.com/ipfs/go-ipld-format"
)

type Tree struct {
entries map[string]*TreeEntry
size int
order []string
cid cid.Cid
entries map[string]*TreeEntry
size int
order []string
cid cid.Cid
rawData []byte
rawDataOnce sync.Once
}

type TreeEntry struct {
name string
Mode string `json:"mode"`
Mode string `json:"mode"`
Hash cid.Cid `json:"hash"`
}

Expand Down Expand Up @@ -95,13 +98,17 @@ func (t *Tree) Loggable() map[string]interface{} {
}

func (t *Tree) RawData() []byte {
buf := new(bytes.Buffer)
t.rawDataOnce.Do(func() {
buf := new(bytes.Buffer)

fmt.Fprintf(buf, "tree %d\x00", t.size)
for _, s := range t.order {
t.entries[s].WriteTo(buf)
}
return buf.Bytes()
fmt.Fprintf(buf, "tree %d\x00", t.size)
for _, s := range t.order {
t.entries[s].WriteTo(buf)
}
t.rawData = buf.Bytes()
})

return t.rawData
}

func (t *Tree) Resolve(p []string) (interface{}, []string, error) {
Expand Down

0 comments on commit 17f1dfc

Please sign in to comment.