From 153e2ba85919da899f182369a111188ce84d783c Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Fri, 20 Aug 2021 10:09:34 +0200 Subject: [PATCH] repository: Implement lisiting blobs per pack file --- internal/repository/master_index.go | 39 +++++++++++++++++++++++++++++ internal/restic/repository.go | 6 +++++ 2 files changed, 45 insertions(+) diff --git a/internal/repository/master_index.go b/internal/repository/master_index.go index 5e099a3a5..adc110df8 100644 --- a/internal/repository/master_index.go +++ b/internal/repository/master_index.go @@ -400,3 +400,42 @@ func (mi *MasterIndex) Save(ctx context.Context, repo restic.Repository, packBla return obsolete, err } + +// 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) + 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++ { + if ctx.Err() != nil { + return + } + + packBlob := make(map[restic.ID][]restic.Blob) + for pack := range packs { + if pack[0]&0xf == i { + packBlob[pack] = nil + } + } + if len(packBlob) == 0 { + continue + } + for pb := range mi.Each(ctx) { + if packs.Has(pb.PackID) && pb.PackID[0]&0xf == i { + packBlob[pb.PackID] = append(packBlob[pb.PackID], pb.Blob) + } + } + + // pass on packs + for packID, pbs := range packBlob { + select { + case out <- restic.PackBlobs{PackID: packID, Blobs: pbs}: + case <-ctx.Done(): + return + } + } + } + }() + return out +} diff --git a/internal/restic/repository.go b/internal/restic/repository.go index 38c611ce6..c2a6e9f74 100644 --- a/internal/restic/repository.go +++ b/internal/restic/repository.go @@ -60,6 +60,11 @@ type Lister interface { List(context.Context, FileType, func(FileInfo) error) error } +type PackBlobs struct { + PackID ID + Blobs []Blob +} + // MasterIndex keeps track of the blobs are stored within files. type MasterIndex interface { Has(BlobHandle) bool @@ -71,4 +76,5 @@ type MasterIndex interface { // the context is cancelled, the background goroutine terminates. This // blocks any modification of the index. Each(ctx context.Context) <-chan PackedBlob + ListPacks(ctx context.Context, packs IDSet) <-chan PackBlobs }