mirror of
https://github.com/restic/restic.git
synced 2026-11-04 14:29:21 +00:00
repository: move Blob, Blobs and PackedBlob to pack package
This removes them from the public interface. The latter now only provides the PackBlob interface, without being bound to the type used internally by the pack package.
This commit is contained in:
1 parent
35af104749
commit
c062a78dcd
27 files changed
+373
-345
No files matched your search
@@ -159,14 +159,15 @@ func (a *AssociatedSet[T]) All() iter.Seq2[restic.BlobHandle, T] {
|
||||
}
|
||||
|
||||
for pb := range a.idx.Values() {
|
||||
if _, ok := a.overflow[pb.BlobHandle]; ok {
|
||||
bh := pb.Handle()
|
||||
if _, ok := a.overflow[bh]; ok {
|
||||
// already reported via overflow set
|
||||
continue
|
||||
}
|
||||
|
||||
val, known := a.Get(pb.BlobHandle)
|
||||
val, known := a.Get(bh)
|
||||
if known {
|
||||
if !yield(pb.BlobHandle, val) {
|
||||
if !yield(bh, val) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/restic/restic/internal/crypto"
|
||||
"github.com/restic/restic/internal/repository/pack"
|
||||
"github.com/restic/restic/internal/restic"
|
||||
"github.com/restic/restic/internal/test"
|
||||
)
|
||||
@@ -19,17 +20,17 @@ func (n *noopSaver) SaveUnpacked(_ context.Context, _ restic.FileType, buf []byt
|
||||
return restic.Hash(buf), nil
|
||||
}
|
||||
|
||||
func makeFakePackedBlob() (restic.BlobHandle, restic.PackedBlob) {
|
||||
func makeFakePackedBlob() (restic.BlobHandle, *pack.PackedBlob) {
|
||||
bh := restic.NewRandomBlobHandle()
|
||||
blob := restic.PackedBlob{
|
||||
PackID: restic.NewRandomID(),
|
||||
Blob: restic.Blob{
|
||||
pb := &pack.PackedBlob{
|
||||
Pack: restic.NewRandomID(),
|
||||
Blob: pack.Blob{
|
||||
BlobHandle: bh,
|
||||
Length: uint(crypto.CiphertextLength(10)),
|
||||
Offset: 0,
|
||||
},
|
||||
}
|
||||
return bh, blob
|
||||
return bh, pb
|
||||
}
|
||||
|
||||
func list(bs *AssociatedSet[uint8]) restic.BlobHandles {
|
||||
@@ -40,7 +41,7 @@ func TestAssociatedSet(t *testing.T) {
|
||||
bh, blob := makeFakePackedBlob()
|
||||
|
||||
mi := NewMasterIndex()
|
||||
test.OK(t, mi.StorePack(context.TODO(), blob.PackID, restic.Blobs{blob.Blob}, &noopSaver{}))
|
||||
test.OK(t, mi.StorePack(context.TODO(), blob.PackID(), pack.Blobs{blob.Blob}, &noopSaver{}))
|
||||
test.OK(t, mi.Flush(context.TODO(), &noopSaver{}))
|
||||
|
||||
bs := NewAssociatedSet[uint8](mi)
|
||||
@@ -123,14 +124,14 @@ func TestAssociatedSetWithExtendedIndex(t *testing.T) {
|
||||
_, blob := makeFakePackedBlob()
|
||||
|
||||
mi := NewMasterIndex()
|
||||
test.OK(t, mi.StorePack(context.TODO(), blob.PackID, restic.Blobs{blob.Blob}, &noopSaver{}))
|
||||
test.OK(t, mi.StorePack(context.TODO(), blob.PackID(), pack.Blobs{blob.Blob}, &noopSaver{}))
|
||||
test.OK(t, mi.Flush(context.TODO(), &noopSaver{}))
|
||||
|
||||
bs := NewAssociatedSet[uint8](mi)
|
||||
|
||||
// add new blobs to index after building the set
|
||||
of, blob2 := makeFakePackedBlob()
|
||||
test.OK(t, mi.StorePack(context.TODO(), blob2.PackID, restic.Blobs{blob2.Blob}, &noopSaver{}))
|
||||
test.OK(t, mi.StorePack(context.TODO(), blob2.PackID(), pack.Blobs{blob2.Blob}, &noopSaver{}))
|
||||
test.OK(t, mi.Flush(context.TODO(), &noopSaver{}))
|
||||
|
||||
// non-existent
|
||||
@@ -167,10 +168,10 @@ func TestAssociatedSetIntersectAndSub(t *testing.T) {
|
||||
bh3, blob3 := makeFakePackedBlob()
|
||||
bh4, blob4 := makeFakePackedBlob()
|
||||
|
||||
test.OK(t, mi.StorePack(context.TODO(), blob1.PackID, restic.Blobs{blob1.Blob}, saver))
|
||||
test.OK(t, mi.StorePack(context.TODO(), blob2.PackID, restic.Blobs{blob2.Blob}, saver))
|
||||
test.OK(t, mi.StorePack(context.TODO(), blob3.PackID, restic.Blobs{blob3.Blob}, saver))
|
||||
test.OK(t, mi.StorePack(context.TODO(), blob4.PackID, restic.Blobs{blob4.Blob}, saver))
|
||||
test.OK(t, mi.StorePack(context.TODO(), blob1.PackID(), pack.Blobs{blob1.Blob}, saver))
|
||||
test.OK(t, mi.StorePack(context.TODO(), blob2.PackID(), pack.Blobs{blob2.Blob}, saver))
|
||||
test.OK(t, mi.StorePack(context.TODO(), blob3.PackID(), pack.Blobs{blob3.Blob}, saver))
|
||||
test.OK(t, mi.StorePack(context.TODO(), blob4.PackID(), pack.Blobs{blob4.Blob}, saver))
|
||||
test.OK(t, mi.Flush(context.TODO(), saver))
|
||||
|
||||
t.Run("Intersect", func(t *testing.T) {
|
||||
|
||||
@@ -73,7 +73,7 @@ func (idx *Index) addToPacks(id restic.ID) int {
|
||||
return len(idx.packs) - 1
|
||||
}
|
||||
|
||||
func (idx *Index) store(packIndex int, blob restic.Blob) {
|
||||
func (idx *Index) store(packIndex int, blob pack.Blob) {
|
||||
// assert that offset and length fit into uint32!
|
||||
if blob.Offset > math.MaxUint32 || blob.Length > math.MaxUint32 || blob.UncompressedLength > math.MaxUint32 {
|
||||
panic("offset or length does not fit in uint32. You have packs > 4GB!")
|
||||
@@ -146,7 +146,7 @@ func (idx *Index) Preallocate(t restic.BlobType, numEntries int) {
|
||||
|
||||
// StorePack remembers the ids of all blobs of a given pack
|
||||
// in the index
|
||||
func (idx *Index) StorePack(id restic.ID, blobs restic.Blobs) {
|
||||
func (idx *Index) StorePack(id restic.ID, blobs pack.Blobs) {
|
||||
idx.m.Lock()
|
||||
defer idx.m.Unlock()
|
||||
|
||||
@@ -162,23 +162,24 @@ func (idx *Index) StorePack(id restic.ID, blobs restic.Blobs) {
|
||||
}
|
||||
}
|
||||
|
||||
func (idx *Index) toPackedBlob(e *indexEntry, t restic.BlobType) restic.PackedBlob {
|
||||
return restic.PackedBlob{
|
||||
Blob: restic.Blob{
|
||||
func (idx *Index) toPackedBlob(e *indexEntry, t restic.BlobType) *pack.PackedBlob {
|
||||
return &pack.PackedBlob{
|
||||
Pack: idx.packs[e.packIndex],
|
||||
Blob: pack.Blob{
|
||||
BlobHandle: restic.BlobHandle{
|
||||
ID: e.id,
|
||||
Type: t},
|
||||
Type: t,
|
||||
},
|
||||
Length: uint(e.length),
|
||||
Offset: uint(e.offset),
|
||||
UncompressedLength: uint(e.uncompressedLength),
|
||||
},
|
||||
PackID: idx.packs[e.packIndex],
|
||||
}
|
||||
}
|
||||
|
||||
// Lookup queries the index for the blob ID and returns all entries including
|
||||
// duplicates. Adds found entries to blobs and returns the result.
|
||||
func (idx *Index) Lookup(bh restic.BlobHandle, pbs []restic.PackedBlob) []restic.PackedBlob {
|
||||
// duplicates. Adds found entries to pbs and returns the result.
|
||||
func (idx *Index) Lookup(bh restic.BlobHandle, pbs []*pack.PackedBlob) []*pack.PackedBlob {
|
||||
idx.m.RLock()
|
||||
defer idx.m.RUnlock()
|
||||
|
||||
@@ -215,8 +216,8 @@ func (idx *Index) LookupSize(bh restic.BlobHandle) (plaintextLength uint, found
|
||||
|
||||
// Values returns an iterator over all blobs known to the index. This blocks any
|
||||
// modification of the index.
|
||||
func (idx *Index) Values() iter.Seq[restic.PackedBlob] {
|
||||
return func(yield func(restic.PackedBlob) bool) {
|
||||
func (idx *Index) Values() iter.Seq[*pack.PackedBlob] {
|
||||
return func(yield func(*pack.PackedBlob) bool) {
|
||||
idx.m.RLock()
|
||||
defer idx.m.RUnlock()
|
||||
|
||||
@@ -231,17 +232,23 @@ func (idx *Index) Values() iter.Seq[restic.PackedBlob] {
|
||||
}
|
||||
}
|
||||
|
||||
// EachByPack returns a channel that yields all blobs known to the index
|
||||
// PackBlobs lists all blobs contained in a pack file according to the index.
|
||||
type PackBlobs struct {
|
||||
PackID restic.ID
|
||||
Blobs pack.Blobs
|
||||
}
|
||||
|
||||
// EachByPack returns a channel that yields all blobs known to the index,
|
||||
// grouped by packID but ignoring blobs with a packID in packPlacklist for
|
||||
// finalized indexes.
|
||||
// This filtering is used when rebuilding the index where we need to ignore packs
|
||||
// from the finalized index which have been re-read into a non-finalized index.
|
||||
// When the context is cancelled, the background goroutine
|
||||
// terminates. This blocks any modification of the index.
|
||||
func (idx *Index) EachByPack(ctx context.Context, packBlacklist restic.IDSet) <-chan restic.PackBlobs {
|
||||
func (idx *Index) EachByPack(ctx context.Context, packBlacklist restic.IDSet) <-chan PackBlobs {
|
||||
idx.m.RLock()
|
||||
|
||||
ch := make(chan restic.PackBlobs)
|
||||
ch := make(chan PackBlobs)
|
||||
|
||||
go func() {
|
||||
defer idx.m.RUnlock()
|
||||
@@ -262,7 +269,7 @@ func (idx *Index) EachByPack(ctx context.Context, packBlacklist restic.IDSet) <-
|
||||
}
|
||||
|
||||
for packID, packByType := range byPack {
|
||||
var result restic.PackBlobs
|
||||
var result PackBlobs
|
||||
result.PackID = packID
|
||||
for typ, p := range packByType {
|
||||
for _, e := range p {
|
||||
@@ -482,7 +489,7 @@ func (idx *Index) merge(idx2 *Index) error {
|
||||
for e := range m.valuesWithID(e2.id) {
|
||||
b := idx.toPackedBlob(e, restic.BlobType(typ))
|
||||
b2 := idx2.toPackedBlob(e2, restic.BlobType(typ))
|
||||
if b == b2 {
|
||||
if *b == *b2 {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
@@ -519,7 +526,7 @@ func DecodeIndex(buf []byte, id restic.ID) (idx *Index, err error) {
|
||||
packID := idx.addToPacks(p.ID)
|
||||
|
||||
for _, blob := range p.Blobs {
|
||||
idx.store(packID, restic.Blob{
|
||||
idx.store(packID, pack.Blob{
|
||||
BlobHandle: restic.BlobHandle{
|
||||
Type: blob.Type,
|
||||
ID: blob.ID},
|
||||
@@ -550,7 +557,7 @@ func (idx *Index) Len(t restic.BlobType) uint {
|
||||
return idx.byType[t].len()
|
||||
}
|
||||
|
||||
func PackBlobsHash(pbs restic.PackBlobs) restic.ID {
|
||||
func PackBlobsHash(pbs PackBlobs) restic.ID {
|
||||
h := sha256.New()
|
||||
h.Write(pbs.PackID[:])
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ func TestIndexOversized(t *testing.T) {
|
||||
// Add blobs up to indexMaxBlobs + pack.MaxHeaderEntries - 1
|
||||
packID := idx.addToPacks(restic.NewRandomID())
|
||||
for i := uint(0); i < indexMaxBlobs+pack.MaxHeaderEntries-1; i++ {
|
||||
idx.store(packID, restic.Blob{
|
||||
idx.store(packID, pack.Blob{
|
||||
BlobHandle: restic.BlobHandle{
|
||||
Type: restic.DataBlob,
|
||||
ID: restic.NewRandomID(),
|
||||
@@ -27,7 +27,7 @@ func TestIndexOversized(t *testing.T) {
|
||||
rtest.Assert(t, !Oversized(idx), "index should not be considered oversized")
|
||||
|
||||
// Add one more blob to exceed the limit
|
||||
idx.store(packID, restic.Blob{
|
||||
idx.store(packID, pack.Blob{
|
||||
BlobHandle: restic.BlobHandle{
|
||||
Type: restic.DataBlob,
|
||||
ID: restic.NewRandomID(),
|
||||
|
||||
@@ -9,19 +9,20 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/restic/restic/internal/repository/index"
|
||||
"github.com/restic/restic/internal/repository/pack"
|
||||
"github.com/restic/restic/internal/restic"
|
||||
rtest "github.com/restic/restic/internal/test"
|
||||
)
|
||||
|
||||
func TestIndexSerialize(t *testing.T) {
|
||||
tests := []restic.PackedBlob{}
|
||||
tests := []*pack.PackedBlob{}
|
||||
|
||||
idx := index.NewIndex()
|
||||
|
||||
// create 50 packs with 20 blobs each
|
||||
for i := 0; i < 50; i++ {
|
||||
packID := restic.NewRandomID()
|
||||
var blobs restic.Blobs
|
||||
var blobs pack.Blobs
|
||||
|
||||
pos := uint(0)
|
||||
for j := 0; j < 20; j++ {
|
||||
@@ -31,14 +32,14 @@ func TestIndexSerialize(t *testing.T) {
|
||||
// test a mix of compressed and uncompressed packs
|
||||
uncompressedLength = 2 * length
|
||||
}
|
||||
pb := restic.PackedBlob{
|
||||
Blob: restic.Blob{
|
||||
pb := &pack.PackedBlob{
|
||||
Pack: packID,
|
||||
Blob: pack.Blob{
|
||||
BlobHandle: restic.NewRandomBlobHandle(),
|
||||
Offset: pos,
|
||||
Length: length,
|
||||
UncompressedLength: uncompressedLength,
|
||||
},
|
||||
PackID: packID,
|
||||
}
|
||||
blobs = append(blobs, pb.Blob)
|
||||
tests = append(tests, pb)
|
||||
@@ -64,17 +65,17 @@ func TestIndexSerialize(t *testing.T) {
|
||||
rtest.OK(t, err)
|
||||
|
||||
for _, testBlob := range tests {
|
||||
list := idx.Lookup(testBlob.BlobHandle, nil)
|
||||
list := idx.Lookup(testBlob.Handle(), nil)
|
||||
if len(list) != 1 {
|
||||
t.Errorf("expected one result for blob %v, got %v: %v", testBlob.ID.Str(), len(list), list)
|
||||
t.Errorf("expected one result for blob %v, got %v: %v", testBlob.Handle().ID.String(), len(list), list)
|
||||
}
|
||||
result := list[0]
|
||||
|
||||
rtest.Equals(t, testBlob, result)
|
||||
|
||||
list2 := idx2.Lookup(testBlob.BlobHandle, nil)
|
||||
list2 := idx2.Lookup(testBlob.Handle(), nil)
|
||||
if len(list2) != 1 {
|
||||
t.Errorf("expected one result for blob %v, got %v: %v", testBlob.ID.Str(), len(list2), list2)
|
||||
t.Errorf("expected one result for blob %v, got %v: %v", testBlob.Handle().ID.String(), len(list2), list2)
|
||||
}
|
||||
result2 := list2[0]
|
||||
|
||||
@@ -82,21 +83,21 @@ func TestIndexSerialize(t *testing.T) {
|
||||
}
|
||||
|
||||
// add more blobs to idx
|
||||
newtests := []restic.PackedBlob{}
|
||||
newtests := []*pack.PackedBlob{}
|
||||
for i := 0; i < 10; i++ {
|
||||
packID := restic.NewRandomID()
|
||||
var blobs restic.Blobs
|
||||
var blobs pack.Blobs
|
||||
|
||||
pos := uint(0)
|
||||
for j := 0; j < 10; j++ {
|
||||
length := uint(i*100 + j)
|
||||
pb := restic.PackedBlob{
|
||||
Blob: restic.Blob{
|
||||
pb := &pack.PackedBlob{
|
||||
Pack: packID,
|
||||
Blob: pack.Blob{
|
||||
BlobHandle: restic.NewRandomBlobHandle(),
|
||||
Offset: pos,
|
||||
Length: length,
|
||||
},
|
||||
PackID: packID,
|
||||
}
|
||||
blobs = append(blobs, pb.Blob)
|
||||
newtests = append(newtests, pb)
|
||||
@@ -127,9 +128,9 @@ func TestIndexSerialize(t *testing.T) {
|
||||
|
||||
// all new blobs must be in the index
|
||||
for _, testBlob := range newtests {
|
||||
list := idx3.Lookup(testBlob.BlobHandle, nil)
|
||||
list := idx3.Lookup(testBlob.Handle(), nil)
|
||||
if len(list) != 1 {
|
||||
t.Errorf("expected one result for blob %v, got %v: %v", testBlob.ID.Str(), len(list), list)
|
||||
t.Errorf("expected one result for blob %v, got %v: %v", testBlob.Handle().ID.String(), len(list), list)
|
||||
}
|
||||
|
||||
blob := list[0]
|
||||
@@ -145,12 +146,12 @@ func TestIndexSize(t *testing.T) {
|
||||
blobCount := 100
|
||||
for i := 0; i < packs; i++ {
|
||||
packID := restic.NewRandomID()
|
||||
var blobs restic.Blobs
|
||||
var blobs pack.Blobs
|
||||
|
||||
pos := uint(0)
|
||||
for j := 0; j < blobCount; j++ {
|
||||
length := uint(i*100 + j)
|
||||
blobs = append(blobs, restic.Blob{
|
||||
blobs = append(blobs, pack.Blob{
|
||||
BlobHandle: restic.NewRandomBlobHandle(),
|
||||
Offset: pos,
|
||||
Length: length,
|
||||
@@ -293,15 +294,15 @@ func TestIndexUnserialize(t *testing.T) {
|
||||
|
||||
t.Logf("looking for blob %v/%v, got %v", test.tpe, test.id.Str(), blob)
|
||||
|
||||
rtest.Equals(t, test.packID, blob.PackID)
|
||||
rtest.Equals(t, test.tpe, blob.Type)
|
||||
rtest.Equals(t, test.offset, blob.Offset)
|
||||
rtest.Equals(t, test.length, blob.Length)
|
||||
rtest.Equals(t, test.packID, blob.PackID())
|
||||
rtest.Equals(t, test.tpe, blob.Blob.Type)
|
||||
rtest.Equals(t, test.offset, blob.Blob.Offset)
|
||||
rtest.Equals(t, test.length, blob.Blob.Length)
|
||||
switch task.version {
|
||||
case 1:
|
||||
rtest.Equals(t, uint(0), blob.UncompressedLength)
|
||||
rtest.Equals(t, uint(0), blob.Blob.UncompressedLength)
|
||||
case 2:
|
||||
rtest.Equals(t, test.uncompressedLength, blob.UncompressedLength)
|
||||
rtest.Equals(t, test.uncompressedLength, blob.Blob.UncompressedLength)
|
||||
default:
|
||||
t.Fatal("Invalid index version")
|
||||
}
|
||||
@@ -313,20 +314,20 @@ func TestIndexUnserialize(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, blob := range blobs {
|
||||
b, ok := exampleLookupTest.blobs[blob.ID]
|
||||
b, ok := exampleLookupTest.blobs[blob.Handle().ID]
|
||||
if !ok {
|
||||
t.Errorf("unexpected blob %v found", blob.ID.Str())
|
||||
t.Errorf("unexpected blob %v found", blob.Handle().ID.String())
|
||||
}
|
||||
if blob.Type != b {
|
||||
t.Errorf("unexpected type for blob %v: want %v, got %v", blob.ID.Str(), b, blob.Type)
|
||||
if blob.Blob.Type != b {
|
||||
t.Errorf("unexpected type for blob %v: want %v, got %v", blob.Handle().ID.String(), b, blob.Blob.Type)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func listPack(t testing.TB, idx *index.Index, id restic.ID) (pbs []restic.PackedBlob) {
|
||||
func listPack(t testing.TB, idx *index.Index, id restic.ID) (pbs []*pack.PackedBlob) {
|
||||
for pb := range idx.Values() {
|
||||
if pb.PackID.Equal(id) {
|
||||
if pb.PackID().Equal(id) {
|
||||
pbs = append(pbs, pb)
|
||||
}
|
||||
}
|
||||
@@ -401,7 +402,7 @@ func TestIndexPacks(t *testing.T) {
|
||||
|
||||
for i := 0; i < 20; i++ {
|
||||
packID := restic.NewRandomID()
|
||||
idx.StorePack(packID, restic.Blobs{
|
||||
idx.StorePack(packID, pack.Blobs{
|
||||
{
|
||||
BlobHandle: restic.NewRandomBlobHandle(),
|
||||
Offset: 0,
|
||||
@@ -433,12 +434,12 @@ func createRandomIndex(rng *rand.Rand, packfiles int) (idx *index.Index, lookupB
|
||||
// create index with given number of pack files
|
||||
for i := 0; i < packfiles; i++ {
|
||||
packID := NewRandomTestID(rng)
|
||||
var blobs restic.Blobs
|
||||
var blobs pack.Blobs
|
||||
offset := 0
|
||||
for offset < maxPackSize {
|
||||
size := 2000 + rng.Intn(4*1024*1024)
|
||||
id := NewRandomTestID(rng)
|
||||
blobs = append(blobs, restic.Blob{
|
||||
blobs = append(blobs, pack.Blob{
|
||||
BlobHandle: restic.BlobHandle{
|
||||
Type: restic.DataBlob,
|
||||
ID: id,
|
||||
@@ -482,7 +483,7 @@ func BenchmarkIndexHasKnown(b *testing.B) {
|
||||
idx, _ := createRandomIndex(rand.New(rand.NewSource(0)), 200000)
|
||||
handles := make([]restic.BlobHandle, 0, 100000)
|
||||
for handle := range idx.Values() {
|
||||
handles = append(handles, handle.BlobHandle)
|
||||
handles = append(handles, handle.Handle())
|
||||
if len(handles) == cap(handles) {
|
||||
break
|
||||
}
|
||||
@@ -517,14 +518,14 @@ func BenchmarkIndexAllocParallel(b *testing.B) {
|
||||
}
|
||||
|
||||
func TestIndexHas(t *testing.T) {
|
||||
tests := []restic.PackedBlob{}
|
||||
tests := []*pack.PackedBlob{}
|
||||
|
||||
idx := index.NewIndex()
|
||||
|
||||
// create 50 packs with 20 blobs each
|
||||
for i := 0; i < 50; i++ {
|
||||
packID := restic.NewRandomID()
|
||||
var blobs restic.Blobs
|
||||
var blobs pack.Blobs
|
||||
|
||||
pos := uint(0)
|
||||
for j := 0; j < 20; j++ {
|
||||
@@ -534,14 +535,14 @@ func TestIndexHas(t *testing.T) {
|
||||
// test a mix of compressed and uncompressed packs
|
||||
uncompressedLength = 2 * length
|
||||
}
|
||||
pb := restic.PackedBlob{
|
||||
Blob: restic.Blob{
|
||||
pb := &pack.PackedBlob{
|
||||
Pack: packID,
|
||||
Blob: pack.Blob{
|
||||
BlobHandle: restic.NewRandomBlobHandle(),
|
||||
Offset: pos,
|
||||
Length: length,
|
||||
UncompressedLength: uncompressedLength,
|
||||
},
|
||||
PackID: packID,
|
||||
}
|
||||
blobs = append(blobs, pb.Blob)
|
||||
tests = append(tests, pb)
|
||||
@@ -551,11 +552,11 @@ func TestIndexHas(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, testBlob := range tests {
|
||||
rtest.Assert(t, idx.Has(testBlob.BlobHandle), "Index reports not having data blob added to it")
|
||||
rtest.Assert(t, idx.Has(testBlob.Handle()), "Index reports not having data blob added to it")
|
||||
}
|
||||
|
||||
rtest.Assert(t, !idx.Has(restic.NewRandomBlobHandle()), "Index reports having a data blob not added to it")
|
||||
rtest.Assert(t, !idx.Has(restic.BlobHandle{ID: tests[0].ID, Type: restic.TreeBlob}), "Index reports having a tree blob added to it with the same id as a data blob")
|
||||
rtest.Assert(t, !idx.Has(restic.BlobHandle{ID: tests[0].Handle().ID, Type: restic.TreeBlob}), "Index reports having a tree blob added to it with the same id as a data blob")
|
||||
}
|
||||
|
||||
func TestMixedEachByPack(t *testing.T) {
|
||||
@@ -566,7 +567,7 @@ func TestMixedEachByPack(t *testing.T) {
|
||||
for i := 0; i < 50; i++ {
|
||||
packID := restic.NewRandomID()
|
||||
expected[packID] = 1
|
||||
blobs := restic.Blobs{
|
||||
blobs := pack.Blobs{
|
||||
{
|
||||
BlobHandle: restic.BlobHandle{Type: restic.DataBlob, ID: restic.NewRandomID()},
|
||||
Offset: 0,
|
||||
@@ -608,7 +609,7 @@ func TestEachByPackIgnoes(t *testing.T) {
|
||||
} else {
|
||||
expected[packID] = 1
|
||||
}
|
||||
blobs := restic.Blobs{
|
||||
blobs := pack.Blobs{
|
||||
{
|
||||
BlobHandle: restic.BlobHandle{Type: restic.DataBlob, ID: restic.NewRandomID()},
|
||||
Offset: 0,
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/restic/restic/internal/debug"
|
||||
"github.com/restic/restic/internal/repository/pack"
|
||||
"github.com/restic/restic/internal/restic"
|
||||
"github.com/restic/restic/internal/ui/progress"
|
||||
"golang.org/x/sync/errgroup"
|
||||
@@ -39,10 +40,11 @@ func (mi *MasterIndex) clearPendingBlobs() {
|
||||
}
|
||||
|
||||
// Lookup queries all known Indexes for the ID and returns all matches.
|
||||
func (mi *MasterIndex) Lookup(bh restic.BlobHandle) (pbs []restic.PackedBlob) {
|
||||
func (mi *MasterIndex) Lookup(bh restic.BlobHandle) []*pack.PackedBlob {
|
||||
mi.idxMutex.RLock()
|
||||
defer mi.idxMutex.RUnlock()
|
||||
|
||||
var pbs []*pack.PackedBlob
|
||||
for _, idx := range mi.idx {
|
||||
pbs = idx.Lookup(bh, pbs)
|
||||
}
|
||||
@@ -145,12 +147,12 @@ func (mi *MasterIndex) Insert(idx *Index) {
|
||||
}
|
||||
|
||||
// StorePack remembers the id and pack in the index.
|
||||
func (mi *MasterIndex) StorePack(ctx context.Context, id restic.ID, blobs restic.Blobs, r restic.SaverUnpacked[restic.FileType]) error {
|
||||
func (mi *MasterIndex) StorePack(ctx context.Context, id restic.ID, blobs pack.Blobs, r restic.SaverUnpacked[restic.FileType]) error {
|
||||
mi.storePack(id, blobs)
|
||||
return mi.saveFullIndex(ctx, r)
|
||||
}
|
||||
|
||||
func (mi *MasterIndex) storePack(id restic.ID, blobs restic.Blobs) {
|
||||
func (mi *MasterIndex) storePack(id restic.ID, blobs pack.Blobs) {
|
||||
mi.idxMutex.Lock()
|
||||
defer mi.idxMutex.Unlock()
|
||||
|
||||
@@ -218,8 +220,8 @@ func (mi *MasterIndex) finalizeFullIndexes() []*Index {
|
||||
|
||||
// Values returns an iterator over all blobs known to the index. This blocks any
|
||||
// modification of the index.
|
||||
func (mi *MasterIndex) Values() iter.Seq[restic.PackedBlob] {
|
||||
return func(yield func(restic.PackedBlob) bool) {
|
||||
func (mi *MasterIndex) Values() iter.Seq[*pack.PackedBlob] {
|
||||
return func(yield func(*pack.PackedBlob) bool) {
|
||||
mi.idxMutex.RLock()
|
||||
defer mi.idxMutex.RUnlock()
|
||||
|
||||
@@ -663,13 +665,13 @@ func (mi *MasterIndex) saveFullIndex(ctx context.Context, r restic.SaverUnpacked
|
||||
}
|
||||
|
||||
// ListPacks returns the blobs of the specified pack files grouped by pack file.
|
||||
func (mi *MasterIndex) ListPacks(ctx context.Context, packs restic.IDSet) <-chan restic.PackBlobs {
|
||||
out := make(chan restic.PackBlobs)
|
||||
func (mi *MasterIndex) ListPacks(ctx context.Context, packs restic.IDSet) <-chan PackBlobs {
|
||||
out := make(chan PackBlobs)
|
||||
go func() {
|
||||
defer close(out)
|
||||
// only resort a part of the index to keep the memory overhead bounded
|
||||
for i := byte(0); i < 16; i++ {
|
||||
packBlob := make(map[restic.ID]restic.Blobs)
|
||||
packBlob := make(map[restic.ID]pack.Blobs)
|
||||
for pack := range packs {
|
||||
if pack[0]&0xf == i {
|
||||
packBlob[pack] = nil
|
||||
@@ -682,8 +684,9 @@ func (mi *MasterIndex) ListPacks(ctx context.Context, packs restic.IDSet) <-chan
|
||||
if ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
if packs.Has(pb.PackID) && pb.PackID[0]&0xf == i {
|
||||
packBlob[pb.PackID] = append(packBlob[pb.PackID], pb.Blob)
|
||||
packID := pb.PackID()
|
||||
if packs.Has(packID) && packID[0]&0xf == i {
|
||||
packBlob[packID] = append(packBlob[packID], pb.Blob)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -692,7 +695,7 @@ func (mi *MasterIndex) ListPacks(ctx context.Context, packs restic.IDSet) <-chan
|
||||
// allow GC
|
||||
packBlob[packID] = nil
|
||||
select {
|
||||
case out <- restic.PackBlobs{PackID: packID, Blobs: pbs}:
|
||||
case out <- PackBlobs{PackID: packID, Blobs: pbs}:
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/restic/restic/internal/data"
|
||||
"github.com/restic/restic/internal/repository"
|
||||
"github.com/restic/restic/internal/repository/index"
|
||||
"github.com/restic/restic/internal/repository/pack"
|
||||
"github.com/restic/restic/internal/restic"
|
||||
rtest "github.com/restic/restic/internal/test"
|
||||
"github.com/restic/restic/internal/ui/progress"
|
||||
@@ -24,18 +25,18 @@ func TestMasterIndex(t *testing.T) {
|
||||
bhInIdx2 := restic.NewRandomBlobHandle()
|
||||
bhInIdx12 := restic.BlobHandle{ID: restic.NewRandomID(), Type: restic.TreeBlob}
|
||||
|
||||
blob1 := restic.PackedBlob{
|
||||
PackID: restic.NewRandomID(),
|
||||
Blob: restic.Blob{
|
||||
blob1 := &pack.PackedBlob{
|
||||
Pack: restic.NewRandomID(),
|
||||
Blob: pack.Blob{
|
||||
BlobHandle: bhInIdx1,
|
||||
Length: uint(crypto.CiphertextLength(10)),
|
||||
Offset: 0,
|
||||
},
|
||||
}
|
||||
|
||||
blob2 := restic.PackedBlob{
|
||||
PackID: restic.NewRandomID(),
|
||||
Blob: restic.Blob{
|
||||
blob2 := &pack.PackedBlob{
|
||||
Pack: restic.NewRandomID(),
|
||||
Blob: pack.Blob{
|
||||
BlobHandle: bhInIdx2,
|
||||
Length: uint(crypto.CiphertextLength(100)),
|
||||
Offset: 10,
|
||||
@@ -43,9 +44,9 @@ func TestMasterIndex(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
blob12a := restic.PackedBlob{
|
||||
PackID: restic.NewRandomID(),
|
||||
Blob: restic.Blob{
|
||||
blob12a := &pack.PackedBlob{
|
||||
Pack: restic.NewRandomID(),
|
||||
Blob: pack.Blob{
|
||||
BlobHandle: bhInIdx12,
|
||||
Length: uint(crypto.CiphertextLength(123)),
|
||||
Offset: 110,
|
||||
@@ -53,9 +54,9 @@ func TestMasterIndex(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
blob12b := restic.PackedBlob{
|
||||
PackID: restic.NewRandomID(),
|
||||
Blob: restic.Blob{
|
||||
blob12b := &pack.PackedBlob{
|
||||
Pack: restic.NewRandomID(),
|
||||
Blob: pack.Blob{
|
||||
BlobHandle: bhInIdx12,
|
||||
Length: uint(crypto.CiphertextLength(123)),
|
||||
Offset: 50,
|
||||
@@ -64,12 +65,12 @@ func TestMasterIndex(t *testing.T) {
|
||||
}
|
||||
|
||||
idx1 := index.NewIndex()
|
||||
idx1.StorePack(blob1.PackID, restic.Blobs{blob1.Blob})
|
||||
idx1.StorePack(blob12a.PackID, restic.Blobs{blob12a.Blob})
|
||||
idx1.StorePack(blob1.PackID(), pack.Blobs{blob1.Blob})
|
||||
idx1.StorePack(blob12a.PackID(), pack.Blobs{blob12a.Blob})
|
||||
|
||||
idx2 := index.NewIndex()
|
||||
idx2.StorePack(blob2.PackID, restic.Blobs{blob2.Blob})
|
||||
idx2.StorePack(blob12b.PackID, restic.Blobs{blob12b.Blob})
|
||||
idx2.StorePack(blob2.PackID(), pack.Blobs{blob2.Blob})
|
||||
idx2.StorePack(blob12b.PackID(), pack.Blobs{blob12b.Blob})
|
||||
|
||||
mIdx := index.NewMasterIndex()
|
||||
mIdx.Insert(idx1)
|
||||
@@ -77,7 +78,7 @@ func TestMasterIndex(t *testing.T) {
|
||||
|
||||
// test idInIdx1
|
||||
blobs := mIdx.Lookup(bhInIdx1)
|
||||
rtest.Equals(t, []restic.PackedBlob{blob1}, blobs)
|
||||
rtest.Equals(t, []*pack.PackedBlob{blob1}, blobs)
|
||||
|
||||
size, found := mIdx.LookupSize(bhInIdx1)
|
||||
rtest.Equals(t, true, found)
|
||||
@@ -85,7 +86,7 @@ func TestMasterIndex(t *testing.T) {
|
||||
|
||||
// test idInIdx2
|
||||
blobs = mIdx.Lookup(bhInIdx2)
|
||||
rtest.Equals(t, []restic.PackedBlob{blob2}, blobs)
|
||||
rtest.Equals(t, []*pack.PackedBlob{blob2}, blobs)
|
||||
|
||||
size, found = mIdx.LookupSize(bhInIdx2)
|
||||
rtest.Equals(t, true, found)
|
||||
@@ -95,19 +96,20 @@ func TestMasterIndex(t *testing.T) {
|
||||
blobs = mIdx.Lookup(bhInIdx12)
|
||||
rtest.Equals(t, 2, len(blobs))
|
||||
|
||||
// test Lookup result for blob12a
|
||||
found = false
|
||||
if blobs[0] == blob12a || blobs[1] == blob12a {
|
||||
found = true
|
||||
containsPackedBlob := func(list []*pack.PackedBlob, want *pack.PackedBlob) bool {
|
||||
for _, b := range list {
|
||||
if b.PackID().Equal(want.PackID()) && b.Blob == want.Blob {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
rtest.Assert(t, found, "blob12a not found in result")
|
||||
|
||||
// test Lookup result for blob12a
|
||||
rtest.Assert(t, containsPackedBlob(blobs, blob12a), "blob12a not found in result")
|
||||
|
||||
// test Lookup result for blob12b
|
||||
found = false
|
||||
if blobs[0] == blob12b || blobs[1] == blob12b {
|
||||
found = true
|
||||
}
|
||||
rtest.Assert(t, found, "blob12a not found in result")
|
||||
rtest.Assert(t, containsPackedBlob(blobs, blob12b), "blob12b not found in result")
|
||||
|
||||
size, found = mIdx.LookupSize(bhInIdx12)
|
||||
rtest.Equals(t, true, found)
|
||||
@@ -135,7 +137,7 @@ func TestMasterIndexAddPending(t *testing.T) {
|
||||
// Test AddPending: try to add a blob that's already in an index (should return false)
|
||||
bhInIndex := restic.NewRandomBlobHandle()
|
||||
idx := index.NewIndex()
|
||||
idx.StorePack(restic.NewRandomID(), restic.Blobs{{
|
||||
idx.StorePack(restic.NewRandomID(), pack.Blobs{{
|
||||
BlobHandle: bhInIndex,
|
||||
Length: uint(crypto.CiphertextLength(50)),
|
||||
Offset: 0,
|
||||
@@ -173,14 +175,14 @@ func TestMasterIndexStorePackRemovesPending(t *testing.T) {
|
||||
|
||||
// Store the blob in a pack
|
||||
packID := restic.NewRandomID()
|
||||
blob := restic.Blob{
|
||||
blob := pack.Blob{
|
||||
BlobHandle: bhPending,
|
||||
Length: uint(crypto.CiphertextLength(75)),
|
||||
Offset: 0,
|
||||
UncompressedLength: 75,
|
||||
}
|
||||
saver := &noopSaver{}
|
||||
err := mIdx.StorePack(context.Background(), packID, restic.Blobs{blob}, saver)
|
||||
err := mIdx.StorePack(context.Background(), packID, pack.Blobs{blob}, saver)
|
||||
rtest.OK(t, err)
|
||||
|
||||
// Verify it is still found
|
||||
@@ -191,8 +193,8 @@ func TestMasterIndexStorePackRemovesPending(t *testing.T) {
|
||||
// Verify the blob can be found via Lookup from the index
|
||||
blobs := mIdx.Lookup(bhPending)
|
||||
rtest.Assert(t, len(blobs) > 0, "blob should be found in index after StorePack")
|
||||
rtest.Equals(t, packID, blobs[0].PackID)
|
||||
rtest.Equals(t, bhPending, blobs[0].BlobHandle)
|
||||
rtest.Equals(t, packID, blobs[0].PackID())
|
||||
rtest.Equals(t, bhPending, blobs[0].Handle())
|
||||
|
||||
// Test that adding the same blob as pending again fails (it's now in index)
|
||||
added = mIdx.AddPending(bhPending, 100)
|
||||
@@ -203,18 +205,18 @@ func TestMasterMergeFinalIndexes(t *testing.T) {
|
||||
bhInIdx1 := restic.NewRandomBlobHandle()
|
||||
bhInIdx2 := restic.NewRandomBlobHandle()
|
||||
|
||||
blob1 := restic.PackedBlob{
|
||||
PackID: restic.NewRandomID(),
|
||||
Blob: restic.Blob{
|
||||
blob1 := &pack.PackedBlob{
|
||||
Pack: restic.NewRandomID(),
|
||||
Blob: pack.Blob{
|
||||
BlobHandle: bhInIdx1,
|
||||
Length: 10,
|
||||
Offset: 0,
|
||||
},
|
||||
}
|
||||
|
||||
blob2 := restic.PackedBlob{
|
||||
PackID: restic.NewRandomID(),
|
||||
Blob: restic.Blob{
|
||||
blob2 := &pack.PackedBlob{
|
||||
Pack: restic.NewRandomID(),
|
||||
Blob: pack.Blob{
|
||||
BlobHandle: bhInIdx2,
|
||||
Length: 100,
|
||||
Offset: 10,
|
||||
@@ -223,10 +225,10 @@ func TestMasterMergeFinalIndexes(t *testing.T) {
|
||||
}
|
||||
|
||||
idx1 := index.NewIndex()
|
||||
idx1.StorePack(blob1.PackID, restic.Blobs{blob1.Blob})
|
||||
idx1.StorePack(blob1.PackID(), pack.Blobs{blob1.Blob})
|
||||
|
||||
idx2 := index.NewIndex()
|
||||
idx2.StorePack(blob2.PackID, restic.Blobs{blob2.Blob})
|
||||
idx2.StorePack(blob2.PackID(), pack.Blobs{blob2.Blob})
|
||||
|
||||
mIdx := index.NewMasterIndex()
|
||||
mIdx.Insert(idx1)
|
||||
@@ -246,18 +248,18 @@ func TestMasterMergeFinalIndexes(t *testing.T) {
|
||||
rtest.Equals(t, 2, blobCount)
|
||||
|
||||
blobs := mIdx.Lookup(bhInIdx1)
|
||||
rtest.Equals(t, []restic.PackedBlob{blob1}, blobs)
|
||||
rtest.Equals(t, []*pack.PackedBlob{blob1}, blobs)
|
||||
|
||||
blobs = mIdx.Lookup(bhInIdx2)
|
||||
rtest.Equals(t, []restic.PackedBlob{blob2}, blobs)
|
||||
rtest.Equals(t, []*pack.PackedBlob{blob2}, blobs)
|
||||
|
||||
blobs = mIdx.Lookup(restic.NewRandomBlobHandle())
|
||||
rtest.Assert(t, blobs == nil, "Expected no blobs when fetching with a random id")
|
||||
|
||||
// merge another index containing identical blobs
|
||||
idx3 := index.NewIndex()
|
||||
idx3.StorePack(blob1.PackID, restic.Blobs{blob1.Blob})
|
||||
idx3.StorePack(blob2.PackID, restic.Blobs{blob2.Blob})
|
||||
idx3.StorePack(blob1.PackID(), pack.Blobs{blob1.Blob})
|
||||
idx3.StorePack(blob2.PackID(), pack.Blobs{blob2.Blob})
|
||||
|
||||
mIdx.Insert(idx3)
|
||||
finalIndexes, idxCount, newIDs := index.TestMergeIndex(t, mIdx)
|
||||
@@ -268,10 +270,10 @@ func TestMasterMergeFinalIndexes(t *testing.T) {
|
||||
|
||||
// Index should have same entries as before!
|
||||
blobs = mIdx.Lookup(bhInIdx1)
|
||||
rtest.Equals(t, []restic.PackedBlob{blob1}, blobs)
|
||||
rtest.Equals(t, []*pack.PackedBlob{blob1}, blobs)
|
||||
|
||||
blobs = mIdx.Lookup(bhInIdx2)
|
||||
rtest.Equals(t, []restic.PackedBlob{blob2}, blobs)
|
||||
rtest.Equals(t, []*pack.PackedBlob{blob2}, blobs)
|
||||
|
||||
blobCount = 0
|
||||
for range mIdx.Values() {
|
||||
@@ -448,9 +450,9 @@ func testIndexSave(t *testing.T, version uint) {
|
||||
|
||||
idx := index.NewMasterIndex()
|
||||
rtest.OK(t, idx.Load(context.TODO(), repo, nil, nil))
|
||||
blobs := make(map[restic.PackedBlob]struct{})
|
||||
blobs := make(map[pack.PackedBlob]struct{})
|
||||
for pb := range idx.Values() {
|
||||
blobs[pb] = struct{}{}
|
||||
blobs[*pb] = struct{}{}
|
||||
}
|
||||
|
||||
rtest.OK(t, test.saver(idx, unpacked))
|
||||
@@ -458,8 +460,8 @@ func testIndexSave(t *testing.T, version uint) {
|
||||
rtest.OK(t, idx.Load(context.TODO(), repo, nil, nil))
|
||||
|
||||
for pb := range idx.Values() {
|
||||
if _, ok := blobs[pb]; ok {
|
||||
delete(blobs, pb)
|
||||
if _, ok := blobs[*pb]; ok {
|
||||
delete(blobs, *pb)
|
||||
} else {
|
||||
t.Fatalf("unexpected blobs %v", pb)
|
||||
}
|
||||
@@ -481,9 +483,9 @@ func testIndexSavePartial(t *testing.T, version uint) {
|
||||
// capture blob list before adding fourth snapshot
|
||||
idx := index.NewMasterIndex()
|
||||
rtest.OK(t, idx.Load(context.TODO(), repo, nil, nil))
|
||||
blobs := make(map[restic.PackedBlob]struct{})
|
||||
blobs := make(map[pack.PackedBlob]struct{})
|
||||
for pb := range idx.Values() {
|
||||
blobs[pb] = struct{}{}
|
||||
blobs[*pb] = struct{}{}
|
||||
}
|
||||
|
||||
// add+remove new snapshot and track its pack files
|
||||
@@ -502,8 +504,8 @@ func testIndexSavePartial(t *testing.T, version uint) {
|
||||
idx = index.NewMasterIndex()
|
||||
rtest.OK(t, idx.Load(context.TODO(), repo, nil, nil))
|
||||
for pb := range idx.Values() {
|
||||
if _, ok := blobs[pb]; ok {
|
||||
delete(blobs, pb)
|
||||
if _, ok := blobs[*pb]; ok {
|
||||
delete(blobs, *pb)
|
||||
} else {
|
||||
t.Fatalf("unexpected blobs %v", pb)
|
||||
}
|
||||
@@ -516,7 +518,7 @@ func testIndexSavePartial(t *testing.T, version uint) {
|
||||
checker.TestCheckRepo(t, repo)
|
||||
}
|
||||
|
||||
func loadIndexAndCollectBlobs(t *testing.T, repo restic.ListerLoaderUnpacked, master *index.MasterIndex, indexCount int) map[restic.PackedBlob]struct{} {
|
||||
func loadIndexAndCollectBlobs(t *testing.T, repo restic.ListerLoaderUnpacked, master *index.MasterIndex, indexCount int) map[pack.PackedBlob]struct{} {
|
||||
p := progress.NewCounter(0, 0, nil)
|
||||
rtest.OK(t, master.Load(context.TODO(), repo, p, nil))
|
||||
v, max := p.Get()
|
||||
@@ -525,10 +527,10 @@ func loadIndexAndCollectBlobs(t *testing.T, repo restic.ListerLoaderUnpacked, ma
|
||||
return collectBlobs(master)
|
||||
}
|
||||
|
||||
func collectBlobs(master *index.MasterIndex) map[restic.PackedBlob]struct{} {
|
||||
s := make(map[restic.PackedBlob]struct{})
|
||||
func collectBlobs(master *index.MasterIndex) map[pack.PackedBlob]struct{} {
|
||||
s := make(map[pack.PackedBlob]struct{})
|
||||
for pb := range master.Values() {
|
||||
s[pb] = struct{}{}
|
||||
s[*pb] = struct{}{}
|
||||
}
|
||||
return s
|
||||
}
|
||||
@@ -588,17 +590,17 @@ func TestRewriteOversizedIndex(t *testing.T) {
|
||||
return idx.Len(restic.DataBlob) > 2*fullIndexCount
|
||||
}
|
||||
|
||||
var blobs restic.Blobs
|
||||
var blobs pack.Blobs
|
||||
|
||||
// build oversized index
|
||||
idx := index.NewIndex()
|
||||
numPacks := 5
|
||||
for p := 0; p < numPacks; p++ {
|
||||
packID := restic.NewRandomID()
|
||||
packBlobs := make(restic.Blobs, 0, fullIndexCount)
|
||||
packBlobs := make(pack.Blobs, 0, fullIndexCount)
|
||||
|
||||
for i := 0; i < fullIndexCount; i++ {
|
||||
blob := restic.Blob{
|
||||
blob := pack.Blob{
|
||||
BlobHandle: restic.BlobHandle{
|
||||
Type: restic.DataBlob,
|
||||
ID: restic.NewRandomID(),
|
||||
@@ -645,17 +647,17 @@ func TestRewriteSplitPacks(t *testing.T) {
|
||||
bh2 := restic.NewRandomBlobHandle()
|
||||
bhOther := restic.NewRandomBlobHandle()
|
||||
|
||||
blob1 := restic.PackedBlob{
|
||||
PackID: restic.NewRandomID(),
|
||||
Blob: restic.Blob{
|
||||
blob1 := &pack.PackedBlob{
|
||||
Pack: restic.NewRandomID(),
|
||||
Blob: pack.Blob{
|
||||
BlobHandle: bh1,
|
||||
Length: uint(crypto.CiphertextLength(10)),
|
||||
Offset: 0,
|
||||
},
|
||||
}
|
||||
blob2 := restic.PackedBlob{
|
||||
PackID: blob1.PackID,
|
||||
Blob: restic.Blob{
|
||||
blob2 := &pack.PackedBlob{
|
||||
Pack: blob1.PackID(),
|
||||
Blob: pack.Blob{
|
||||
BlobHandle: bh2,
|
||||
Length: uint(crypto.CiphertextLength(100)),
|
||||
Offset: 10,
|
||||
@@ -663,9 +665,9 @@ func TestRewriteSplitPacks(t *testing.T) {
|
||||
},
|
||||
}
|
||||
// used to force index repacking
|
||||
blobOther := restic.PackedBlob{
|
||||
PackID: restic.NewRandomID(),
|
||||
Blob: restic.Blob{
|
||||
blobOther := &pack.PackedBlob{
|
||||
Pack: restic.NewRandomID(),
|
||||
Blob: pack.Blob{
|
||||
BlobHandle: bhOther,
|
||||
Length: uint(crypto.CiphertextLength(100)),
|
||||
Offset: 10,
|
||||
@@ -673,25 +675,25 @@ func TestRewriteSplitPacks(t *testing.T) {
|
||||
}
|
||||
|
||||
mi := index.NewMasterIndex()
|
||||
rtest.OK(t, mi.StorePack(context.TODO(), blob1.PackID, restic.Blobs{blob1.Blob}, unpacked))
|
||||
rtest.OK(t, mi.StorePack(context.TODO(), blobOther.PackID, restic.Blobs{blobOther.Blob}, unpacked))
|
||||
rtest.OK(t, mi.StorePack(context.TODO(), blob1.PackID(), pack.Blobs{blob1.Blob}, unpacked))
|
||||
rtest.OK(t, mi.StorePack(context.TODO(), blobOther.PackID(), pack.Blobs{blobOther.Blob}, unpacked))
|
||||
rtest.OK(t, mi.Flush(context.TODO(), unpacked))
|
||||
rtest.OK(t, mi.StorePack(context.TODO(), blob2.PackID, restic.Blobs{blob2.Blob}, unpacked))
|
||||
rtest.OK(t, mi.StorePack(context.TODO(), blobOther.PackID, restic.Blobs{blobOther.Blob}, unpacked))
|
||||
rtest.OK(t, mi.StorePack(context.TODO(), blob2.PackID(), pack.Blobs{blob2.Blob}, unpacked))
|
||||
rtest.OK(t, mi.StorePack(context.TODO(), blobOther.PackID(), pack.Blobs{blobOther.Blob}, unpacked))
|
||||
rtest.OK(t, mi.Flush(context.TODO(), unpacked))
|
||||
|
||||
rtest.OK(t, mi.Rewrite(context.TODO(), unpacked, restic.NewIDSet(blobOther.PackID), nil, nil, index.MasterIndexRewriteOpts{}))
|
||||
rtest.OK(t, mi.Rewrite(context.TODO(), unpacked, restic.NewIDSet(blobOther.PackID()), nil, nil, index.MasterIndexRewriteOpts{}))
|
||||
|
||||
mi = index.NewMasterIndex()
|
||||
rtest.OK(t, mi.Load(context.TODO(), repo, nil, nil))
|
||||
|
||||
// test that all blobs are still in the index
|
||||
for _, blob := range []restic.PackedBlob{blob1, blob2} {
|
||||
blobs := mi.Lookup(blob.BlobHandle)
|
||||
rtest.Equals(t, []restic.PackedBlob{blob}, blobs)
|
||||
for _, blob := range []*pack.PackedBlob{blob1, blob2} {
|
||||
blobs := mi.Lookup(blob.Handle())
|
||||
rtest.Equals(t, []*pack.PackedBlob{blob}, blobs)
|
||||
}
|
||||
|
||||
blobs := mi.Lookup(blobOther.BlobHandle)
|
||||
blobs := mi.Lookup(blobOther.Handle())
|
||||
rtest.Equals(t, nil, blobs)
|
||||
}
|
||||
|
||||
@@ -713,17 +715,17 @@ func TestRewriteFullPacks(t *testing.T) {
|
||||
packA := restic.NewRandomID()
|
||||
packB := restic.NewRandomID()
|
||||
|
||||
blobA := restic.PackedBlob{
|
||||
PackID: packA,
|
||||
Blob: restic.Blob{
|
||||
blobA := &pack.PackedBlob{
|
||||
Pack: packA,
|
||||
Blob: pack.Blob{
|
||||
BlobHandle: restic.NewRandomBlobHandle(),
|
||||
Length: uint(crypto.CiphertextLength(10)),
|
||||
Offset: 0,
|
||||
},
|
||||
}
|
||||
blobB := restic.PackedBlob{
|
||||
PackID: packB,
|
||||
Blob: restic.Blob{
|
||||
blobB := &pack.PackedBlob{
|
||||
Pack: packB,
|
||||
Blob: pack.Blob{
|
||||
BlobHandle: restic.NewRandomBlobHandle(),
|
||||
Length: uint(crypto.CiphertextLength(50)),
|
||||
Offset: 0,
|
||||
@@ -731,11 +733,11 @@ func TestRewriteFullPacks(t *testing.T) {
|
||||
}
|
||||
|
||||
mi := index.NewMasterIndex()
|
||||
rtest.OK(t, mi.StorePack(context.TODO(), packA, restic.Blobs{blobA.Blob}, unpacked))
|
||||
rtest.OK(t, mi.StorePack(context.TODO(), packA, pack.Blobs{blobA.Blob}, unpacked))
|
||||
rtest.OK(t, mi.Flush(context.TODO(), unpacked))
|
||||
rtest.OK(t, mi.StorePack(context.TODO(), packB, restic.Blobs{blobB.Blob}, unpacked))
|
||||
rtest.OK(t, mi.StorePack(context.TODO(), packB, pack.Blobs{blobB.Blob}, unpacked))
|
||||
rtest.OK(t, mi.Flush(context.TODO(), unpacked))
|
||||
rtest.OK(t, mi.StorePack(context.TODO(), packB, restic.Blobs{blobB.Blob}, unpacked))
|
||||
rtest.OK(t, mi.StorePack(context.TODO(), packB, pack.Blobs{blobB.Blob}, unpacked))
|
||||
rtest.OK(t, mi.Flush(context.TODO(), unpacked))
|
||||
|
||||
indexIDs := mi.IDs()
|
||||
@@ -750,6 +752,6 @@ func TestRewriteFullPacks(t *testing.T) {
|
||||
rtest.Equals(t, 2, len(afterRewrite))
|
||||
rtest.Equals(t, 2, len(afterRewrite.Intersect(indexIDs)))
|
||||
|
||||
rtest.Equals(t, []restic.PackedBlob{blobA}, mi2.Lookup(blobA.BlobHandle))
|
||||
rtest.Equals(t, []restic.PackedBlob{blobB}, mi2.Lookup(blobB.BlobHandle))
|
||||
rtest.Equals(t, []*pack.PackedBlob{blobA}, mi2.Lookup(blobA.Handle()))
|
||||
rtest.Equals(t, []*pack.PackedBlob{blobB}, mi2.Lookup(blobB.Handle()))
|
||||
}
|
||||
Reference in new issue
Block a user