|
|
|
@ -26,8 +26,8 @@ func assertSetImplementation() {
|
|
|
|
|
|
|
|
|
|
// Set holds elements in go's native map
|
|
|
|
|
type Set struct {
|
|
|
|
|
items map[interface{}]struct{}
|
|
|
|
|
list *doublylinkedlist.List
|
|
|
|
|
table map[interface{}]struct{}
|
|
|
|
|
ordering *doublylinkedlist.List
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var itemExists = struct{}{}
|
|
|
|
@ -35,8 +35,8 @@ var itemExists = struct{}{}
|
|
|
|
|
// New instantiates a new empty set and adds the passed values, if any, to the set
|
|
|
|
|
func New(values ...interface{}) *Set {
|
|
|
|
|
set := &Set{
|
|
|
|
|
items: make(map[interface{}]struct{}),
|
|
|
|
|
list: doublylinkedlist.New(),
|
|
|
|
|
table: make(map[interface{}]struct{}),
|
|
|
|
|
ordering: doublylinkedlist.New(),
|
|
|
|
|
}
|
|
|
|
|
if len(values) > 0 {
|
|
|
|
|
set.Add(values...)
|
|
|
|
@ -48,13 +48,10 @@ func New(values ...interface{}) *Set {
|
|
|
|
|
// Note that insertion-order is not affected if an element is re-inserted into the set.
|
|
|
|
|
func (set *Set) Add(items ...interface{}) {
|
|
|
|
|
for _, item := range items {
|
|
|
|
|
|
|
|
|
|
if _, contains := set.items[item]; contains {
|
|
|
|
|
continue
|
|
|
|
|
if _, contains := set.table[item]; !contains {
|
|
|
|
|
set.table[item] = itemExists
|
|
|
|
|
set.ordering.Append(item)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set.items[item] = itemExists
|
|
|
|
|
set.list.Append(item)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -62,14 +59,11 @@ func (set *Set) Add(items ...interface{}) {
|
|
|
|
|
// Slow operation, worst-case O(n^2).
|
|
|
|
|
func (set *Set) Remove(items ...interface{}) {
|
|
|
|
|
for _, item := range items {
|
|
|
|
|
|
|
|
|
|
if _, contains := set.items[item]; !contains {
|
|
|
|
|
continue
|
|
|
|
|
if _, contains := set.table[item]; contains {
|
|
|
|
|
delete(set.table, item)
|
|
|
|
|
index := set.ordering.IndexOf(item)
|
|
|
|
|
set.ordering.Remove(index)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delete(set.items, item)
|
|
|
|
|
index := set.list.IndexOf(item)
|
|
|
|
|
set.list.Remove(index)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -78,7 +72,7 @@ func (set *Set) Remove(items ...interface{}) {
|
|
|
|
|
// Returns true if no arguments are passed at all, i.e. set is always superset of empty set.
|
|
|
|
|
func (set *Set) Contains(items ...interface{}) bool {
|
|
|
|
|
for _, item := range items {
|
|
|
|
|
if _, contains := set.items[item]; !contains {
|
|
|
|
|
if _, contains := set.table[item]; !contains {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -92,13 +86,13 @@ func (set *Set) Empty() bool {
|
|
|
|
|
|
|
|
|
|
// Size returns number of elements within the set.
|
|
|
|
|
func (set *Set) Size() int {
|
|
|
|
|
return set.list.Size()
|
|
|
|
|
return set.ordering.Size()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Clear clears all values in the set.
|
|
|
|
|
func (set *Set) Clear() {
|
|
|
|
|
set.items = make(map[interface{}]struct{})
|
|
|
|
|
set.list.Clear()
|
|
|
|
|
set.table = make(map[interface{}]struct{})
|
|
|
|
|
set.ordering.Clear()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Values returns all items in the set.
|
|
|
|
|