github.com/mckael/restic@v0.8.3/internal/restic/backend_find.go (about) 1 package restic 2 3 import ( 4 "context" 5 6 "github.com/restic/restic/internal/errors" 7 ) 8 9 // ErrNoIDPrefixFound is returned by Find() when no ID for the given prefix 10 // could be found. 11 var ErrNoIDPrefixFound = errors.New("no ID found") 12 13 // ErrMultipleIDMatches is returned by Find() when multiple IDs with the given 14 // prefix are found. 15 var ErrMultipleIDMatches = errors.New("multiple IDs with prefix found") 16 17 // Find loads the list of all files of type t and searches for names which 18 // start with prefix. If none is found, nil and ErrNoIDPrefixFound is returned. 19 // If more than one is found, nil and ErrMultipleIDMatches is returned. 20 func Find(be Lister, t FileType, prefix string) (string, error) { 21 match := "" 22 23 ctx, cancel := context.WithCancel(context.TODO()) 24 defer cancel() 25 26 err := be.List(ctx, t, func(fi FileInfo) error { 27 if prefix == fi.Name[:len(prefix)] { 28 if match == "" { 29 match = fi.Name 30 } else { 31 return ErrMultipleIDMatches 32 } 33 } 34 35 return nil 36 }) 37 38 if err != nil { 39 return "", err 40 } 41 42 if match != "" { 43 return match, nil 44 } 45 46 return "", ErrNoIDPrefixFound 47 } 48 49 const minPrefixLength = 8 50 51 // PrefixLength returns the number of bytes required so that all prefixes of 52 // all names of type t are unique. 53 func PrefixLength(be Lister, t FileType) (int, error) { 54 // load all IDs of the given type 55 list := make([]string, 0, 100) 56 57 ctx, cancel := context.WithCancel(context.TODO()) 58 defer cancel() 59 60 err := be.List(ctx, t, func(fi FileInfo) error { 61 list = append(list, fi.Name) 62 return nil 63 }) 64 65 if err != nil { 66 return 0, err 67 } 68 69 // select prefixes of length l, test if the last one is the same as the current one 70 id := ID{} 71 outer: 72 for l := minPrefixLength; l < len(id); l++ { 73 var last string 74 75 for _, name := range list { 76 if last == name[:l] { 77 continue outer 78 } 79 last = name[:l] 80 } 81 82 return l, nil 83 } 84 85 return len(id), nil 86 }