forked from TrueCloudLab/restic
index: reduce size of compressed indexes
use the same index size for compressed and uncompressed indexes. Otherwise, decoding the index of a compressed repository requires significantly more memory.
This commit is contained in:
parent
77873f5a9d
commit
462b82a060
5 changed files with 10 additions and 30 deletions
|
@ -68,7 +68,7 @@ func TestRebuildIndexAlwaysFull(t *testing.T) {
|
|||
defer func() {
|
||||
index.IndexFull = indexFull
|
||||
}()
|
||||
index.IndexFull = func(*index.Index, bool) bool { return true }
|
||||
index.IndexFull = func(*index.Index) bool { return true }
|
||||
testRebuildIndex(t, nil)
|
||||
}
|
||||
|
||||
|
|
|
@ -91,12 +91,11 @@ func (idx *Index) Final() bool {
|
|||
|
||||
const (
|
||||
indexMaxBlobs = 50000
|
||||
indexMaxBlobsCompressed = 3 * indexMaxBlobs
|
||||
indexMaxAge = 10 * time.Minute
|
||||
)
|
||||
|
||||
// IndexFull returns true iff the index is "full enough" to be saved as a preliminary index.
|
||||
var IndexFull = func(idx *Index, compress bool) bool {
|
||||
var IndexFull = func(idx *Index) bool {
|
||||
idx.m.RLock()
|
||||
defer idx.m.RUnlock()
|
||||
|
||||
|
@ -107,18 +106,12 @@ var IndexFull = func(idx *Index, compress bool) bool {
|
|||
blobs += idx.byType[typ].len()
|
||||
}
|
||||
age := time.Since(idx.created)
|
||||
var maxBlobs uint
|
||||
if compress {
|
||||
maxBlobs = indexMaxBlobsCompressed
|
||||
} else {
|
||||
maxBlobs = indexMaxBlobs
|
||||
}
|
||||
|
||||
switch {
|
||||
case age >= indexMaxAge:
|
||||
debug.Log("index %p is old enough", idx, age)
|
||||
return true
|
||||
case blobs >= maxBlobs:
|
||||
case blobs >= indexMaxBlobs:
|
||||
debug.Log("index %p has %d blobs", idx, blobs)
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ type MasterIndex struct {
|
|||
idx []*Index
|
||||
pendingBlobs restic.BlobSet
|
||||
idxMutex sync.RWMutex
|
||||
compress bool
|
||||
}
|
||||
|
||||
// NewMasterIndex creates a new master index.
|
||||
|
@ -33,10 +32,6 @@ func (mi *MasterIndex) clear() {
|
|||
mi.idx[0].Finalize()
|
||||
}
|
||||
|
||||
func (mi *MasterIndex) MarkCompressed() {
|
||||
mi.compress = true
|
||||
}
|
||||
|
||||
// Lookup queries all known Indexes for the ID and returns all matches.
|
||||
func (mi *MasterIndex) Lookup(bh restic.BlobHandle) (pbs []restic.PackedBlob) {
|
||||
mi.idxMutex.RLock()
|
||||
|
@ -211,7 +206,7 @@ func (mi *MasterIndex) finalizeFullIndexes() []*Index {
|
|||
continue
|
||||
}
|
||||
|
||||
if IndexFull(idx, mi.compress) {
|
||||
if IndexFull(idx) {
|
||||
debug.Log("index %p is full", idx)
|
||||
idx.Finalize()
|
||||
list = append(list, idx)
|
||||
|
@ -417,7 +412,7 @@ func (mi *MasterIndex) Rewrite(ctx context.Context, repo restic.Unpacked, exclud
|
|||
newIndex := NewIndex()
|
||||
for task := range rewriteCh {
|
||||
// always rewrite indexes using the old format, that include a pack that must be removed or that are not full
|
||||
if !task.oldFormat && len(task.idx.Packs().Intersect(excludePacks)) == 0 && IndexFull(task.idx, mi.compress) {
|
||||
if !task.oldFormat && len(task.idx.Packs().Intersect(excludePacks)) == 0 && IndexFull(task.idx) {
|
||||
// make sure that each pack is only stored exactly once in the index
|
||||
excludePacks.Merge(task.idx.Packs())
|
||||
// index is already up to date
|
||||
|
@ -433,7 +428,7 @@ func (mi *MasterIndex) Rewrite(ctx context.Context, repo restic.Unpacked, exclud
|
|||
|
||||
for pbs := range task.idx.EachByPack(wgCtx, excludePacks) {
|
||||
newIndex.StorePack(pbs.PackID, pbs.Blobs)
|
||||
if IndexFull(newIndex, mi.compress) {
|
||||
if IndexFull(newIndex) {
|
||||
select {
|
||||
case saveCh <- newIndex:
|
||||
case <-wgCtx.Done():
|
||||
|
@ -527,7 +522,7 @@ func (mi *MasterIndex) SaveFallback(ctx context.Context, repo restic.SaverRemove
|
|||
for pbs := range idx.EachByPack(wgCtx, excludePacks) {
|
||||
newIndex.StorePack(pbs.PackID, pbs.Blobs)
|
||||
p.Add(1)
|
||||
if IndexFull(newIndex, mi.compress) {
|
||||
if IndexFull(newIndex) {
|
||||
select {
|
||||
case ch <- newIndex:
|
||||
case <-wgCtx.Done():
|
||||
|
|
|
@ -588,19 +588,11 @@ func (r *Repository) ListPacksFromIndex(ctx context.Context, packs restic.IDSet)
|
|||
// SetIndex instructs the repository to use the given index.
|
||||
func (r *Repository) SetIndex(i restic.MasterIndex) error {
|
||||
r.idx = i.(*index.MasterIndex)
|
||||
r.configureIndex()
|
||||
return r.prepareCache()
|
||||
}
|
||||
|
||||
func (r *Repository) clearIndex() {
|
||||
r.idx = index.NewMasterIndex()
|
||||
r.configureIndex()
|
||||
}
|
||||
|
||||
func (r *Repository) configureIndex() {
|
||||
if r.cfg.Version >= 2 {
|
||||
r.idx.MarkCompressed()
|
||||
}
|
||||
}
|
||||
|
||||
// LoadIndex loads all index files from the backend in parallel and stores them
|
||||
|
|
|
@ -376,7 +376,7 @@ func TestRepositoryIncrementalIndex(t *testing.T) {
|
|||
func testRepositoryIncrementalIndex(t *testing.T, version uint) {
|
||||
repo, _ := repository.TestRepositoryWithVersion(t, version)
|
||||
|
||||
index.IndexFull = func(*index.Index, bool) bool { return true }
|
||||
index.IndexFull = func(*index.Index) bool { return true }
|
||||
|
||||
// add a few rounds of packs
|
||||
for j := 0; j < 5; j++ {
|
||||
|
|
Loading…
Reference in a new issue