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

Commit 82c7a30

Browse files
committed
storage/filesystem: keep packs open in PackfileIter
PackfileIter was not taking into account the option KeepDescriptors and was always closing the file. This caused "file already closed" errors when iterating packfiles in with KeepDescriptors active. Signed-off-by: Javi Fontan <jfontan@gmail.com>
1 parent f69f530 commit 82c7a30

File tree

2 files changed

+63
-14
lines changed

2 files changed

+63
-14
lines changed

storage/filesystem/object.go

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,10 @@ func (s *ObjectStorage) IterEncodedObjects(t plumbing.ObjectType) (storer.Encode
396396
return storer.NewMultiEncodedObjectIter(iters), nil
397397
}
398398

399-
func (s *ObjectStorage) buildPackfileIters(t plumbing.ObjectType, seen map[plumbing.Hash]struct{}) (storer.EncodedObjectIter, error) {
399+
func (s *ObjectStorage) buildPackfileIters(
400+
t plumbing.ObjectType,
401+
seen map[plumbing.Hash]struct{},
402+
) (storer.EncodedObjectIter, error) {
400403
if err := s.requireIndex(); err != nil {
401404
return nil, err
402405
}
@@ -412,7 +415,10 @@ func (s *ObjectStorage) buildPackfileIters(t plumbing.ObjectType, seen map[plumb
412415
if err != nil {
413416
return nil, err
414417
}
415-
return newPackfileIter(s.dir.Fs(), pack, t, seen, s.index[h], s.deltaBaseCache)
418+
return newPackfileIter(
419+
s.dir.Fs(), pack, t, seen, s.index[h],
420+
s.deltaBaseCache, s.options.KeepDescriptors,
421+
)
416422
},
417423
}, nil
418424
}
@@ -470,9 +476,10 @@ func (it *lazyPackfilesIter) Close() {
470476
}
471477

472478
type packfileIter struct {
473-
pack billy.File
474-
iter storer.EncodedObjectIter
475-
seen map[plumbing.Hash]struct{}
479+
pack billy.File
480+
iter storer.EncodedObjectIter
481+
seen map[plumbing.Hash]struct{}
482+
keepPack bool
476483
}
477484

478485
// NewPackfileIter returns a new EncodedObjectIter for the provided packfile
@@ -483,6 +490,7 @@ func NewPackfileIter(
483490
f billy.File,
484491
idxFile billy.File,
485492
t plumbing.ObjectType,
493+
keepPack bool,
486494
) (storer.EncodedObjectIter, error) {
487495
idx := idxfile.NewMemoryIndex()
488496
if err := idxfile.NewDecoder(idxFile).Decode(idx); err != nil {
@@ -493,7 +501,8 @@ func NewPackfileIter(
493501
return nil, err
494502
}
495503

496-
return newPackfileIter(fs, f, t, make(map[plumbing.Hash]struct{}), idx, nil)
504+
seen := make(map[plumbing.Hash]struct{})
505+
return newPackfileIter(fs, f, t, seen, idx, nil, keepPack)
497506
}
498507

499508
func newPackfileIter(
@@ -503,6 +512,7 @@ func newPackfileIter(
503512
seen map[plumbing.Hash]struct{},
504513
index idxfile.Index,
505514
cache cache.Object,
515+
keepPack bool,
506516
) (storer.EncodedObjectIter, error) {
507517
var p *packfile.Packfile
508518
if cache != nil {
@@ -517,9 +527,10 @@ func newPackfileIter(
517527
}
518528

519529
return &packfileIter{
520-
pack: f,
521-
iter: iter,
522-
seen: seen,
530+
pack: f,
531+
iter: iter,
532+
seen: seen,
533+
keepPack: keepPack,
523534
}, nil
524535
}
525536

@@ -557,7 +568,9 @@ func (iter *packfileIter) ForEach(cb func(plumbing.EncodedObject) error) error {
557568

558569
func (iter *packfileIter) Close() {
559570
iter.iter.Close()
560-
_ = iter.pack.Close()
571+
if !iter.keepPack {
572+
_ = iter.pack.Close()
573+
}
561574
}
562575

563576
type objectsIter struct {

storage/filesystem/object_test.go

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,18 +153,54 @@ func (s *FsSuite) TestPackfileIter(c *C) {
153153
idxf, err := dg.ObjectPackIdx(h)
154154
c.Assert(err, IsNil)
155155

156-
iter, err := NewPackfileIter(fs, f, idxf, t)
156+
iter, err := NewPackfileIter(fs, f, idxf, t, false)
157157
c.Assert(err, IsNil)
158+
158159
err = iter.ForEach(func(o plumbing.EncodedObject) error {
159160
c.Assert(o.Type(), Equals, t)
160161
return nil
161162
})
162-
163163
c.Assert(err, IsNil)
164164
}
165165
}
166166
})
167+
}
168+
169+
func (s *FsSuite) TestPackfileIterKeepDescriptors(c *C) {
170+
fixtures.ByTag(".git").Test(c, func(f *fixtures.Fixture) {
171+
fs := f.DotGit()
172+
ops := dotgit.Options{KeepDescriptors: true}
173+
dg := dotgit.NewWithOptions(fs, ops)
174+
175+
for _, t := range objectTypes {
176+
ph, err := dg.ObjectPacks()
177+
c.Assert(err, IsNil)
178+
179+
for _, h := range ph {
180+
f, err := dg.ObjectPack(h)
181+
c.Assert(err, IsNil)
182+
183+
idxf, err := dg.ObjectPackIdx(h)
184+
c.Assert(err, IsNil)
167185

186+
iter, err := NewPackfileIter(fs, f, idxf, t, true)
187+
c.Assert(err, IsNil)
188+
189+
err = iter.ForEach(func(o plumbing.EncodedObject) error {
190+
c.Assert(o.Type(), Equals, t)
191+
return nil
192+
})
193+
c.Assert(err, IsNil)
194+
195+
// test twice to check that packfiles are not closed
196+
err = iter.ForEach(func(o plumbing.EncodedObject) error {
197+
c.Assert(o.Type(), Equals, t)
198+
return nil
199+
})
200+
c.Assert(err, IsNil)
201+
}
202+
}
203+
})
168204
}
169205

170206
func BenchmarkPackfileIter(b *testing.B) {
@@ -201,7 +237,7 @@ func BenchmarkPackfileIter(b *testing.B) {
201237
b.Fatal(err)
202238
}
203239

204-
iter, err := NewPackfileIter(fs, f, idxf, t)
240+
iter, err := NewPackfileIter(fs, f, idxf, t, false)
205241
if err != nil {
206242
b.Fatal(err)
207243
}
@@ -257,7 +293,7 @@ func BenchmarkPackfileIterReadContent(b *testing.B) {
257293
b.Fatal(err)
258294
}
259295

260-
iter, err := NewPackfileIter(fs, f, idxf, t)
296+
iter, err := NewPackfileIter(fs, f, idxf, t, false)
261297
if err != nil {
262298
b.Fatal(err)
263299
}

0 commit comments

Comments
 (0)