mirror of
https://github.com/restic/restic.git
synced 2025-08-21 10:57:55 +00:00
Optimize pack readHeader() implementation
Load pack header length and 15 header entries with single backend request. This eliminates separate header Load() request for most pack files and significantly improves index.New() performance. Signed-off-by: Igor Fedorenko <igor@ifedorenko.com>
This commit is contained in:
46
internal/pack/pack_internal_test.go
Normal file
46
internal/pack/pack_internal_test.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package pack
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/restic/restic/internal/crypto"
|
||||
rtest "github.com/restic/restic/internal/test"
|
||||
)
|
||||
|
||||
type countingReaderAt struct {
|
||||
delegate io.ReaderAt
|
||||
invocationCount int
|
||||
}
|
||||
|
||||
func (rd *countingReaderAt) ReadAt(p []byte, off int64) (n int, err error) {
|
||||
rd.invocationCount++
|
||||
return rd.delegate.ReadAt(p, off)
|
||||
}
|
||||
|
||||
func TestReadHeaderEagerLoad(t *testing.T) {
|
||||
|
||||
testReadHeader := func(entryCount uint, expectedReadInvocationCount int) {
|
||||
expectedHeader := rtest.Random(0, int(entryCount*entrySize)+crypto.Extension)
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
buf.Write(rtest.Random(0, 100)) // pack blobs data
|
||||
buf.Write(expectedHeader) // pack header
|
||||
binary.Write(buf, binary.LittleEndian, uint32(len(expectedHeader))) // pack header length
|
||||
|
||||
rd := &countingReaderAt{delegate: bytes.NewReader(buf.Bytes())}
|
||||
|
||||
header, err := readHeader(rd, int64(buf.Len()))
|
||||
rtest.OK(t, err)
|
||||
|
||||
rtest.Equals(t, expectedHeader, header)
|
||||
rtest.Equals(t, expectedReadInvocationCount, rd.invocationCount)
|
||||
}
|
||||
|
||||
testReadHeader(1, 1)
|
||||
testReadHeader(eagerEntries-1, 1)
|
||||
testReadHeader(eagerEntries, 1)
|
||||
testReadHeader(eagerEntries+1, 2)
|
||||
}
|
Reference in New Issue
Block a user