@@ -365,7 +365,7 @@ func (s *ObjectStorage) IterEncodedObjects(t plumbing.ObjectType) (storer.Encode
365365 return nil , err
366366 }
367367
368- seen := make (map [plumbing.Hash ]bool )
368+ seen := make (map [plumbing.Hash ]struct {} )
369369 var iters []storer.EncodedObjectIter
370370 if len (objects ) != 0 {
371371 iters = append (iters , & objectsIter {s : s , t : t , h : objects })
@@ -377,11 +377,11 @@ func (s *ObjectStorage) IterEncodedObjects(t plumbing.ObjectType) (storer.Encode
377377 return nil , err
378378 }
379379
380- iters = append (iters , packi ... )
380+ iters = append (iters , packi )
381381 return storer .NewMultiEncodedObjectIter (iters ), nil
382382}
383383
384- func (s * ObjectStorage ) buildPackfileIters (t plumbing.ObjectType , seen map [plumbing.Hash ]bool ) ([] storer.EncodedObjectIter , error ) {
384+ func (s * ObjectStorage ) buildPackfileIters (t plumbing.ObjectType , seen map [plumbing.Hash ]struct {} ) (storer.EncodedObjectIter , error ) {
385385 if err := s .requireIndex (); err != nil {
386386 return nil , err
387387 }
@@ -390,40 +390,80 @@ func (s *ObjectStorage) buildPackfileIters(t plumbing.ObjectType, seen map[plumb
390390 if err != nil {
391391 return nil , err
392392 }
393+ return & lazyPackfilesIter {
394+ hashes : packs ,
395+ open : func (h plumbing.Hash ) (storer.EncodedObjectIter , error ) {
396+ pack , err := s .dir .ObjectPack (h )
397+ if err != nil {
398+ return nil , err
399+ }
400+ return newPackfileIter (pack , t , seen , s .index [h ], s .deltaBaseCache )
401+ },
402+ }, nil
403+ }
393404
394- var iters []storer.EncodedObjectIter
395- for _ , h := range packs {
396- pack , err := s .dir .ObjectPack (h )
397- if err != nil {
398- return nil , err
399- }
405+ type lazyPackfilesIter struct {
406+ hashes []plumbing.Hash
407+ open func (h plumbing.Hash ) (storer.EncodedObjectIter , error )
408+ cur storer.EncodedObjectIter
409+ }
400410
401- iter , err := newPackfileIter (pack , t , seen , s .index [h ], s .deltaBaseCache )
402- if err != nil {
411+ func (it * lazyPackfilesIter ) Next () (plumbing.EncodedObject , error ) {
412+ for {
413+ if it .cur == nil {
414+ if len (it .hashes ) == 0 {
415+ return nil , io .EOF
416+ }
417+ h := it .hashes [0 ]
418+ it .hashes = it .hashes [1 :]
419+
420+ sub , err := it .open (h )
421+ if err == io .EOF {
422+ continue
423+ } else if err != nil {
424+ return nil , err
425+ }
426+ it .cur = sub
427+ }
428+ ob , err := it .cur .Next ()
429+ if err == io .EOF {
430+ it .cur .Close ()
431+ it .cur = nil
432+ continue
433+ } else if err != nil {
403434 return nil , err
404435 }
405-
406- iters = append (iters , iter )
436+ return ob , nil
407437 }
438+ }
408439
409- return iters , nil
440+ func (it * lazyPackfilesIter ) ForEach (cb func (plumbing.EncodedObject ) error ) error {
441+ return storer .ForEachIterator (it , cb )
442+ }
443+
444+ func (it * lazyPackfilesIter ) Close () {
445+ if it .cur != nil {
446+ it .cur .Close ()
447+ it .cur = nil
448+ }
449+ it .hashes = nil
410450}
411451
412452type packfileIter struct {
413453 f billy.File
414454 d * packfile.Decoder
415455 t plumbing.ObjectType
416456
417- seen map [plumbing.Hash ]bool
457+ seen map [plumbing.Hash ]struct {}
418458 position uint32
419459 total uint32
420460}
421461
422462func NewPackfileIter (f billy.File , t plumbing.ObjectType ) (storer.EncodedObjectIter , error ) {
423- return newPackfileIter (f , t , make (map [plumbing.Hash ]bool ), nil , nil )
463+ return newPackfileIter (f , t , make (map [plumbing.Hash ]struct {} ), nil , nil )
424464}
425465
426- func newPackfileIter (f billy.File , t plumbing.ObjectType , seen map [plumbing.Hash ]bool ,
466+ func newPackfileIter (f billy.File , t plumbing.ObjectType , seen map [plumbing.Hash ]struct {} ,
427467 index * packfile.Index , cache cache.Object ) (storer.EncodedObjectIter , error ) {
428468 s := packfile .NewScanner (f )
429469 _ , total , err := s .Header ()
@@ -464,7 +504,7 @@ func (iter *packfileIter) Next() (plumbing.EncodedObject, error) {
464504 continue
465505 }
466506
467- if iter .seen [obj .Hash ()] {
507+ if _ , ok := iter .seen [obj .Hash ()]; ok {
468508 return iter .Next ()
469509 }
470510
@@ -516,12 +556,11 @@ func (iter *objectsIter) Close() {
516556 iter .h = []plumbing.Hash {}
517557}
518558
519- func hashListAsMap (l []plumbing.Hash ) map [plumbing.Hash ]bool {
520- m := make (map [plumbing.Hash ]bool , len (l ))
559+ func hashListAsMap (l []plumbing.Hash ) map [plumbing.Hash ]struct {} {
560+ m := make (map [plumbing.Hash ]struct {} , len (l ))
521561 for _ , h := range l {
522- m [h ] = true
562+ m [h ] = struct {}{}
523563 }
524-
525564 return m
526565}
527566
0 commit comments