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

Commit 3052df3

Browse files
committed
plumbing: storer, new NewMultiReferenceIter
Signed-off-by: Máximo Cuadros <mcuadros@gmail.com>
1 parent ff04a1d commit 3052df3

File tree

2 files changed

+89
-2
lines changed

2 files changed

+89
-2
lines changed

plumbing/storer/reference.go

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,27 @@ func (iter *ReferenceSliceIter) Next() (*plumbing.Reference, error) {
131131
// an error happens or the end of the iter is reached. If ErrStop is sent
132132
// the iteration is stop but no error is returned. The iterator is closed.
133133
func (iter *ReferenceSliceIter) ForEach(cb func(*plumbing.Reference) error) error {
134+
return forEachReferenceIter(iter, cb)
135+
}
136+
137+
type bareReferenceIterator interface {
138+
Next() (*plumbing.Reference, error)
139+
Close()
140+
}
141+
142+
func forEachReferenceIter(iter bareReferenceIterator, cb func(*plumbing.Reference) error) error {
134143
defer iter.Close()
135-
for _, r := range iter.series {
136-
if err := cb(r); err != nil {
144+
for {
145+
obj, err := iter.Next()
146+
if err != nil {
147+
if err == io.EOF {
148+
return nil
149+
}
150+
151+
return err
152+
}
153+
154+
if err := cb(obj); err != nil {
137155
if err == ErrStop {
138156
return nil
139157
}
@@ -150,6 +168,52 @@ func (iter *ReferenceSliceIter) Close() {
150168
iter.pos = len(iter.series)
151169
}
152170

171+
// MultiReferenceIter implements ReferenceIter. It iterates over several
172+
// ReferenceIter,
173+
//
174+
// The MultiReferenceIter must be closed with a call to Close() when it is no
175+
// longer needed.
176+
type MultiReferenceIter struct {
177+
iters []ReferenceIter
178+
}
179+
180+
// NewMultiReferenceIter returns an reference iterator for the given slice of
181+
// EncodedObjectIters.
182+
func NewMultiReferenceIter(iters []ReferenceIter) ReferenceIter {
183+
return &MultiReferenceIter{iters: iters}
184+
}
185+
186+
// Next returns the next reference from the iterator, if one iterator reach
187+
// io.EOF is removed and the next one is used.
188+
func (iter *MultiReferenceIter) Next() (*plumbing.Reference, error) {
189+
if len(iter.iters) == 0 {
190+
return nil, io.EOF
191+
}
192+
193+
obj, err := iter.iters[0].Next()
194+
if err == io.EOF {
195+
iter.iters[0].Close()
196+
iter.iters = iter.iters[1:]
197+
return iter.Next()
198+
}
199+
200+
return obj, err
201+
}
202+
203+
// ForEach call the cb function for each reference contained on this iter until
204+
// an error happens or the end of the iter is reached. If ErrStop is sent
205+
// the iteration is stop but no error is returned. The iterator is closed.
206+
func (iter *MultiReferenceIter) ForEach(cb func(*plumbing.Reference) error) error {
207+
return forEachReferenceIter(iter, cb)
208+
}
209+
210+
// Close releases any resources used by the iterator.
211+
func (iter *MultiReferenceIter) Close() {
212+
for _, i := range iter.iters {
213+
i.Close()
214+
}
215+
}
216+
153217
// ResolveReference resolves a SymbolicReference to a HashReference.
154218
func ResolveReference(s ReferenceStorer, n plumbing.ReferenceName) (*plumbing.Reference, error) {
155219
r, err := s.Reference(n)

plumbing/storer/reference_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,26 @@ func (s *ReferenceSuite) TestReferenceFilteredIterForEachStop(c *C) {
172172

173173
c.Assert(count, Equals, 1)
174174
}
175+
176+
func (s *ReferenceSuite) TestMultiReferenceIterForEach(c *C) {
177+
i := NewMultiReferenceIter(
178+
[]ReferenceIter{
179+
NewReferenceSliceIter([]*plumbing.Reference{
180+
plumbing.NewReferenceFromStrings("foo", "foo"),
181+
}),
182+
NewReferenceSliceIter([]*plumbing.Reference{
183+
plumbing.NewReferenceFromStrings("bar", "bar"),
184+
}),
185+
},
186+
)
187+
188+
var result []string
189+
err := i.ForEach(func(r *plumbing.Reference) error {
190+
result = append(result, r.Name().String())
191+
return nil
192+
})
193+
194+
c.Assert(err, IsNil)
195+
c.Assert(result, HasLen, 2)
196+
c.Assert(result, DeepEquals, []string{"foo", "bar"})
197+
}

0 commit comments

Comments
 (0)