@@ -20,24 +20,25 @@ import (
2020type ObjectStorage struct {
2121 options Options
2222
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
2526
2627 dir * dotgit.DotGit
2728 index map [plumbing.Hash ]idxfile.Index
2829}
2930
3031// 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 {})
3334}
3435
3536// 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 {
3738 return & ObjectStorage {
38- options : ops ,
39- deltaBaseCache : cache ,
40- dir : dir ,
39+ options : ops ,
40+ objectCache : objectCache ,
41+ dir : dir ,
4142 }
4243}
4344
@@ -206,7 +207,7 @@ func (s *ObjectStorage) encodedObjectSizeFromPackfile(h plumbing.Hash) (
206207 idx := s .index [pack ]
207208 hash , err := idx .FindHash (offset )
208209 if err == nil {
209- obj , ok := s .deltaBaseCache .Get (hash )
210+ obj , ok := s .objectCache .Get (hash )
210211 if ok {
211212 return obj .Size (), nil
212213 }
@@ -215,8 +216,8 @@ func (s *ObjectStorage) encodedObjectSizeFromPackfile(h plumbing.Hash) (
215216 }
216217
217218 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 )
220221 } else {
221222 p = packfile .NewPackfile (idx , s .dir .Fs (), f )
222223 }
@@ -241,9 +242,19 @@ func (s *ObjectStorage) EncodedObjectSize(h plumbing.Hash) (
241242// EncodedObject returns the object with the given hash, by searching for it in
242243// the packfile and the git object directories.
243244func (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 {
246249 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+ }
247258 }
248259
249260 // 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
254265 // Create a new object storage with the DotGit(s) and check for the
255266 // required hash object. Skip when not found.
256267 for _ , dg := range dotgits {
257- o := NewObjectStorage (dg , s .deltaBaseCache )
268+ o := NewObjectStorage (dg , s .objectCache )
258269 enobj , enerr := o .EncodedObject (t , h )
259270 if enerr != nil {
260271 continue
@@ -296,6 +307,10 @@ func (s *ObjectStorage) DeltaObject(t plumbing.ObjectType,
296307}
297308
298309func (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+
299314 f , err := s .dir .Object (h )
300315 if err != nil {
301316 if os .IsNotExist (err ) {
@@ -327,6 +342,8 @@ func (s *ObjectStorage) getFromUnpacked(h plumbing.Hash) (obj plumbing.EncodedOb
327342 return nil , err
328343 }
329344
345+ s .objectCache .Put (obj )
346+
330347 _ , err = io .Copy (w , r )
331348 return obj , err
332349}
@@ -369,7 +386,7 @@ func (s *ObjectStorage) decodeObjectAt(
369386) (plumbing.EncodedObject , error ) {
370387 hash , err := idx .FindHash (offset )
371388 if err == nil {
372- obj , ok := s .deltaBaseCache .Get (hash )
389+ obj , ok := s .objectCache .Get (hash )
373390 if ok {
374391 return obj , nil
375392 }
@@ -380,8 +397,8 @@ func (s *ObjectStorage) decodeObjectAt(
380397 }
381398
382399 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 )
385402 } else {
386403 p = packfile .NewPackfile (idx , s .dir .Fs (), f )
387404 }
@@ -400,11 +417,7 @@ func (s *ObjectStorage) decodeDeltaObjectAt(
400417 }
401418
402419 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 )
408421 if err != nil {
409422 return nil , err
410423 }
@@ -495,7 +508,7 @@ func (s *ObjectStorage) buildPackfileIters(
495508 }
496509 return newPackfileIter (
497510 s .dir .Fs (), pack , t , seen , s .index [h ],
498- s .deltaBaseCache , s .options .KeepDescriptors ,
511+ s .objectCache , s .options .KeepDescriptors ,
499512 )
500513 },
501514 }, nil
0 commit comments