From 3063ad1d0539b5314b87d1b2c1126a0adc8cc249 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sun, 26 Jul 2015 22:04:03 +0200 Subject: [PATCH] Split id.go into several files --- backend/id.go | 30 ----------------------- backend/ids.go | 50 +++++++++++++++++++++++++++++++++++++ backend/ids_test.go | 57 +++++++++++++++++++++++++++++++++++++++++++ backend/idset.go | 30 +++++++++++++++++++++++ backend/idset_test.go | 34 ++++++++++++++++++++++++++ 5 files changed, 171 insertions(+), 30 deletions(-) create mode 100644 backend/ids.go create mode 100644 backend/ids_test.go create mode 100644 backend/idset.go create mode 100644 backend/idset_test.go diff --git a/backend/id.go b/backend/id.go index 71b810322..966cd7a4e 100644 --- a/backend/id.go +++ b/backend/id.go @@ -102,33 +102,3 @@ func (id *ID) UnmarshalJSON(b []byte) error { func IDFromData(d []byte) ID { return hashData(d) } - -type IDs []ID - -func (ids IDs) Len() int { - return len(ids) -} - -func (ids IDs) Less(i, j int) bool { - if len(ids[i]) < len(ids[j]) { - return true - } - - for k, b := range ids[i] { - if b == ids[j][k] { - continue - } - - if b < ids[j][k] { - return true - } else { - return false - } - } - - return false -} - -func (ids IDs) Swap(i, j int) { - ids[i], ids[j] = ids[j], ids[i] -} diff --git a/backend/ids.go b/backend/ids.go new file mode 100644 index 000000000..f2569f7e0 --- /dev/null +++ b/backend/ids.go @@ -0,0 +1,50 @@ +package backend + +// IDs is an ordered list of IDs that implements sort.Interface. +type IDs []ID + +func (ids IDs) Len() int { + return len(ids) +} + +func (ids IDs) Less(i, j int) bool { + if len(ids[i]) < len(ids[j]) { + return true + } + + for k, b := range ids[i] { + if b == ids[j][k] { + continue + } + + if b < ids[j][k] { + return true + } + + return false + } + + return false +} + +func (ids IDs) Swap(i, j int) { + ids[i], ids[j] = ids[j], ids[i] +} + +// Uniq returns list without duplicate IDs. The returned list retains the order +// of the original list so that the order of the first occurrence of each ID +// stays the same. +func (ids IDs) Uniq() (list IDs) { + seen := NewIDSet() + + for _, id := range ids { + if seen.Has(id) { + continue + } + + list = append(list, id) + seen.Insert(id) + } + + return list +} diff --git a/backend/ids_test.go b/backend/ids_test.go new file mode 100644 index 000000000..02647eba1 --- /dev/null +++ b/backend/ids_test.go @@ -0,0 +1,57 @@ +package backend_test + +import ( + "reflect" + "testing" + + "github.com/restic/restic/backend" +) + +var uniqTests = []struct { + before, after backend.IDs +}{ + { + backend.IDs{ + str2id("7bb086db0d06285d831485da8031281e28336a56baa313539eaea1c73a2a1a40"), + str2id("1285b30394f3b74693cc29a758d9624996ae643157776fce8154aabd2f01515f"), + str2id("7bb086db0d06285d831485da8031281e28336a56baa313539eaea1c73a2a1a40"), + }, + backend.IDs{ + str2id("7bb086db0d06285d831485da8031281e28336a56baa313539eaea1c73a2a1a40"), + str2id("1285b30394f3b74693cc29a758d9624996ae643157776fce8154aabd2f01515f"), + }, + }, + { + backend.IDs{ + str2id("1285b30394f3b74693cc29a758d9624996ae643157776fce8154aabd2f01515f"), + str2id("7bb086db0d06285d831485da8031281e28336a56baa313539eaea1c73a2a1a40"), + str2id("7bb086db0d06285d831485da8031281e28336a56baa313539eaea1c73a2a1a40"), + }, + backend.IDs{ + str2id("1285b30394f3b74693cc29a758d9624996ae643157776fce8154aabd2f01515f"), + str2id("7bb086db0d06285d831485da8031281e28336a56baa313539eaea1c73a2a1a40"), + }, + }, + { + backend.IDs{ + str2id("1285b30394f3b74693cc29a758d9624996ae643157776fce8154aabd2f01515f"), + str2id("f658198b405d7e80db5ace1980d125c8da62f636b586c46bf81dfb856a49d0c8"), + str2id("7bb086db0d06285d831485da8031281e28336a56baa313539eaea1c73a2a1a40"), + str2id("7bb086db0d06285d831485da8031281e28336a56baa313539eaea1c73a2a1a40"), + }, + backend.IDs{ + str2id("1285b30394f3b74693cc29a758d9624996ae643157776fce8154aabd2f01515f"), + str2id("f658198b405d7e80db5ace1980d125c8da62f636b586c46bf81dfb856a49d0c8"), + str2id("7bb086db0d06285d831485da8031281e28336a56baa313539eaea1c73a2a1a40"), + }, + }, +} + +func TestUniqIDs(t *testing.T) { + for i, test := range uniqTests { + uniq := test.before.Uniq() + if !reflect.DeepEqual(uniq, test.after) { + t.Errorf("uniqIDs() test %v failed\n wanted: %v\n got: %v", i, test.after, uniq) + } + } +} diff --git a/backend/idset.go b/backend/idset.go new file mode 100644 index 000000000..25543d8dd --- /dev/null +++ b/backend/idset.go @@ -0,0 +1,30 @@ +package backend + +// IDSet is a set of IDs. +type IDSet map[ID]struct{} + +// NewIDSet returns a new IDSet, populated with ids. +func NewIDSet(ids ...ID) IDSet { + m := make(IDSet) + for _, id := range ids { + m[id] = struct{}{} + } + + return m +} + +// Has returns true iff id is contained in the set. +func (s IDSet) Has(id ID) bool { + _, ok := s[id] + return ok +} + +// Insert adds id to the set. +func (s IDSet) Insert(id ID) { + s[id] = struct{}{} +} + +// Delete removes id from the set. +func (s IDSet) Delete(id ID) { + delete(s, id) +} diff --git a/backend/idset_test.go b/backend/idset_test.go new file mode 100644 index 000000000..7084c8abf --- /dev/null +++ b/backend/idset_test.go @@ -0,0 +1,34 @@ +package backend_test + +import ( + "testing" + + "github.com/restic/restic/backend" +) + +var idsetTests = []struct { + id backend.ID + seen bool +}{ + {str2id("7bb086db0d06285d831485da8031281e28336a56baa313539eaea1c73a2a1a40"), false}, + {str2id("1285b30394f3b74693cc29a758d9624996ae643157776fce8154aabd2f01515f"), false}, + {str2id("7bb086db0d06285d831485da8031281e28336a56baa313539eaea1c73a2a1a40"), true}, + {str2id("7bb086db0d06285d831485da8031281e28336a56baa313539eaea1c73a2a1a40"), true}, + {str2id("1285b30394f3b74693cc29a758d9624996ae643157776fce8154aabd2f01515f"), true}, + {str2id("f658198b405d7e80db5ace1980d125c8da62f636b586c46bf81dfb856a49d0c8"), false}, + {str2id("7bb086db0d06285d831485da8031281e28336a56baa313539eaea1c73a2a1a40"), true}, + {str2id("1285b30394f3b74693cc29a758d9624996ae643157776fce8154aabd2f01515f"), true}, + {str2id("f658198b405d7e80db5ace1980d125c8da62f636b586c46bf81dfb856a49d0c8"), true}, + {str2id("7bb086db0d06285d831485da8031281e28336a56baa313539eaea1c73a2a1a40"), true}, +} + +func TestIDSet(t *testing.T) { + set := backend.NewIDSet() + for i, test := range idsetTests { + seen := set.Has(test.id) + if seen != test.seen { + t.Errorf("IDSet test %v failed: wanted %v, got %v", i, test.seen, seen) + } + set.Insert(test.id) + } +}