4
4
"bytes"
5
5
"errors"
6
6
"io"
7
+ "io/ioutil"
7
8
8
9
"gopkg.in/src-d/go-git.v4/plumbing"
9
10
"gopkg.in/src-d/go-git.v4/plumbing/cache"
@@ -263,11 +264,14 @@ func (p *Parser) indexObjects() error {
263
264
}
264
265
265
266
func (p * Parser ) resolveDeltas () error {
267
+ buf := & bytes.Buffer {}
266
268
for _ , obj := range p .oi {
267
- content , err := p .get (obj )
269
+ buf .Reset ()
270
+ err := p .get (obj , buf )
268
271
if err != nil {
269
272
return err
270
273
}
274
+ content := buf .Bytes ()
271
275
272
276
if err := p .onInflatedObjectHeader (obj .Type , obj .Length , obj .Offset ); err != nil {
273
277
return err
@@ -279,7 +283,7 @@ func (p *Parser) resolveDeltas() error {
279
283
280
284
if ! obj .IsDelta () && len (obj .Children ) > 0 {
281
285
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 {
283
287
return err
284
288
}
285
289
}
@@ -294,120 +298,123 @@ func (p *Parser) resolveDeltas() error {
294
298
return nil
295
299
}
296
300
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 {
299
302
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
+ }
301
308
}
302
309
303
310
// If it's not on the cache and is not a delta we can try to find it in the
304
311
// 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 () {
306
313
e , err := p .storage .EncodedObject (plumbing .AnyObject , o .SHA1 )
307
314
if err != nil {
308
- return nil , err
315
+ return err
309
316
}
310
317
o .Type = e .Type ()
311
318
312
319
r , err := e .Reader ()
313
320
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
320
322
}
321
- }
322
323
323
- if b != nil {
324
- return b , nil
324
+ _ , err = buf . ReadFrom ( io . LimitReader ( r , e . Size ()))
325
+ return err
325
326
}
326
327
327
328
if o .ExternalRef {
328
329
// we were not able to resolve a ref in a thin pack
329
- return nil , ErrReferenceDeltaNotFound
330
+ return ErrReferenceDeltaNotFound
330
331
}
331
332
332
- var data []byte
333
333
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 )
335
338
if err != nil {
336
- return nil , err
339
+ return err
337
340
}
341
+ base := b .Bytes ()
338
342
339
- data , err = p .resolveObject (o , base )
343
+ err = p .resolveObject (buf , o , base )
340
344
if err != nil {
341
- return nil , err
345
+ return err
342
346
}
343
347
} else {
344
- data , err = p .readData (o )
348
+ err : = p .readData (buf , o )
345
349
if err != nil {
346
- return nil , err
350
+ return err
347
351
}
348
352
}
349
353
350
354
if len (o .Children ) > 0 {
355
+ data := make ([]byte , buf .Len ())
356
+ copy (data , buf .Bytes ())
351
357
p .cache .Put (o .Offset , data )
352
358
}
353
-
354
- return data , nil
359
+ return nil
355
360
}
356
361
357
362
func (p * Parser ) resolveObject (
363
+ w io.Writer ,
358
364
o * objectInfo ,
359
365
base []byte ,
360
- ) ([] byte , error ) {
366
+ ) error {
361
367
if ! o .DiskType .IsDelta () {
362
- return nil , nil
368
+ return nil
363
369
}
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 )
366
374
if err != nil {
367
- return nil , err
375
+ return err
368
376
}
377
+ data := buf .Bytes ()
369
378
370
379
data , err = applyPatchBase (o , data , base )
371
380
if err != nil {
372
- return nil , err
381
+ return err
373
382
}
374
383
375
384
if p .storage != nil {
376
385
obj := new (plumbing.MemoryObject )
377
386
obj .SetSize (o .Size ())
378
387
obj .SetType (o .Type )
379
388
if _ , err := obj .Write (data ); err != nil {
380
- return nil , err
389
+ return err
381
390
}
382
391
383
392
if _ , err := p .storage .SetEncodedObject (obj ); err != nil {
384
- return nil , err
393
+ return err
385
394
}
386
395
}
387
-
388
- return data , nil
396
+ _ , err = w . Write ( data )
397
+ return err
389
398
}
390
399
391
- func (p * Parser ) readData (o * objectInfo ) ([] byte , error ) {
400
+ func (p * Parser ) readData (w io. Writer , o * objectInfo ) error {
392
401
if ! p .scanner .IsSeekable && o .DiskType .IsDelta () {
393
402
data , ok := p .deltas [o .Offset ]
394
403
if ! ok {
395
- return nil , ErrDeltaNotCached
404
+ return ErrDeltaNotCached
396
405
}
397
-
398
- return data , nil
406
+ _ , err := w . Write ( data )
407
+ return err
399
408
}
400
409
401
410
if _ , err := p .scanner .SeekObjectHeader (o .Offset ); err != nil {
402
- return nil , err
411
+ return err
403
412
}
404
413
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
408
416
}
409
-
410
- return buf .Bytes (), nil
417
+ return nil
411
418
}
412
419
413
420
func applyPatchBase (ota * objectInfo , data , base []byte ) ([]byte , error ) {
0 commit comments