mirror of https://github.com/restic/restic.git
Add pack.Handle and pack.Handles
This commit is contained in:
parent
35e3762e37
commit
1b4b469440
|
@ -0,0 +1,109 @@
|
||||||
|
package pack
|
||||||
|
|
||||||
|
import "sort"
|
||||||
|
|
||||||
|
// BlobSet is a set of blobs.
|
||||||
|
type BlobSet map[Handle]struct{}
|
||||||
|
|
||||||
|
// NewBlobSet returns a new BlobSet, populated with ids.
|
||||||
|
func NewBlobSet(handles ...Handle) BlobSet {
|
||||||
|
m := make(BlobSet)
|
||||||
|
for _, h := range handles {
|
||||||
|
m[h] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
// Has returns true iff id is contained in the set.
|
||||||
|
func (s BlobSet) Has(h Handle) bool {
|
||||||
|
_, ok := s[h]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert adds id to the set.
|
||||||
|
func (s BlobSet) Insert(h Handle) {
|
||||||
|
s[h] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete removes id from the set.
|
||||||
|
func (s BlobSet) Delete(h Handle) {
|
||||||
|
delete(s, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equals returns true iff s equals other.
|
||||||
|
func (s BlobSet) Equals(other BlobSet) bool {
|
||||||
|
if len(s) != len(other) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for h := range s {
|
||||||
|
if _, ok := other[h]; !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge adds the blobs in other to the current set.
|
||||||
|
func (s BlobSet) Merge(other BlobSet) {
|
||||||
|
for h := range other {
|
||||||
|
s.Insert(h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intersect returns a new set containing the handles that are present in both sets.
|
||||||
|
func (s BlobSet) Intersect(other BlobSet) (result BlobSet) {
|
||||||
|
result = NewBlobSet()
|
||||||
|
|
||||||
|
set1 := s
|
||||||
|
set2 := other
|
||||||
|
|
||||||
|
// iterate over the smaller set
|
||||||
|
if len(set2) < len(set1) {
|
||||||
|
set1, set2 = set2, set1
|
||||||
|
}
|
||||||
|
|
||||||
|
for h := range set1 {
|
||||||
|
if set2.Has(h) {
|
||||||
|
result.Insert(h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sub returns a new set containing all handles that are present in s but not in
|
||||||
|
// other.
|
||||||
|
func (s BlobSet) Sub(other BlobSet) (result BlobSet) {
|
||||||
|
result = NewBlobSet()
|
||||||
|
for h := range s {
|
||||||
|
if !other.Has(h) {
|
||||||
|
result.Insert(h)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// List returns a slice of all Handles in the set.
|
||||||
|
func (s BlobSet) List() Handles {
|
||||||
|
list := make(Handles, 0, len(s))
|
||||||
|
for h := range s {
|
||||||
|
list = append(list, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Sort(list)
|
||||||
|
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s BlobSet) String() string {
|
||||||
|
str := s.List().String()
|
||||||
|
if len(str) < 2 {
|
||||||
|
return "{}"
|
||||||
|
}
|
||||||
|
|
||||||
|
return "{" + str[1:len(str)-1] + "}"
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package pack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"restic/backend"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Handle identifies a blob of a given type.
|
||||||
|
type Handle struct {
|
||||||
|
ID backend.ID
|
||||||
|
Type BlobType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h Handle) String() string {
|
||||||
|
name := h.ID.String()
|
||||||
|
if len(name) > 10 {
|
||||||
|
name = name[:10]
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("<%s/%s>", h.Type, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handles is an ordered list of Handles that implements sort.Interface.
|
||||||
|
type Handles []Handle
|
||||||
|
|
||||||
|
func (h Handles) Len() int {
|
||||||
|
return len(h)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h Handles) Less(i, j int) bool {
|
||||||
|
if h[i].Type != h[j].Type {
|
||||||
|
return h[i].Type < h[j].Type
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, b := range h[i].ID {
|
||||||
|
if b == h[j].ID[k] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if b < h[j].ID[k] {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h Handles) Swap(i, j int) {
|
||||||
|
h[i], h[j] = h[j], h[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h Handles) String() string {
|
||||||
|
elements := make([]string, 0, len(h))
|
||||||
|
for _, e := range h {
|
||||||
|
elements = append(elements, e.String())
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%v", elements)
|
||||||
|
}
|
Loading…
Reference in New Issue