1package multihash
2
3// Set is a set of Multihashes, holding one copy per Multihash.
4type Set struct {
5	set map[string]struct{}
6}
7
8// NewSet creates a new set correctly initialized.
9func NewSet() *Set {
10	return &Set{
11		set: make(map[string]struct{}),
12	}
13}
14
15// Add adds a new multihash to the set.
16func (s *Set) Add(m Multihash) {
17	s.set[string(m)] = struct{}{}
18}
19
20// Len returns the number of elements in the set.
21func (s *Set) Len() int {
22	return len(s.set)
23}
24
25// Has returns true if the element is in the set.
26func (s *Set) Has(m Multihash) bool {
27	_, ok := s.set[string(m)]
28	return ok
29}
30
31// Visit adds a multihash only if it is not in the set already.  Returns true
32// if the multihash was added (was not in the set before).
33func (s *Set) Visit(m Multihash) bool {
34	_, ok := s.set[string(m)]
35	if !ok {
36		s.set[string(m)] = struct{}{}
37		return true
38	}
39	return false
40}
41
42// ForEach runs f(m) with each multihash in the set. If returns immediately if
43// f(m) returns an error.
44func (s *Set) ForEach(f func(m Multihash) error) error {
45	for elem := range s.set {
46		mh := Multihash(elem)
47		if err := f(mh); err != nil {
48			return err
49		}
50	}
51	return nil
52}
53
54// Remove removes an element from the set.
55func (s *Set) Remove(m Multihash) {
56	delete(s.set, string(m))
57}
58
59// All returns a slice with all the elements in the set.
60func (s *Set) All() []Multihash {
61	out := make([]Multihash, 0, len(s.set))
62	for m := range s.set {
63		out = append(out, Multihash(m))
64	}
65	return out
66}
67