2016-08-14 15:59:20 +00:00
|
|
|
package list
|
2016-08-14 14:01:42 +00:00
|
|
|
|
|
|
|
import (
|
2017-06-04 09:16:55 +00:00
|
|
|
"context"
|
2017-07-23 12:21:03 +00:00
|
|
|
|
2017-07-24 15:42:25 +00:00
|
|
|
"github.com/restic/restic/internal/restic"
|
2017-07-23 12:21:03 +00:00
|
|
|
"github.com/restic/restic/internal/worker"
|
2016-08-14 14:01:42 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const listPackWorkers = 10
|
|
|
|
|
|
|
|
// Lister combines lists packs in a repo and blobs in a pack.
|
|
|
|
type Lister interface {
|
2018-01-21 16:25:36 +00:00
|
|
|
List(context.Context, restic.FileType, func(restic.ID, int64) error) error
|
2018-01-24 02:43:21 +00:00
|
|
|
ListPack(context.Context, restic.ID, int64) ([]restic.Blob, int64, error)
|
2016-08-14 14:01:42 +00:00
|
|
|
}
|
|
|
|
|
2016-08-14 15:59:20 +00:00
|
|
|
// Result is returned in the channel from LoadBlobsFromAllPacks.
|
|
|
|
type Result struct {
|
2016-08-31 18:58:57 +00:00
|
|
|
packID restic.ID
|
2016-08-14 14:11:59 +00:00
|
|
|
size int64
|
2016-08-31 18:58:57 +00:00
|
|
|
entries []restic.Blob
|
2016-08-14 14:11:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// PackID returns the pack ID of this result.
|
2016-08-31 18:58:57 +00:00
|
|
|
func (l Result) PackID() restic.ID {
|
2016-08-14 14:11:59 +00:00
|
|
|
return l.packID
|
|
|
|
}
|
|
|
|
|
2017-02-08 23:43:10 +00:00
|
|
|
// Size returns the size of the pack.
|
2016-08-14 15:59:20 +00:00
|
|
|
func (l Result) Size() int64 {
|
2016-08-14 14:11:59 +00:00
|
|
|
return l.size
|
|
|
|
}
|
|
|
|
|
|
|
|
// Entries returns a list of all blobs saved in the pack.
|
2016-08-31 18:58:57 +00:00
|
|
|
func (l Result) Entries() []restic.Blob {
|
2016-08-14 14:11:59 +00:00
|
|
|
return l.entries
|
2016-08-14 14:01:42 +00:00
|
|
|
}
|
|
|
|
|
2016-08-14 15:59:20 +00:00
|
|
|
// AllPacks sends the contents of all packs to ch.
|
2017-06-15 11:12:46 +00:00
|
|
|
func AllPacks(ctx context.Context, repo Lister, ignorePacks restic.IDSet, ch chan<- worker.Job) {
|
2018-01-24 02:43:21 +00:00
|
|
|
type fileInfo struct {
|
|
|
|
id restic.ID
|
|
|
|
size int64
|
|
|
|
}
|
|
|
|
|
2017-06-04 09:16:55 +00:00
|
|
|
f := func(ctx context.Context, job worker.Job) (interface{}, error) {
|
2018-01-24 02:43:21 +00:00
|
|
|
packInfo := job.Data.(fileInfo)
|
|
|
|
entries, size, err := repo.ListPack(ctx, packInfo.id, packInfo.size)
|
2016-08-14 14:01:42 +00:00
|
|
|
|
2016-08-14 15:59:20 +00:00
|
|
|
return Result{
|
2018-01-24 02:43:21 +00:00
|
|
|
packID: packInfo.id,
|
2016-08-14 14:11:59 +00:00
|
|
|
size: size,
|
|
|
|
entries: entries,
|
2016-08-14 14:01:42 +00:00
|
|
|
}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
jobCh := make(chan worker.Job)
|
2017-06-04 09:16:55 +00:00
|
|
|
wp := worker.New(ctx, listPackWorkers, f, jobCh, ch)
|
2016-08-14 14:01:42 +00:00
|
|
|
|
|
|
|
go func() {
|
|
|
|
defer close(jobCh)
|
2018-01-21 16:25:36 +00:00
|
|
|
|
|
|
|
_ = repo.List(ctx, restic.DataFile, func(id restic.ID, size int64) error {
|
2017-06-15 11:12:46 +00:00
|
|
|
if ignorePacks.Has(id) {
|
2018-01-21 16:25:36 +00:00
|
|
|
return nil
|
2017-06-15 11:12:46 +00:00
|
|
|
}
|
|
|
|
|
2016-08-14 14:01:42 +00:00
|
|
|
select {
|
2018-01-24 02:43:21 +00:00
|
|
|
case jobCh <- worker.Job{Data: fileInfo{id: id, size: size}, Result: Result{packID: id}}:
|
2017-06-04 09:16:55 +00:00
|
|
|
case <-ctx.Done():
|
2018-01-21 16:25:36 +00:00
|
|
|
return ctx.Err()
|
2016-08-14 14:01:42 +00:00
|
|
|
}
|
2018-01-21 16:25:36 +00:00
|
|
|
return nil
|
|
|
|
})
|
2016-08-14 14:01:42 +00:00
|
|
|
}()
|
|
|
|
|
|
|
|
wp.Wait()
|
|
|
|
}
|