@@ -20,24 +20,25 @@ import (
20
20
type ObjectStorage struct {
21
21
options Options
22
22
23
- // deltaBaseCache is an object cache uses to cache delta's bases when
24
- deltaBaseCache cache.Object
23
+ // objectCache is an object cache uses to cache delta's bases and also recently
24
+ // loaded loose objects
25
+ objectCache cache.Object
25
26
26
27
dir * dotgit.DotGit
27
28
index map [plumbing.Hash ]idxfile.Index
28
29
}
29
30
30
31
// NewObjectStorage creates a new ObjectStorage with the given .git directory and cache.
31
- func NewObjectStorage (dir * dotgit.DotGit , cache cache.Object ) * ObjectStorage {
32
- return NewObjectStorageWithOptions (dir , cache , Options {})
32
+ func NewObjectStorage (dir * dotgit.DotGit , objectCache cache.Object ) * ObjectStorage {
33
+ return NewObjectStorageWithOptions (dir , objectCache , Options {})
33
34
}
34
35
35
36
// NewObjectStorageWithOptions creates a new ObjectStorage with the given .git directory, cache and extra options
36
- func NewObjectStorageWithOptions (dir * dotgit.DotGit , cache cache.Object , ops Options ) * ObjectStorage {
37
+ func NewObjectStorageWithOptions (dir * dotgit.DotGit , objectCache cache.Object , ops Options ) * ObjectStorage {
37
38
return & ObjectStorage {
38
- options : ops ,
39
- deltaBaseCache : cache ,
40
- dir : dir ,
39
+ options : ops ,
40
+ objectCache : objectCache ,
41
+ dir : dir ,
41
42
}
42
43
}
43
44
@@ -206,7 +207,7 @@ func (s *ObjectStorage) encodedObjectSizeFromPackfile(h plumbing.Hash) (
206
207
idx := s .index [pack ]
207
208
hash , err := idx .FindHash (offset )
208
209
if err == nil {
209
- obj , ok := s .deltaBaseCache .Get (hash )
210
+ obj , ok := s .objectCache .Get (hash )
210
211
if ok {
211
212
return obj .Size (), nil
212
213
}
@@ -215,8 +216,8 @@ func (s *ObjectStorage) encodedObjectSizeFromPackfile(h plumbing.Hash) (
215
216
}
216
217
217
218
var p * packfile.Packfile
218
- if s .deltaBaseCache != nil {
219
- p = packfile .NewPackfileWithCache (idx , s .dir .Fs (), f , s .deltaBaseCache )
219
+ if s .objectCache != nil {
220
+ p = packfile .NewPackfileWithCache (idx , s .dir .Fs (), f , s .objectCache )
220
221
} else {
221
222
p = packfile .NewPackfile (idx , s .dir .Fs (), f )
222
223
}
@@ -241,9 +242,19 @@ func (s *ObjectStorage) EncodedObjectSize(h plumbing.Hash) (
241
242
// EncodedObject returns the object with the given hash, by searching for it in
242
243
// the packfile and the git object directories.
243
244
func (s * ObjectStorage ) EncodedObject (t plumbing.ObjectType , h plumbing.Hash ) (plumbing.EncodedObject , error ) {
244
- obj , err := s .getFromUnpacked (h )
245
- if err == plumbing .ErrObjectNotFound {
245
+ var obj plumbing.EncodedObject
246
+ var err error
247
+
248
+ if s .index != nil {
246
249
obj , err = s .getFromPackfile (h , false )
250
+ if err == plumbing .ErrObjectNotFound {
251
+ obj , err = s .getFromUnpacked (h )
252
+ }
253
+ } else {
254
+ obj , err = s .getFromUnpacked (h )
255
+ if err == plumbing .ErrObjectNotFound {
256
+ obj , err = s .getFromPackfile (h , false )
257
+ }
247
258
}
248
259
249
260
// If the error is still object not found, check if it's a shared object
@@ -254,7 +265,7 @@ func (s *ObjectStorage) EncodedObject(t plumbing.ObjectType, h plumbing.Hash) (p
254
265
// Create a new object storage with the DotGit(s) and check for the
255
266
// required hash object. Skip when not found.
256
267
for _ , dg := range dotgits {
257
- o := NewObjectStorage (dg , s .deltaBaseCache )
268
+ o := NewObjectStorage (dg , s .objectCache )
258
269
enobj , enerr := o .EncodedObject (t , h )
259
270
if enerr != nil {
260
271
continue
@@ -296,6 +307,10 @@ func (s *ObjectStorage) DeltaObject(t plumbing.ObjectType,
296
307
}
297
308
298
309
func (s * ObjectStorage ) getFromUnpacked (h plumbing.Hash ) (obj plumbing.EncodedObject , err error ) {
310
+ if cacheObj , found := s .objectCache .Get (h ); found {
311
+ return cacheObj , nil
312
+ }
313
+
299
314
f , err := s .dir .Object (h )
300
315
if err != nil {
301
316
if os .IsNotExist (err ) {
@@ -327,6 +342,8 @@ func (s *ObjectStorage) getFromUnpacked(h plumbing.Hash) (obj plumbing.EncodedOb
327
342
return nil , err
328
343
}
329
344
345
+ s .objectCache .Put (obj )
346
+
330
347
_ , err = io .Copy (w , r )
331
348
return obj , err
332
349
}
@@ -369,7 +386,7 @@ func (s *ObjectStorage) decodeObjectAt(
369
386
) (plumbing.EncodedObject , error ) {
370
387
hash , err := idx .FindHash (offset )
371
388
if err == nil {
372
- obj , ok := s .deltaBaseCache .Get (hash )
389
+ obj , ok := s .objectCache .Get (hash )
373
390
if ok {
374
391
return obj , nil
375
392
}
@@ -380,8 +397,8 @@ func (s *ObjectStorage) decodeObjectAt(
380
397
}
381
398
382
399
var p * packfile.Packfile
383
- if s .deltaBaseCache != nil {
384
- p = packfile .NewPackfileWithCache (idx , s .dir .Fs (), f , s .deltaBaseCache )
400
+ if s .objectCache != nil {
401
+ p = packfile .NewPackfileWithCache (idx , s .dir .Fs (), f , s .objectCache )
385
402
} else {
386
403
p = packfile .NewPackfile (idx , s .dir .Fs (), f )
387
404
}
@@ -400,11 +417,7 @@ func (s *ObjectStorage) decodeDeltaObjectAt(
400
417
}
401
418
402
419
p := packfile .NewScanner (f )
403
- if _ , err := p .SeekFromStart (offset ); err != nil {
404
- return nil , err
405
- }
406
-
407
- header , err := p .NextObjectHeader ()
420
+ header , err := p .SeekObjectHeader (offset )
408
421
if err != nil {
409
422
return nil , err
410
423
}
@@ -495,7 +508,7 @@ func (s *ObjectStorage) buildPackfileIters(
495
508
}
496
509
return newPackfileIter (
497
510
s .dir .Fs (), pack , t , seen , s .index [h ],
498
- s .deltaBaseCache , s .options .KeepDescriptors ,
511
+ s .objectCache , s .options .KeepDescriptors ,
499
512
)
500
513
},
501
514
}, nil
0 commit comments