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

Commit 104be68

Browse files
committed
Merge pull request #28 from mcuadros/memory-object
storages: memory object
2 parents 1ac0055 + a964e32 commit 104be68

File tree

14 files changed

+289
-97
lines changed

14 files changed

+289
-97
lines changed

commit.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ func (c *Commit) File(path string) (file *File, err error) {
5151

5252
// Decode transform an core.Object into a Blob struct
5353
func (c *Commit) Decode(o core.Object) error {
54+
if o.Type() != core.CommitObject {
55+
return ErrUnsupportedObject
56+
}
57+
5458
c.Hash = o.Hash()
5559
r := bufio.NewReader(o.Reader())
5660

core/hash.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import (
99
// Hash SHA1 hased content
1010
type Hash [20]byte
1111

12+
// ZeroHash is Hash with value zero
13+
var ZeroHash Hash
14+
1215
// ComputeHash compute the hash for a given ObjectType and content
1316
func ComputeHash(t ObjectType, content []byte) Hash {
1417
h := t.Bytes()

core/object.go

Lines changed: 1 addition & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
package core
33

44
import (
5-
"bytes"
65
"errors"
76
"io"
87
)
@@ -13,11 +12,11 @@ var (
1312

1413
// Object is a generic representation of any git object
1514
type Object interface {
15+
Hash() Hash
1616
Type() ObjectType
1717
SetType(ObjectType)
1818
Size() int64
1919
SetSize(int64)
20-
Hash() Hash
2120
Reader() io.Reader
2221
Writer() io.Writer
2322
}
@@ -147,87 +146,3 @@ func (iter *ObjectSliceIter) Next() (Object, error) {
147146
func (iter *ObjectSliceIter) Close() {
148147
iter.pos = len(iter.series)
149148
}
150-
151-
type RAWObject struct {
152-
b []byte
153-
t ObjectType
154-
s int64
155-
}
156-
157-
func (o *RAWObject) Type() ObjectType { return o.t }
158-
func (o *RAWObject) SetType(t ObjectType) { o.t = t }
159-
func (o *RAWObject) Size() int64 { return o.s }
160-
func (o *RAWObject) SetSize(s int64) { o.s = s }
161-
func (o *RAWObject) Reader() io.Reader { return bytes.NewBuffer(o.b) }
162-
func (o *RAWObject) Hash() Hash { return ComputeHash(o.t, o.b) }
163-
func (o *RAWObject) Writer() io.Writer { return o }
164-
func (o *RAWObject) Write(p []byte) (n int, err error) {
165-
o.b = append(o.b, p...)
166-
return len(p), nil
167-
}
168-
169-
type RAWObjectStorage struct {
170-
Objects map[Hash]Object
171-
Commits map[Hash]Object
172-
Trees map[Hash]Object
173-
Blobs map[Hash]Object
174-
}
175-
176-
func NewRAWObjectStorage() *RAWObjectStorage {
177-
return &RAWObjectStorage{
178-
Objects: make(map[Hash]Object, 0),
179-
Commits: make(map[Hash]Object, 0),
180-
Trees: make(map[Hash]Object, 0),
181-
Blobs: make(map[Hash]Object, 0),
182-
}
183-
}
184-
185-
func (o *RAWObjectStorage) New() (Object, error) {
186-
return &RAWObject{}, nil
187-
}
188-
189-
func (o *RAWObjectStorage) Set(obj Object) (Hash, error) {
190-
h := obj.Hash()
191-
o.Objects[h] = obj
192-
193-
switch obj.Type() {
194-
case CommitObject:
195-
o.Commits[h] = o.Objects[h]
196-
case TreeObject:
197-
o.Trees[h] = o.Objects[h]
198-
case BlobObject:
199-
o.Blobs[h] = o.Objects[h]
200-
}
201-
202-
return h, nil
203-
}
204-
205-
func (o *RAWObjectStorage) Get(h Hash) (Object, error) {
206-
obj, ok := o.Objects[h]
207-
if !ok {
208-
return nil, ObjectNotFoundErr
209-
}
210-
211-
return obj, nil
212-
}
213-
214-
func (o *RAWObjectStorage) Iter(t ObjectType) ObjectIter {
215-
var series []Object
216-
switch t {
217-
case CommitObject:
218-
series = flattenObjectMap(o.Commits)
219-
case TreeObject:
220-
series = flattenObjectMap(o.Trees)
221-
case BlobObject:
222-
series = flattenObjectMap(o.Blobs)
223-
}
224-
return NewObjectSliceIter(series)
225-
}
226-
227-
func flattenObjectMap(m map[Hash]Object) []Object {
228-
objects := make([]Object, 0, len(m))
229-
for _, obj := range m {
230-
objects = append(objects, obj)
231-
}
232-
return objects
233-
}

formats/packfile/reader.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ func (r *Reader) readObjects(count uint32) error {
125125
// of which 12-20 % is _not_ zlib inflation (ie. is our code).
126126
for i := 0; i < int(count); i++ {
127127
start := r.r.position
128-
obj, err := r.newRAWObject()
128+
obj, err := r.newObject()
129129
if err != nil && err != io.EOF {
130130
return err
131131
}
@@ -143,7 +143,7 @@ func (r *Reader) readObjects(count uint32) error {
143143
return nil
144144
}
145145

146-
func (r *Reader) newRAWObject() (core.Object, error) {
146+
func (r *Reader) newObject() (core.Object, error) {
147147
raw, err := r.s.New()
148148
if err != nil {
149149
return nil, err

formats/packfile/reader_test.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"time"
1111

1212
"gopkg.in/src-d/go-git.v2/core"
13+
"gopkg.in/src-d/go-git.v2/storages/memory"
1314

1415
"github.com/dustin/go-humanize"
1516
. "gopkg.in/check.v1"
@@ -29,7 +30,7 @@ func (s *ReaderSuite) TestReadPackfile(c *C) {
2930

3031
r := NewReader(d)
3132

32-
storage := core.NewRAWObjectStorage()
33+
storage := memory.NewObjectStorage()
3334
_, err := r.Read(storage)
3435
c.Assert(err, IsNil)
3536

@@ -63,7 +64,7 @@ func (s *ReaderSuite) testReadPackfileGitFixture(c *C, file string, f Format) {
6364
r := NewReader(d)
6465
r.Format = f
6566

66-
storage := core.NewRAWObjectStorage()
67+
storage := memory.NewObjectStorage()
6768
_, err = r.Read(storage)
6869
c.Assert(err, IsNil)
6970

@@ -99,7 +100,7 @@ func (s *ReaderSuite) testReadPackfileGitFixture(c *C, file string, f Format) {
99100
})
100101
}
101102

102-
func AssertObjects(c *C, s *core.RAWObjectStorage, expects []string) {
103+
func AssertObjects(c *C, s *memory.ObjectStorage, expects []string) {
103104
c.Assert(len(expects), Equals, len(s.Objects))
104105
for _, expected := range expects {
105106
obtained, err := s.Get(core.NewHash(expected))
@@ -174,14 +175,14 @@ func (s *ReaderSuite) _TestMemoryREF(c *C) {
174175
fmt.Println("time", time.Since(start))
175176
}
176177

177-
func readFromFile(c *C, file string, f Format) *core.RAWObjectStorage {
178+
func readFromFile(c *C, file string, f Format) *memory.ObjectStorage {
178179
d, err := os.Open(file)
179180
c.Assert(err, IsNil)
180181

181182
r := NewReader(d)
182183
r.Format = f
183184

184-
storage := core.NewRAWObjectStorage()
185+
storage := memory.NewObjectStorage()
185186
_, err = r.Read(storage)
186187
c.Assert(err, IsNil)
187188

objects.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package git
22

33
import (
4+
"errors"
45
"fmt"
56
"io"
67
"strconv"
@@ -17,8 +18,14 @@ type Blob struct {
1718
obj core.Object
1819
}
1920

21+
var ErrUnsupportedObject = errors.New("unsupported object type")
22+
2023
// Decode transform an core.Object into a Blob struct
2124
func (b *Blob) Decode(o core.Object) error {
25+
if o.Type() != core.BlobObject {
26+
return ErrUnsupportedObject
27+
}
28+
2229
b.Hash = o.Hash()
2330
b.Size = o.Size()
2431
b.obj = o

objects_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
. "gopkg.in/check.v1"
88
"gopkg.in/src-d/go-git.v2/core"
9+
"gopkg.in/src-d/go-git.v2/storages/memory"
910
)
1011

1112
type ObjectsSuite struct {
@@ -71,7 +72,7 @@ func (s *ObjectsSuite) TestParseTree(c *C) {
7172
}
7273

7374
func (s *ObjectsSuite) TestBlobHash(c *C) {
74-
o := &core.RAWObject{}
75+
o := &memory.Object{}
7576
o.SetType(core.BlobObject)
7677
o.SetSize(3)
7778
o.Writer().Write([]byte{'F', 'O', 'O'})

remote_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ package git
22

33
import (
44
"gopkg.in/src-d/go-git.v2/clients/http"
5-
"gopkg.in/src-d/go-git.v2/core"
65
"gopkg.in/src-d/go-git.v2/formats/packfile"
6+
"gopkg.in/src-d/go-git.v2/storages/memory"
77

88
. "gopkg.in/check.v1"
99
)
@@ -57,7 +57,7 @@ func (s *SuiteRemote) TestFetchDefaultBranch(c *C) {
5757

5858
pr := packfile.NewReader(reader)
5959

60-
storage := core.NewRAWObjectStorage()
60+
storage := memory.NewObjectStorage()
6161
_, err = pr.Read(storage)
6262
c.Assert(err, IsNil)
6363
c.Assert(storage.Objects, HasLen, 28)

repository.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"gopkg.in/src-d/go-git.v2/clients/common"
88
"gopkg.in/src-d/go-git.v2/core"
99
"gopkg.in/src-d/go-git.v2/formats/packfile"
10+
"gopkg.in/src-d/go-git.v2/storages/memory"
1011
)
1112

1213
var (
@@ -49,7 +50,7 @@ func NewRepository(url string, auth common.AuthMethod) (*Repository, error) {
4950
func NewPlainRepository() *Repository {
5051
return &Repository{
5152
Remotes: map[string]*Remote{},
52-
Storage: core.NewRAWObjectStorage(),
53+
Storage: memory.NewObjectStorage(),
5354
}
5455
}
5556

storage/memory/object.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package memory
2+
3+
import (
4+
"bytes"
5+
"io"
6+
7+
"gopkg.in/src-d/go-git.v2/core"
8+
)
9+
10+
// Object on memory core.Object implementation
11+
type Object struct {
12+
t core.ObjectType
13+
h core.Hash
14+
content []byte
15+
size int64
16+
}
17+
18+
// Hash return the object Hash, the hash is calculated on-the-fly the first
19+
// time is called, the subsequent calls the same Hash is returned even in the
20+
// type or the content has changed. The Hash is only generated if the size of
21+
// the content is exactly the Object.Size
22+
func (o *Object) Hash() core.Hash {
23+
if o.h == core.ZeroHash && int64(len(o.content)) == o.size {
24+
o.h = core.ComputeHash(o.t, o.content)
25+
}
26+
27+
return o.h
28+
}
29+
30+
// Type return the core.ObjectType
31+
func (o *Object) Type() core.ObjectType { return o.t }
32+
33+
// SetType sets the core.ObjectType
34+
func (o *Object) SetType(t core.ObjectType) { o.t = t }
35+
36+
// Size return the size of the object
37+
func (o *Object) Size() int64 { return o.size }
38+
39+
// SetSize set the object size, the given size should be written afterwards
40+
func (o *Object) SetSize(s int64) { o.size = s }
41+
42+
// Reader returns a io.Reader used to read the object content
43+
func (o *Object) Reader() io.Reader {
44+
return bytes.NewBuffer(o.content)
45+
}
46+
47+
// Writer returns a io.Writed used to write the object content
48+
func (o *Object) Writer() io.Writer {
49+
return o
50+
}
51+
52+
func (o *Object) Write(p []byte) (n int, err error) {
53+
o.content = append(o.content, p...)
54+
return len(p), nil
55+
}

0 commit comments

Comments
 (0)