repository: Use backend.ID to load index

This commit uses ParallelWorkFuncParseID() to load all indexes and
ignores file names with invalid format.

This fixes #475.
This commit is contained in:
Alexander Neumann 2016-02-24 22:41:32 +01:00
parent 77d85cee52
commit 4ae16d7661
7 changed files with 19 additions and 20 deletions

View file

@ -105,7 +105,7 @@ func (cmd CmdDump) DumpIndexes() error {
for id := range cmd.repo.List(backend.Index, done) { for id := range cmd.repo.List(backend.Index, done) {
fmt.Printf("index_id: %v\n", id) fmt.Printf("index_id: %v\n", id)
idx, err := repository.LoadIndex(cmd.repo, id.String()) idx, err := repository.LoadIndex(cmd.repo, id)
if err != nil { if err != nil {
return err return err
} }

View file

@ -71,7 +71,7 @@ func (cmd CmdRebuildIndex) RebuildIndex() error {
cmd.global.Printf(" loading index %v\n", i) cmd.global.Printf(" loading index %v\n", i)
debug.Log("RebuildIndex.RebuildIndex", "load index %v", indexID.Str()) debug.Log("RebuildIndex.RebuildIndex", "load index %v", indexID.Str())
idx, err := repository.LoadIndex(cmd.repo, indexID.String()) idx, err := repository.LoadIndex(cmd.repo, indexID)
if err != nil { if err != nil {
return err return err
} }

View file

@ -83,12 +83,12 @@ func (c *Checker) LoadIndex() (hints []error, errs []error) {
worker := func(id backend.ID, done <-chan struct{}) error { worker := func(id backend.ID, done <-chan struct{}) error {
debug.Log("LoadIndex", "worker got index %v", id) debug.Log("LoadIndex", "worker got index %v", id)
idx, err := repository.LoadIndexWithDecoder(c.repo, id.String(), repository.DecodeIndex) idx, err := repository.LoadIndexWithDecoder(c.repo, id, repository.DecodeIndex)
if err == repository.ErrOldIndexFormat { if err == repository.ErrOldIndexFormat {
debug.Log("LoadIndex", "index %v has old format", id.Str()) debug.Log("LoadIndex", "index %v has old format", id.Str())
hints = append(hints, ErrOldIndexFormat{id}) hints = append(hints, ErrOldIndexFormat{id})
idx, err = repository.LoadIndexWithDecoder(c.repo, id.String(), repository.DecodeOldIndex) idx, err = repository.LoadIndexWithDecoder(c.repo, id, repository.DecodeOldIndex)
} }
if err != nil { if err != nil {

View file

@ -557,15 +557,10 @@ func DecodeOldIndex(rd io.Reader) (idx *Index, err error) {
} }
// LoadIndexWithDecoder loads the index and decodes it with fn. // LoadIndexWithDecoder loads the index and decodes it with fn.
func LoadIndexWithDecoder(repo *Repository, id string, fn func(io.Reader) (*Index, error)) (idx *Index, err error) { func LoadIndexWithDecoder(repo *Repository, id backend.ID, fn func(io.Reader) (*Index, error)) (idx *Index, err error) {
debug.Log("LoadIndexWithDecoder", "Loading index %v", id[:8]) debug.Log("LoadIndexWithDecoder", "Loading index %v", id[:8])
idxID, err := backend.ParseID(id) buf, err := repo.LoadAndDecrypt(backend.Index, id)
if err != nil {
return nil, err
}
buf, err := repo.LoadAndDecrypt(backend.Index, idxID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -576,7 +571,7 @@ func LoadIndexWithDecoder(repo *Repository, id string, fn func(io.Reader) (*Inde
return nil, err return nil, err
} }
idx.id = idxID idx.id = id
return idx, nil return idx, nil
} }
@ -588,7 +583,7 @@ func LoadIndexWithDecoder(repo *Repository, id string, fn func(io.Reader) (*Inde
func ConvertIndex(repo *Repository, id backend.ID) (backend.ID, error) { func ConvertIndex(repo *Repository, id backend.ID) (backend.ID, error) {
debug.Log("ConvertIndex", "checking index %v", id.Str()) debug.Log("ConvertIndex", "checking index %v", id.Str())
idx, err := LoadIndexWithDecoder(repo, id.String(), DecodeOldIndex) idx, err := LoadIndexWithDecoder(repo, id, DecodeOldIndex)
if err != nil { if err != nil {
debug.Log("ConvertIndex", "LoadIndexWithDecoder(%v) returned error: %v", id.Str(), err) debug.Log("ConvertIndex", "LoadIndexWithDecoder(%v) returned error: %v", id.Str(), err)
return id, err return id, err

View file

@ -4,6 +4,7 @@ import (
"sync" "sync"
"restic/backend" "restic/backend"
"restic/debug"
) )
func closeIfOpen(ch chan struct{}) { func closeIfOpen(ch chan struct{}) {
@ -75,12 +76,14 @@ func FilesInParallel(repo backend.Lister, t backend.Type, n uint, f ParallelWork
} }
// ParallelWorkFuncParseID converts a function that takes a backend.ID to a // ParallelWorkFuncParseID converts a function that takes a backend.ID to a
// function that takes a string. // function that takes a string. Filenames that do not parse as a backend.ID
// are ignored.
func ParallelWorkFuncParseID(f ParallelIDWorkFunc) ParallelWorkFunc { func ParallelWorkFuncParseID(f ParallelIDWorkFunc) ParallelWorkFunc {
return func(s string, done <-chan struct{}) error { return func(s string, done <-chan struct{}) error {
id, err := backend.ParseID(s) id, err := backend.ParseID(s)
if err != nil { if err != nil {
return err debug.Log("repository.ParallelWorkFuncParseID", "invalid ID %q: %v", id, err)
return nil
} }
return f(id, done) return f(id, done)

View file

@ -366,7 +366,7 @@ func (r *Repository) LoadIndex() error {
errCh := make(chan error, 1) errCh := make(chan error, 1)
indexes := make(chan *Index) indexes := make(chan *Index)
worker := func(id string, done <-chan struct{}) error { worker := func(id backend.ID, done <-chan struct{}) error {
idx, err := LoadIndex(r, id) idx, err := LoadIndex(r, id)
if err != nil { if err != nil {
return err return err
@ -382,7 +382,8 @@ func (r *Repository) LoadIndex() error {
go func() { go func() {
defer close(indexes) defer close(indexes)
errCh <- FilesInParallel(r.be, backend.Index, loadIndexParallelism, worker) errCh <- FilesInParallel(r.be, backend.Index, loadIndexParallelism,
ParallelWorkFuncParseID(worker))
}() }()
for idx := range indexes { for idx := range indexes {
@ -397,14 +398,14 @@ func (r *Repository) LoadIndex() error {
} }
// LoadIndex loads the index id from backend and returns it. // LoadIndex loads the index id from backend and returns it.
func LoadIndex(repo *Repository, id string) (*Index, error) { func LoadIndex(repo *Repository, id backend.ID) (*Index, error) {
idx, err := LoadIndexWithDecoder(repo, id, DecodeIndex) idx, err := LoadIndexWithDecoder(repo, id, DecodeIndex)
if err == nil { if err == nil {
return idx, nil return idx, nil
} }
if err == ErrOldIndexFormat { if err == ErrOldIndexFormat {
fmt.Fprintf(os.Stderr, "index %v has old format\n", id[:10]) fmt.Fprintf(os.Stderr, "index %v has old format\n", id.Str())
return LoadIndexWithDecoder(repo, id, DecodeOldIndex) return LoadIndexWithDecoder(repo, id, DecodeOldIndex)
} }

View file

@ -292,7 +292,7 @@ func TestRepositoryIncrementalIndex(t *testing.T) {
packEntries := make(map[backend.ID]map[backend.ID]struct{}) packEntries := make(map[backend.ID]map[backend.ID]struct{})
for id := range repo.List(backend.Index, nil) { for id := range repo.List(backend.Index, nil) {
idx, err := repository.LoadIndex(repo, id.String()) idx, err := repository.LoadIndex(repo, id)
OK(t, err) OK(t, err)
for pb := range idx.Each(nil) { for pb := range idx.Each(nil) {