2022-06-12 12:43:43 +00:00
|
|
|
package index
|
2020-12-18 18:37:08 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2021-08-07 22:38:17 +00:00
|
|
|
"runtime"
|
2020-12-18 18:37:08 +00:00
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/restic/restic/internal/restic"
|
|
|
|
)
|
|
|
|
|
|
|
|
// ForAllIndexes loads all index files in parallel and calls the given callback.
|
|
|
|
// It is guaranteed that the function is not run concurrently. If the callback
|
|
|
|
// returns an error, this function is cancelled and also returns that error.
|
2024-05-19 18:36:16 +00:00
|
|
|
func ForAllIndexes(ctx context.Context, lister restic.Lister, repo restic.LoaderUnpacked,
|
2024-08-26 18:07:21 +00:00
|
|
|
fn func(id restic.ID, index *Index, err error) error) error {
|
2020-12-18 18:37:08 +00:00
|
|
|
|
2022-10-15 15:24:47 +00:00
|
|
|
// decoding an index can take quite some time such that this can be both CPU- or IO-bound
|
|
|
|
// as the whole index is kept in memory anyways, a few workers too much don't matter
|
|
|
|
workerCount := repo.Connections() + uint(runtime.GOMAXPROCS(0))
|
2020-12-18 18:37:08 +00:00
|
|
|
|
|
|
|
var m sync.Mutex
|
2024-02-10 21:58:10 +00:00
|
|
|
return restic.ParallelList(ctx, lister, restic.IndexFile, workerCount, func(ctx context.Context, id restic.ID, _ int64) error {
|
2022-10-15 15:24:47 +00:00
|
|
|
var err error
|
|
|
|
var idx *Index
|
|
|
|
|
2023-01-27 14:01:54 +00:00
|
|
|
buf, err := repo.LoadUnpacked(ctx, restic.IndexFile, id)
|
2022-10-15 15:24:47 +00:00
|
|
|
if err == nil {
|
2024-08-26 18:07:21 +00:00
|
|
|
idx, err = DecodeIndex(buf, id)
|
2020-12-18 18:37:08 +00:00
|
|
|
}
|
|
|
|
|
2022-10-15 15:24:47 +00:00
|
|
|
m.Lock()
|
|
|
|
defer m.Unlock()
|
2024-08-26 18:07:21 +00:00
|
|
|
return fn(id, idx, err)
|
2022-10-15 15:24:47 +00:00
|
|
|
})
|
2020-12-18 18:37:08 +00:00
|
|
|
}
|