44 "bytes"
55 "errors"
66 "io"
7+ "io/ioutil"
78
89 "gopkg.in/src-d/go-git.v4/plumbing"
910 "gopkg.in/src-d/go-git.v4/plumbing/cache"
@@ -263,11 +264,14 @@ func (p *Parser) indexObjects() error {
263264}
264265
265266func (p * Parser ) resolveDeltas () error {
267+ buf := & bytes.Buffer {}
266268 for _ , obj := range p .oi {
267- content , err := p .get (obj )
269+ buf .Reset ()
270+ err := p .get (obj , buf )
268271 if err != nil {
269272 return err
270273 }
274+ content := buf .Bytes ()
271275
272276 if err := p .onInflatedObjectHeader (obj .Type , obj .Length , obj .Offset ); err != nil {
273277 return err
@@ -279,7 +283,7 @@ func (p *Parser) resolveDeltas() error {
279283
280284 if ! obj .IsDelta () && len (obj .Children ) > 0 {
281285 for _ , child := range obj .Children {
282- if _ , err := p .resolveObject (child , content ); err != nil {
286+ if err := p .resolveObject (ioutil . Discard , child , content ); err != nil {
283287 return err
284288 }
285289 }
@@ -294,120 +298,123 @@ func (p *Parser) resolveDeltas() error {
294298 return nil
295299}
296300
297- func (p * Parser ) get (o * objectInfo ) (b []byte , err error ) {
298- var ok bool
301+ func (p * Parser ) get (o * objectInfo , buf * bytes.Buffer ) error {
299302 if ! o .ExternalRef { // skip cache check for placeholder parents
300- b , ok = p .cache .Get (o .Offset )
303+ b , ok := p .cache .Get (o .Offset )
304+ if ok {
305+ _ , err := buf .Write (b )
306+ return err
307+ }
301308 }
302309
303310 // If it's not on the cache and is not a delta we can try to find it in the
304311 // storage, if there's one. External refs must enter here.
305- if ! ok && p .storage != nil && ! o .Type .IsDelta () {
312+ if p .storage != nil && ! o .Type .IsDelta () {
306313 e , err := p .storage .EncodedObject (plumbing .AnyObject , o .SHA1 )
307314 if err != nil {
308- return nil , err
315+ return err
309316 }
310317 o .Type = e .Type ()
311318
312319 r , err := e .Reader ()
313320 if err != nil {
314- return nil , err
315- }
316-
317- b = make ([]byte , e .Size ())
318- if _ , err = r .Read (b ); err != nil {
319- return nil , err
321+ return err
320322 }
321- }
322323
323- if b != nil {
324- return b , nil
324+ _ , err = buf . ReadFrom ( io . LimitReader ( r , e . Size ()))
325+ return err
325326 }
326327
327328 if o .ExternalRef {
328329 // we were not able to resolve a ref in a thin pack
329- return nil , ErrReferenceDeltaNotFound
330+ return ErrReferenceDeltaNotFound
330331 }
331332
332- var data []byte
333333 if o .DiskType .IsDelta () {
334- base , err := p .get (o .Parent )
334+ b := bufPool .Get ().(* bytes.Buffer )
335+ defer bufPool .Put (b )
336+ b .Reset ()
337+ err := p .get (o .Parent , b )
335338 if err != nil {
336- return nil , err
339+ return err
337340 }
341+ base := b .Bytes ()
338342
339- data , err = p .resolveObject (o , base )
343+ err = p .resolveObject (buf , o , base )
340344 if err != nil {
341- return nil , err
345+ return err
342346 }
343347 } else {
344- data , err = p .readData (o )
348+ err : = p .readData (buf , o )
345349 if err != nil {
346- return nil , err
350+ return err
347351 }
348352 }
349353
350354 if len (o .Children ) > 0 {
355+ data := make ([]byte , buf .Len ())
356+ copy (data , buf .Bytes ())
351357 p .cache .Put (o .Offset , data )
352358 }
353-
354- return data , nil
359+ return nil
355360}
356361
357362func (p * Parser ) resolveObject (
363+ w io.Writer ,
358364 o * objectInfo ,
359365 base []byte ,
360- ) ([] byte , error ) {
366+ ) error {
361367 if ! o .DiskType .IsDelta () {
362- return nil , nil
368+ return nil
363369 }
364-
365- data , err := p .readData (o )
370+ buf := bufPool .Get ().(* bytes.Buffer )
371+ defer bufPool .Put (buf )
372+ buf .Reset ()
373+ err := p .readData (buf , o )
366374 if err != nil {
367- return nil , err
375+ return err
368376 }
377+ data := buf .Bytes ()
369378
370379 data , err = applyPatchBase (o , data , base )
371380 if err != nil {
372- return nil , err
381+ return err
373382 }
374383
375384 if p .storage != nil {
376385 obj := new (plumbing.MemoryObject )
377386 obj .SetSize (o .Size ())
378387 obj .SetType (o .Type )
379388 if _ , err := obj .Write (data ); err != nil {
380- return nil , err
389+ return err
381390 }
382391
383392 if _ , err := p .storage .SetEncodedObject (obj ); err != nil {
384- return nil , err
393+ return err
385394 }
386395 }
387-
388- return data , nil
396+ _ , err = w . Write ( data )
397+ return err
389398}
390399
391- func (p * Parser ) readData (o * objectInfo ) ([] byte , error ) {
400+ func (p * Parser ) readData (w io. Writer , o * objectInfo ) error {
392401 if ! p .scanner .IsSeekable && o .DiskType .IsDelta () {
393402 data , ok := p .deltas [o .Offset ]
394403 if ! ok {
395- return nil , ErrDeltaNotCached
404+ return ErrDeltaNotCached
396405 }
397-
398- return data , nil
406+ _ , err := w . Write ( data )
407+ return err
399408 }
400409
401410 if _ , err := p .scanner .SeekObjectHeader (o .Offset ); err != nil {
402- return nil , err
411+ return err
403412 }
404413
405- buf := new (bytes.Buffer )
406- if _ , _ , err := p .scanner .NextObject (buf ); err != nil {
407- return nil , err
414+ if _ , _ , err := p .scanner .NextObject (w ); err != nil {
415+ return err
408416 }
409-
410- return buf .Bytes (), nil
417+ return nil
411418}
412419
413420func applyPatchBase (ota * objectInfo , data , base []byte ) ([]byte , error ) {
0 commit comments