| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | package repository_test | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2020-08-04 16:42:38 +02:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2020-07-05 08:37:34 +02:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 	"math/rand" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							| 
									
										
										
										
											2020-10-10 07:42:22 +02:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 07:42:22 +02:00
										 |  |  | 	"github.com/restic/restic/internal/checker" | 
					
						
							| 
									
										
										
										
											2022-06-12 14:48:30 +02:00
										 |  |  | 	"github.com/restic/restic/internal/crypto" | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 	"github.com/restic/restic/internal/repository" | 
					
						
							|  |  |  | 	"github.com/restic/restic/internal/restic" | 
					
						
							|  |  |  | 	rtest "github.com/restic/restic/internal/test" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | func TestMasterIndex(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	bhInIdx1 := restic.NewRandomBlobHandle() | 
					
						
							|  |  |  | 	bhInIdx2 := restic.NewRandomBlobHandle() | 
					
						
							|  |  |  | 	bhInIdx12 := restic.BlobHandle{ID: restic.NewRandomID(), Type: restic.TreeBlob} | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	blob1 := restic.PackedBlob{ | 
					
						
							|  |  |  | 		PackID: restic.NewRandomID(), | 
					
						
							|  |  |  | 		Blob: restic.Blob{ | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 			BlobHandle: bhInIdx1, | 
					
						
							| 
									
										
										
										
											2022-06-12 14:48:30 +02:00
										 |  |  | 			Length:     uint(crypto.CiphertextLength(10)), | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 			Offset:     0, | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	blob2 := restic.PackedBlob{ | 
					
						
							|  |  |  | 		PackID: restic.NewRandomID(), | 
					
						
							|  |  |  | 		Blob: restic.Blob{ | 
					
						
							| 
									
										
										
										
											2022-04-29 23:17:01 +02:00
										 |  |  | 			BlobHandle:         bhInIdx2, | 
					
						
							| 
									
										
										
										
											2022-06-12 14:48:30 +02:00
										 |  |  | 			Length:             uint(crypto.CiphertextLength(100)), | 
					
						
							| 
									
										
										
										
											2022-04-29 23:17:01 +02:00
										 |  |  | 			Offset:             10, | 
					
						
							|  |  |  | 			UncompressedLength: 200, | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 	blob12a := restic.PackedBlob{ | 
					
						
							|  |  |  | 		PackID: restic.NewRandomID(), | 
					
						
							|  |  |  | 		Blob: restic.Blob{ | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 			BlobHandle: bhInIdx12, | 
					
						
							| 
									
										
										
										
											2022-06-12 14:48:30 +02:00
										 |  |  | 			Length:     uint(crypto.CiphertextLength(123)), | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 			Offset:     110, | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	blob12b := restic.PackedBlob{ | 
					
						
							|  |  |  | 		PackID: restic.NewRandomID(), | 
					
						
							|  |  |  | 		Blob: restic.Blob{ | 
					
						
							| 
									
										
										
										
											2022-04-29 23:17:01 +02:00
										 |  |  | 			BlobHandle:         bhInIdx12, | 
					
						
							| 
									
										
										
										
											2022-06-12 14:48:30 +02:00
										 |  |  | 			Length:             uint(crypto.CiphertextLength(123)), | 
					
						
							| 
									
										
										
										
											2022-04-29 23:17:01 +02:00
										 |  |  | 			Offset:             50, | 
					
						
							|  |  |  | 			UncompressedLength: 80, | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 	idx1 := repository.NewIndex() | 
					
						
							| 
									
										
										
										
											2022-05-26 13:41:06 +02:00
										 |  |  | 	idx1.StorePack(blob1.PackID, []restic.Blob{blob1.Blob}) | 
					
						
							|  |  |  | 	idx1.StorePack(blob12a.PackID, []restic.Blob{blob12a.Blob}) | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	idx2 := repository.NewIndex() | 
					
						
							| 
									
										
										
										
											2022-05-26 13:41:06 +02:00
										 |  |  | 	idx2.StorePack(blob2.PackID, []restic.Blob{blob2.Blob}) | 
					
						
							|  |  |  | 	idx2.StorePack(blob12b.PackID, []restic.Blob{blob12b.Blob}) | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	mIdx := repository.NewMasterIndex() | 
					
						
							|  |  |  | 	mIdx.Insert(idx1) | 
					
						
							|  |  |  | 	mIdx.Insert(idx2) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 	// test idInIdx1 | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	found := mIdx.Has(bhInIdx1) | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 	rtest.Equals(t, true, found) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	blobs := mIdx.Lookup(bhInIdx1) | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 	rtest.Equals(t, []restic.PackedBlob{blob1}, blobs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	size, found := mIdx.LookupSize(bhInIdx1) | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 	rtest.Equals(t, true, found) | 
					
						
							|  |  |  | 	rtest.Equals(t, uint(10), size) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// test idInIdx2 | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	found = mIdx.Has(bhInIdx2) | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 	rtest.Equals(t, true, found) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	blobs = mIdx.Lookup(bhInIdx2) | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 	rtest.Equals(t, []restic.PackedBlob{blob2}, blobs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	size, found = mIdx.LookupSize(bhInIdx2) | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 	rtest.Equals(t, true, found) | 
					
						
							| 
									
										
										
										
											2022-04-29 23:17:01 +02:00
										 |  |  | 	rtest.Equals(t, uint(200), size) | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// test idInIdx12 | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	found = mIdx.Has(bhInIdx12) | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 	rtest.Equals(t, true, found) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	blobs = mIdx.Lookup(bhInIdx12) | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 	rtest.Equals(t, 2, len(blobs)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// test Lookup result for blob12a | 
					
						
							|  |  |  | 	found = false | 
					
						
							|  |  |  | 	if blobs[0] == blob12a || blobs[1] == blob12a { | 
					
						
							|  |  |  | 		found = true | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	rtest.Assert(t, found, "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") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	size, found = mIdx.LookupSize(bhInIdx12) | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 	rtest.Equals(t, true, found) | 
					
						
							|  |  |  | 	rtest.Equals(t, uint(123), size) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// test not in index | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	found = mIdx.Has(restic.BlobHandle{ID: restic.NewRandomID(), Type: restic.TreeBlob}) | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 	rtest.Assert(t, !found, "Expected no blobs when fetching with a random id") | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	blobs = mIdx.Lookup(restic.NewRandomBlobHandle()) | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 	rtest.Assert(t, blobs == nil, "Expected no blobs when fetching with a random id") | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	_, found = mIdx.LookupSize(restic.NewRandomBlobHandle()) | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 	rtest.Assert(t, !found, "Expected no blobs when fetching with a random id") | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-18 20:53:51 +02:00
										 |  |  | func TestMasterMergeFinalIndexes(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	bhInIdx1 := restic.NewRandomBlobHandle() | 
					
						
							|  |  |  | 	bhInIdx2 := restic.NewRandomBlobHandle() | 
					
						
							| 
									
										
										
										
											2020-07-18 20:53:51 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	blob1 := restic.PackedBlob{ | 
					
						
							|  |  |  | 		PackID: restic.NewRandomID(), | 
					
						
							|  |  |  | 		Blob: restic.Blob{ | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 			BlobHandle: bhInIdx1, | 
					
						
							|  |  |  | 			Length:     10, | 
					
						
							|  |  |  | 			Offset:     0, | 
					
						
							| 
									
										
										
										
											2020-07-18 20:53:51 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	blob2 := restic.PackedBlob{ | 
					
						
							|  |  |  | 		PackID: restic.NewRandomID(), | 
					
						
							|  |  |  | 		Blob: restic.Blob{ | 
					
						
							| 
									
										
										
										
											2022-04-29 23:17:01 +02:00
										 |  |  | 			BlobHandle:         bhInIdx2, | 
					
						
							|  |  |  | 			Length:             100, | 
					
						
							|  |  |  | 			Offset:             10, | 
					
						
							|  |  |  | 			UncompressedLength: 200, | 
					
						
							| 
									
										
										
										
											2020-07-18 20:53:51 +02:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	idx1 := repository.NewIndex() | 
					
						
							| 
									
										
										
										
											2022-05-26 13:41:06 +02:00
										 |  |  | 	idx1.StorePack(blob1.PackID, []restic.Blob{blob1.Blob}) | 
					
						
							| 
									
										
										
										
											2020-07-18 20:53:51 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	idx2 := repository.NewIndex() | 
					
						
							| 
									
										
										
										
											2022-05-26 13:41:06 +02:00
										 |  |  | 	idx2.StorePack(blob2.PackID, []restic.Blob{blob2.Blob}) | 
					
						
							| 
									
										
										
										
											2020-07-18 20:53:51 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	mIdx := repository.NewMasterIndex() | 
					
						
							|  |  |  | 	mIdx.Insert(idx1) | 
					
						
							|  |  |  | 	mIdx.Insert(idx2) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-05 21:57:16 +02:00
										 |  |  | 	finalIndexes, idxCount := repository.TestMergeIndex(t, mIdx) | 
					
						
							| 
									
										
										
										
											2020-07-18 20:53:51 +02:00
										 |  |  | 	rtest.Equals(t, []*repository.Index{idx1, idx2}, finalIndexes) | 
					
						
							| 
									
										
										
										
											2022-06-05 21:57:16 +02:00
										 |  |  | 	rtest.Equals(t, 1, idxCount) | 
					
						
							| 
									
										
										
										
											2020-08-04 16:42:38 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	blobCount := 0 | 
					
						
							| 
									
										
										
										
											2022-08-19 20:04:39 +02:00
										 |  |  | 	mIdx.Each(context.TODO(), func(pb restic.PackedBlob) { | 
					
						
							| 
									
										
										
										
											2020-08-04 16:42:38 +02:00
										 |  |  | 		blobCount++ | 
					
						
							| 
									
										
										
										
											2022-08-19 20:04:39 +02:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2020-08-04 16:42:38 +02:00
										 |  |  | 	rtest.Equals(t, 2, blobCount) | 
					
						
							| 
									
										
										
										
											2020-07-18 20:53:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	blobs := mIdx.Lookup(bhInIdx1) | 
					
						
							| 
									
										
										
										
											2020-07-18 20:53:51 +02:00
										 |  |  | 	rtest.Equals(t, []restic.PackedBlob{blob1}, blobs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	blobs = mIdx.Lookup(bhInIdx2) | 
					
						
							| 
									
										
										
										
											2020-07-18 20:53:51 +02:00
										 |  |  | 	rtest.Equals(t, []restic.PackedBlob{blob2}, blobs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	blobs = mIdx.Lookup(restic.NewRandomBlobHandle()) | 
					
						
							| 
									
										
										
										
											2020-07-18 20:53:51 +02:00
										 |  |  | 	rtest.Assert(t, blobs == nil, "Expected no blobs when fetching with a random id") | 
					
						
							| 
									
										
										
										
											2020-08-04 16:42:38 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// merge another index containing identical blobs | 
					
						
							|  |  |  | 	idx3 := repository.NewIndex() | 
					
						
							| 
									
										
										
										
											2022-05-26 13:41:06 +02:00
										 |  |  | 	idx3.StorePack(blob1.PackID, []restic.Blob{blob1.Blob}) | 
					
						
							|  |  |  | 	idx3.StorePack(blob2.PackID, []restic.Blob{blob2.Blob}) | 
					
						
							| 
									
										
										
										
											2020-08-04 16:42:38 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	mIdx.Insert(idx3) | 
					
						
							| 
									
										
										
										
											2022-06-05 21:57:16 +02:00
										 |  |  | 	finalIndexes, idxCount = repository.TestMergeIndex(t, mIdx) | 
					
						
							| 
									
										
										
										
											2020-08-04 16:42:38 +02:00
										 |  |  | 	rtest.Equals(t, []*repository.Index{idx3}, finalIndexes) | 
					
						
							| 
									
										
										
										
											2022-06-05 21:57:16 +02:00
										 |  |  | 	rtest.Equals(t, 1, idxCount) | 
					
						
							| 
									
										
										
										
											2020-08-04 16:42:38 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Index should have same entries as before! | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	blobs = mIdx.Lookup(bhInIdx1) | 
					
						
							| 
									
										
										
										
											2020-08-04 16:42:38 +02:00
										 |  |  | 	rtest.Equals(t, []restic.PackedBlob{blob1}, blobs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	blobs = mIdx.Lookup(bhInIdx2) | 
					
						
							| 
									
										
										
										
											2020-08-04 16:42:38 +02:00
										 |  |  | 	rtest.Equals(t, []restic.PackedBlob{blob2}, blobs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	blobCount = 0 | 
					
						
							| 
									
										
										
										
											2022-08-19 20:04:39 +02:00
										 |  |  | 	mIdx.Each(context.TODO(), func(pb restic.PackedBlob) { | 
					
						
							| 
									
										
										
										
											2020-08-04 16:42:38 +02:00
										 |  |  | 		blobCount++ | 
					
						
							| 
									
										
										
										
											2022-08-19 20:04:39 +02:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2020-08-04 16:42:38 +02:00
										 |  |  | 	rtest.Equals(t, 2, blobCount) | 
					
						
							| 
									
										
										
										
											2020-07-18 20:53:51 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-30 16:35:05 +01:00
										 |  |  | func createRandomMasterIndex(t testing.TB, rng *rand.Rand, num, size int) (*repository.MasterIndex, restic.BlobHandle) { | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 	mIdx := repository.NewMasterIndex() | 
					
						
							| 
									
										
										
										
											2020-07-04 07:05:51 +02:00
										 |  |  | 	for i := 0; i < num-1; i++ { | 
					
						
							|  |  |  | 		idx, _ := createRandomIndex(rng, size) | 
					
						
							|  |  |  | 		mIdx.Insert(idx) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	idx1, lookupBh := createRandomIndex(rng, size) | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 	mIdx.Insert(idx1) | 
					
						
							| 
									
										
										
										
											2020-07-18 20:53:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-26 15:43:04 +02:00
										 |  |  | 	repository.TestMergeIndex(t, mIdx) | 
					
						
							| 
									
										
										
										
											2020-07-18 20:53:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	return mIdx, lookupBh | 
					
						
							| 
									
										
										
										
											2020-07-04 07:05:51 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-05 06:28:24 +02:00
										 |  |  | func BenchmarkMasterIndexAlloc(b *testing.B) { | 
					
						
							|  |  |  | 	rng := rand.New(rand.NewSource(0)) | 
					
						
							|  |  |  | 	b.ReportAllocs() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < b.N; i++ { | 
					
						
							| 
									
										
										
										
											2021-01-30 16:35:05 +01:00
										 |  |  | 		createRandomMasterIndex(b, rng, 10000, 5) | 
					
						
							| 
									
										
										
										
											2020-08-05 06:28:24 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-04 07:05:51 +02:00
										 |  |  | func BenchmarkMasterIndexLookupSingleIndex(b *testing.B) { | 
					
						
							| 
									
										
										
										
											2021-01-30 16:35:05 +01:00
										 |  |  | 	mIdx, lookupBh := createRandomMasterIndex(b, rand.New(rand.NewSource(0)), 1, 200000) | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	b.ResetTimer() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < b.N; i++ { | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 		mIdx.Lookup(lookupBh) | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func BenchmarkMasterIndexLookupMultipleIndex(b *testing.B) { | 
					
						
							| 
									
										
										
										
											2021-01-30 16:35:05 +01:00
										 |  |  | 	mIdx, lookupBh := createRandomMasterIndex(b, rand.New(rand.NewSource(0)), 100, 10000) | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	b.ResetTimer() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < b.N; i++ { | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 		mIdx.Lookup(lookupBh) | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func BenchmarkMasterIndexLookupSingleIndexUnknown(b *testing.B) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	lookupBh := restic.NewRandomBlobHandle() | 
					
						
							| 
									
										
										
										
											2021-01-30 16:35:05 +01:00
										 |  |  | 	mIdx, _ := createRandomMasterIndex(b, rand.New(rand.NewSource(0)), 1, 200000) | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	b.ResetTimer() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < b.N; i++ { | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 		mIdx.Lookup(lookupBh) | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func BenchmarkMasterIndexLookupMultipleIndexUnknown(b *testing.B) { | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 	lookupBh := restic.NewRandomBlobHandle() | 
					
						
							| 
									
										
										
										
											2021-01-30 16:35:05 +01:00
										 |  |  | 	mIdx, _ := createRandomMasterIndex(b, rand.New(rand.NewSource(0)), 100, 10000) | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	b.ResetTimer() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < b.N; i++ { | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 		mIdx.Lookup(lookupBh) | 
					
						
							| 
									
										
										
										
											2018-01-12 01:20:12 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-07-05 08:37:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | func BenchmarkMasterIndexLookupParallel(b *testing.B) { | 
					
						
							| 
									
										
										
										
											2020-07-04 07:05:51 +02:00
										 |  |  | 	for _, numindices := range []int{25, 50, 100} { | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 		var lookupBh restic.BlobHandle | 
					
						
							| 
									
										
										
										
											2020-07-05 08:37:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		b.StopTimer() | 
					
						
							|  |  |  | 		rng := rand.New(rand.NewSource(0)) | 
					
						
							| 
									
										
										
										
											2022-05-26 12:49:03 +02:00
										 |  |  | 		mIdx, lookupBh := createRandomMasterIndex(b, rng, numindices, 10000) | 
					
						
							| 
									
										
										
										
											2020-07-05 08:37:34 +02:00
										 |  |  | 		b.StartTimer() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		name := fmt.Sprintf("known,indices=%d", numindices) | 
					
						
							|  |  |  | 		b.Run(name, func(b *testing.B) { | 
					
						
							|  |  |  | 			b.RunParallel(func(pb *testing.PB) { | 
					
						
							|  |  |  | 				for pb.Next() { | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 					mIdx.Lookup(lookupBh) | 
					
						
							| 
									
										
										
										
											2020-07-05 08:37:34 +02:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 		lookupBh = restic.NewRandomBlobHandle() | 
					
						
							| 
									
										
										
										
											2020-07-05 08:37:34 +02:00
										 |  |  | 		name = fmt.Sprintf("unknown,indices=%d", numindices) | 
					
						
							|  |  |  | 		b.Run(name, func(b *testing.B) { | 
					
						
							|  |  |  | 			b.RunParallel(func(pb *testing.PB) { | 
					
						
							|  |  |  | 				for pb.Next() { | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 					mIdx.Lookup(lookupBh) | 
					
						
							| 
									
										
										
										
											2020-07-05 08:37:34 +02:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func BenchmarkMasterIndexLookupBlobSize(b *testing.B) { | 
					
						
							|  |  |  | 	rng := rand.New(rand.NewSource(0)) | 
					
						
							| 
									
										
										
										
											2021-01-30 16:35:05 +01:00
										 |  |  | 	mIdx, lookupBh := createRandomMasterIndex(b, rand.New(rng), 5, 200000) | 
					
						
							| 
									
										
										
										
											2020-07-05 08:37:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-14 13:26:10 +02:00
										 |  |  | 	b.ResetTimer() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < b.N; i++ { | 
					
						
							| 
									
										
										
										
											2020-11-05 22:18:00 +01:00
										 |  |  | 		mIdx.LookupSize(lookupBh) | 
					
						
							| 
									
										
										
										
											2020-07-05 08:37:34 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-10-10 07:42:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-11 00:24:39 +02:00
										 |  |  | func BenchmarkMasterIndexEach(b *testing.B) { | 
					
						
							|  |  |  | 	rng := rand.New(rand.NewSource(0)) | 
					
						
							|  |  |  | 	mIdx, _ := createRandomMasterIndex(b, rand.New(rng), 5, 200000) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	b.ResetTimer() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < b.N; i++ { | 
					
						
							|  |  |  | 		entries := 0 | 
					
						
							| 
									
										
										
										
											2022-08-19 20:04:39 +02:00
										 |  |  | 		mIdx.Each(context.TODO(), func(pb restic.PackedBlob) { | 
					
						
							| 
									
										
										
										
											2022-09-11 00:24:39 +02:00
										 |  |  | 			entries++ | 
					
						
							| 
									
										
										
										
											2022-08-19 20:04:39 +02:00
										 |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2022-09-11 00:24:39 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 07:42:22 +02:00
										 |  |  | var ( | 
					
						
							|  |  |  | 	snapshotTime = time.Unix(1470492820, 207401672) | 
					
						
							|  |  |  | 	depth        = 3 | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-29 23:16:16 +02:00
										 |  |  | func createFilledRepo(t testing.TB, snapshots int, dup float32, version uint) (restic.Repository, func()) { | 
					
						
							|  |  |  | 	repo, cleanup := repository.TestRepositoryWithVersion(t, version) | 
					
						
							| 
									
										
										
										
											2020-10-10 07:42:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < 3; i++ { | 
					
						
							|  |  |  | 		restic.TestCreateSnapshot(t, repo, snapshotTime.Add(time.Duration(i)*time.Second), depth, dup) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return repo, cleanup | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestIndexSave(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-04-29 23:16:16 +02:00
										 |  |  | 	repository.TestAllVersions(t, testIndexSave) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testIndexSave(t *testing.T, version uint) { | 
					
						
							|  |  |  | 	repo, cleanup := createFilledRepo(t, 3, 0, version) | 
					
						
							| 
									
										
										
										
											2020-10-10 07:42:22 +02:00
										 |  |  | 	defer cleanup() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-30 16:32:00 +01:00
										 |  |  | 	err := repo.LoadIndex(context.TODO()) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-10-10 07:42:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-26 12:49:03 +02:00
										 |  |  | 	obsoletes, err := repo.Index().Save(context.TODO(), repo, nil, nil, nil) | 
					
						
							| 
									
										
										
										
											2020-10-10 07:42:22 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("unable to save new index: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for id := range obsoletes { | 
					
						
							|  |  |  | 		t.Logf("remove index %v", id.Str()) | 
					
						
							|  |  |  | 		h := restic.Handle{Type: restic.IndexFile, Name: id.String()} | 
					
						
							|  |  |  | 		err = repo.Backend().Remove(context.TODO(), h) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Errorf("error removing index %v: %v", id, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-07 00:07:32 +01:00
										 |  |  | 	checker := checker.New(repo, false) | 
					
						
							| 
									
										
										
										
											2021-11-07 22:33:44 +01:00
										 |  |  | 	err = checker.LoadSnapshots(context.TODO()) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Error(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 07:42:22 +02:00
										 |  |  | 	hints, errs := checker.LoadIndex(context.TODO()) | 
					
						
							|  |  |  | 	for _, h := range hints { | 
					
						
							|  |  |  | 		t.Logf("hint: %v\n", h) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, err := range errs { | 
					
						
							|  |  |  | 		t.Errorf("checker found error: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx, cancel := context.WithCancel(context.TODO()) | 
					
						
							|  |  |  | 	defer cancel() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	errCh := make(chan error) | 
					
						
							| 
									
										
										
										
											2020-12-06 00:07:45 +01:00
										 |  |  | 	go checker.Structure(ctx, nil, errCh) | 
					
						
							| 
									
										
										
										
											2020-10-10 07:42:22 +02:00
										 |  |  | 	i := 0 | 
					
						
							|  |  |  | 	for err := range errCh { | 
					
						
							|  |  |  | 		t.Errorf("checker returned error: %v", err) | 
					
						
							|  |  |  | 		i++ | 
					
						
							|  |  |  | 		if i == 10 { | 
					
						
							|  |  |  | 			t.Errorf("more than 10 errors returned, skipping the rest") | 
					
						
							|  |  |  | 			cancel() | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |