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

Commit 2dc59a6

Browse files
authored
Merge pull request #580 from erizocosmico/perf/refs-iter-once
remote: iterate over references only once
2 parents f9a1c7a + 1c2fb31 commit 2dc59a6

File tree

2 files changed

+73
-40
lines changed

2 files changed

+73
-40
lines changed

remote.go

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,12 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) error {
107107
return ErrDeleteRefNotSupported
108108
}
109109

110-
req, err := r.newReferenceUpdateRequest(o, remoteRefs, ar)
110+
localRefs, err := r.references()
111+
if err != nil {
112+
return err
113+
}
114+
115+
req, err := r.newReferenceUpdateRequest(o, localRefs, remoteRefs, ar)
111116
if err != nil {
112117
return err
113118
}
@@ -156,7 +161,12 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) error {
156161
return r.updateRemoteReferenceStorage(req, rs)
157162
}
158163

159-
func (r *Remote) newReferenceUpdateRequest(o *PushOptions, remoteRefs storer.ReferenceStorer, ar *packp.AdvRefs) (*packp.ReferenceUpdateRequest, error) {
164+
func (r *Remote) newReferenceUpdateRequest(
165+
o *PushOptions,
166+
localRefs []*plumbing.Reference,
167+
remoteRefs storer.ReferenceStorer,
168+
ar *packp.AdvRefs,
169+
) (*packp.ReferenceUpdateRequest, error) {
160170
req := packp.NewReferenceUpdateRequestFromCapabilities(ar.Capabilities)
161171

162172
if o.Progress != nil {
@@ -168,7 +178,7 @@ func (r *Remote) newReferenceUpdateRequest(o *PushOptions, remoteRefs storer.Ref
168178
}
169179
}
170180

171-
if err := r.addReferencesToUpdate(o.RefSpecs, remoteRefs, req); err != nil {
181+
if err := r.addReferencesToUpdate(o.RefSpecs, localRefs, remoteRefs, req); err != nil {
172182
return nil, err
173183
}
174184

@@ -262,14 +272,19 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (storer.ReferenceSt
262272
return nil, err
263273
}
264274

275+
localRefs, err := r.references()
276+
if err != nil {
277+
return nil, err
278+
}
279+
265280
refs, err := calculateRefs(o.RefSpecs, remoteRefs, o.Tags)
266281
if err != nil {
267282
return nil, err
268283
}
269284

270285
req.Wants, err = getWants(r.s, refs)
271286
if len(req.Wants) > 0 {
272-
req.Haves, err = getHaves(r.s)
287+
req.Haves, err = getHaves(localRefs)
273288
if err != nil {
274289
return nil, err
275290
}
@@ -346,17 +361,18 @@ func (r *Remote) fetchPack(ctx context.Context, o *FetchOptions, s transport.Upl
346361
return err
347362
}
348363

349-
func (r *Remote) addReferencesToUpdate(refspecs []config.RefSpec,
364+
func (r *Remote) addReferencesToUpdate(
365+
refspecs []config.RefSpec,
366+
localRefs []*plumbing.Reference,
350367
remoteRefs storer.ReferenceStorer,
351368
req *packp.ReferenceUpdateRequest) error {
352-
353369
for _, rs := range refspecs {
354370
if rs.IsDelete() {
355371
if err := r.deleteReferences(rs, remoteRefs, req); err != nil {
356372
return err
357373
}
358374
} else {
359-
if err := r.addOrUpdateReferences(rs, remoteRefs, req); err != nil {
375+
if err := r.addOrUpdateReferences(rs, localRefs, remoteRefs, req); err != nil {
360376
return err
361377
}
362378
}
@@ -365,18 +381,20 @@ func (r *Remote) addReferencesToUpdate(refspecs []config.RefSpec,
365381
return nil
366382
}
367383

368-
func (r *Remote) addOrUpdateReferences(rs config.RefSpec,
369-
remoteRefs storer.ReferenceStorer, req *packp.ReferenceUpdateRequest) error {
370-
iter, err := r.s.IterReferences()
371-
if err != nil {
372-
return err
384+
func (r *Remote) addOrUpdateReferences(
385+
rs config.RefSpec,
386+
localRefs []*plumbing.Reference,
387+
remoteRefs storer.ReferenceStorer,
388+
req *packp.ReferenceUpdateRequest,
389+
) error {
390+
for _, ref := range localRefs {
391+
err := r.addReferenceIfRefSpecMatches(rs, remoteRefs, ref, req)
392+
if err != nil {
393+
return err
394+
}
373395
}
374396

375-
return iter.ForEach(func(ref *plumbing.Reference) error {
376-
return r.addReferenceIfRefSpecMatches(
377-
rs, remoteRefs, ref, req,
378-
)
379-
})
397+
return nil
380398
}
381399

382400
func (r *Remote) deleteReferences(rs config.RefSpec,
@@ -449,28 +467,41 @@ func (r *Remote) addReferenceIfRefSpecMatches(rs config.RefSpec,
449467
return nil
450468
}
451469

452-
func getHaves(localRefs storer.ReferenceStorer) ([]plumbing.Hash, error) {
453-
iter, err := localRefs.IterReferences()
470+
func (r *Remote) references() ([]*plumbing.Reference, error) {
471+
var localRefs []*plumbing.Reference
472+
iter, err := r.s.IterReferences()
454473
if err != nil {
455474
return nil, err
456475
}
457476

477+
for {
478+
ref, err := iter.Next()
479+
if err == io.EOF {
480+
break
481+
}
482+
483+
if err != nil {
484+
return nil, err
485+
}
486+
487+
localRefs = append(localRefs, ref)
488+
}
489+
490+
return localRefs, nil
491+
}
492+
493+
func getHaves(localRefs []*plumbing.Reference) ([]plumbing.Hash, error) {
458494
haves := map[plumbing.Hash]bool{}
459-
err = iter.ForEach(func(ref *plumbing.Reference) error {
495+
for _, ref := range localRefs {
460496
if haves[ref.Hash()] == true {
461-
return nil
497+
continue
462498
}
463499

464500
if ref.Type() != plumbing.HashReference {
465-
return nil
501+
continue
466502
}
467503

468504
haves[ref.Hash()] = true
469-
return nil
470-
})
471-
472-
if err != nil {
473-
return nil, err
474505
}
475506

476507
var result []plumbing.Hash

remote_test.go

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -625,20 +625,22 @@ func (s *RemoteSuite) TestPushWrongRemoteName(c *C) {
625625
}
626626

627627
func (s *RemoteSuite) TestGetHaves(c *C) {
628-
st := memory.NewStorage()
629-
st.SetReference(plumbing.NewReferenceFromStrings(
630-
"foo", "f7b877701fbf855b44c0a9e86f3fdce2c298b07f",
631-
))
632-
633-
st.SetReference(plumbing.NewReferenceFromStrings(
634-
"bar", "fe6cb94756faa81e5ed9240f9191b833db5f40ae",
635-
))
636-
637-
st.SetReference(plumbing.NewReferenceFromStrings(
638-
"qux", "f7b877701fbf855b44c0a9e86f3fdce2c298b07f",
639-
))
628+
var localRefs = []*plumbing.Reference{
629+
plumbing.NewReferenceFromStrings(
630+
"foo",
631+
"f7b877701fbf855b44c0a9e86f3fdce2c298b07f",
632+
),
633+
plumbing.NewReferenceFromStrings(
634+
"bar",
635+
"fe6cb94756faa81e5ed9240f9191b833db5f40ae",
636+
),
637+
plumbing.NewReferenceFromStrings(
638+
"qux",
639+
"f7b877701fbf855b44c0a9e86f3fdce2c298b07f",
640+
),
641+
}
640642

641-
l, err := getHaves(st)
643+
l, err := getHaves(localRefs)
642644
c.Assert(err, IsNil)
643645
c.Assert(l, HasLen, 2)
644646
}

0 commit comments

Comments
 (0)