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

Commit f4e603f

Browse files
committed
plumbing: packfile, Add a buffer to crc writer.
crc update with block smaller than 16 bytes uses a slower version of the function. ReadByte is heavily used by zlib inflate so most of the time crc is update byte by byte. A new Flush method is added to the scanner to flush this crc writer cache. It is only called when the Scanner reader is a teeReader. Signed-off-by: Javi Fontan <jfontan@gmail.com>
1 parent f6aca08 commit f4e603f

File tree

1 file changed

+31
-9
lines changed

1 file changed

+31
-9
lines changed

plumbing/format/packfile/scanner.go

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,7 @@ func NewScanner(r io.Reader) *Scanner {
6363

6464
crc := crc32.NewIEEE()
6565
return &Scanner{
66-
r: &teeReader{
67-
newByteReadSeeker(seeker),
68-
crc,
69-
},
66+
r: newTeeReader(newByteReadSeeker(seeker), crc),
7067
crc: crc,
7168
IsSeekable: ok,
7269
}
@@ -143,6 +140,8 @@ func (s *Scanner) readCount() (uint32, error) {
143140

144141
// NextObjectHeader returns the ObjectHeader for the next object in the reader
145142
func (s *Scanner) NextObjectHeader() (*ObjectHeader, error) {
143+
defer s.Flush()
144+
146145
if err := s.doPending(); err != nil {
147146
return nil, err
148147
}
@@ -271,6 +270,7 @@ func (s *Scanner) NextObject(w io.Writer) (written int64, crc32 uint32, err erro
271270

272271
s.pendingObject = nil
273272
written, err = s.copyObject(w)
273+
s.Flush()
274274
crc32 = s.crc.Sum32()
275275
return
276276
}
@@ -339,6 +339,16 @@ func (s *Scanner) Close() error {
339339
return err
340340
}
341341

342+
// Flush finishes writing the buffer to crc hasher in case we are using
343+
// a teeReader. Otherwise it is a no-op.
344+
func (s *Scanner) Flush() error {
345+
tee, ok := s.r.(*teeReader)
346+
if ok {
347+
return tee.Flush()
348+
}
349+
return nil
350+
}
351+
342352
type trackableReader struct {
343353
count int64
344354
io.Reader
@@ -400,10 +410,21 @@ type reader interface {
400410

401411
type teeReader struct {
402412
reader
403-
w hash.Hash32
413+
w hash.Hash32
414+
bufWriter *bufio.Writer
415+
}
416+
417+
func newTeeReader(r reader, h hash.Hash32) *teeReader {
418+
return &teeReader{
419+
reader: r,
420+
w: h,
421+
bufWriter: bufio.NewWriter(h),
422+
}
404423
}
405424

406425
func (r *teeReader) Read(p []byte) (n int, err error) {
426+
r.Flush()
427+
407428
n, err = r.reader.Read(p)
408429
if n > 0 {
409430
if n, err := r.w.Write(p[:n]); err != nil {
@@ -416,11 +437,12 @@ func (r *teeReader) Read(p []byte) (n int, err error) {
416437
func (r *teeReader) ReadByte() (b byte, err error) {
417438
b, err = r.reader.ReadByte()
418439
if err == nil {
419-
_, err := r.w.Write([]byte{b})
420-
if err != nil {
421-
return 0, err
422-
}
440+
return b, r.bufWriter.WriteByte(b)
423441
}
424442

425443
return
426444
}
445+
446+
func (r *teeReader) Flush() (err error) {
447+
return r.bufWriter.Flush()
448+
}

0 commit comments

Comments
 (0)