blob: dfdfed0c6775273f4d3935c01e94fb88d708b903 [file] [log] [blame]
// Copyright ©2014 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package set
import "gonum.org/v1/gonum/graph"
// Ints is a set of int identifiers.
type Ints map[int]struct{}
// The simple accessor methods for Ints are provided to allow ease of
// implementation change should the need arise.
// Add inserts an element into the set.
func (s Ints) Add(e int) {
s[e] = struct{}{}
}
// Has reports the existence of the element in the set.
func (s Ints) Has(e int) bool {
_, ok := s[e]
return ok
}
// Remove deletes the specified element from the set.
func (s Ints) Remove(e int) {
delete(s, e)
}
// Count reports the number of elements stored in the set.
func (s Ints) Count() int {
return len(s)
}
// IntsEqual reports set equality between the parameters. Sets are equal if
// and only if they have the same elements.
func IntsEqual(a, b Ints) bool {
if intsSame(a, b) {
return true
}
if len(a) != len(b) {
return false
}
for e := range a {
if _, ok := b[e]; !ok {
return false
}
}
return true
}
// Int64s is a set of int64 identifiers.
type Int64s map[int64]struct{}
// The simple accessor methods for Ints are provided to allow ease of
// implementation change should the need arise.
// Add inserts an element into the set.
func (s Int64s) Add(e int64) {
s[e] = struct{}{}
}
// Has reports the existence of the element in the set.
func (s Int64s) Has(e int64) bool {
_, ok := s[e]
return ok
}
// Remove deletes the specified element from the set.
func (s Int64s) Remove(e int64) {
delete(s, e)
}
// Count reports the number of elements stored in the set.
func (s Int64s) Count() int {
return len(s)
}
// Int64sEqual reports set equality between the parameters. Sets are equal if
// and only if they have the same elements.
func Int64sEqual(a, b Int64s) bool {
if int64sSame(a, b) {
return true
}
if len(a) != len(b) {
return false
}
for e := range a {
if _, ok := b[e]; !ok {
return false
}
}
return true
}
// Nodes is a set of nodes keyed in their integer identifiers.
type Nodes map[int64]graph.Node
// NewNodes returns a new Nodes.
func NewNodes() *Nodes {
s := make(Nodes)
return &s
}
// NewNodes returns a new Nodes with the given size hint, n.
func NewNodesSize(n int) *Nodes {
s := make(Nodes, n)
return &s
}
// The simple accessor methods for Nodes are provided to allow ease of
// implementation change should the need arise.
// Add inserts an element into the set.
func (s *Nodes) Add(n graph.Node) {
(*s)[n.ID()] = n
}
// Remove deletes the specified element from the set.
func (s *Nodes) Remove(e graph.Node) {
delete((*s), e.ID())
}
// Count returns the number of element in the set.
func (s *Nodes) Count() int {
return len(*s)
}
// Has reports the existence of the element in the set.
func (s *Nodes) Has(n graph.Node) bool {
_, ok := (*s)[n.ID()]
return ok
}
// clear clears the set, possibly using the same backing store.
func (s *Nodes) clear() {
if len(*s) != 0 {
*s = make(Nodes)
}
}
// Clone performs a perfect Clone from src to s returning the result.
// If s.Count() is not 0, a new Nodes is made and returned.
func (s *Nodes) Clone(src *Nodes) *Nodes {
if same(src, s) {
return s
}
if len(*s) != 0 {
*s = *NewNodesSize(len(*src))
}
// Work is reflected into s from dst.
dst := *s
for e, n := range *src {
dst[e] = n
}
return s
}
// Equal reports set equality between the parameters. Sets are equal if
// and only if they have the same elements.
func Equal(a, b *Nodes) bool {
if same(a, b) {
return true
}
_a := *a
_b := *b
if len(_a) != len(_b) {
return false
}
for e := range _a {
if _, ok := _b[e]; !ok {
return false
}
}
return true
}
// Union takes the union of a and b, and stores it in s.
//
// The union of two sets, a and b, is the set containing all the
// elements of each, for instance:
//
// {a,b,c} UNION {d,e,f} = {a,b,c,d,e,f}
//
// Since sets may not have repetition, unions of two sets that overlap
// do not contain repeat elements, that is:
//
// {a,b,c} UNION {b,c,d} = {a,b,c,d}
//
func (s *Nodes) Union(a, b *Nodes) *Nodes {
if same(a, b) {
return s.Clone(a)
}
if !same(a, s) && !same(b, s) {
s.clear()
}
// Work is reflected into s from dst.
dst := *s
if !same(s, a) {
for e, n := range *a {
dst[e] = n
}
}
if !same(s, b) {
for e, n := range *b {
dst[e] = n
}
}
return s
}
// Intersect takes the intersection of a and b, and stores it in s.
//
// The intersection of two sets, a and b, is the set containing all
// the elements shared between the two sets, for instance:
//
// {a,b,c} INTERSECT {b,c,d} = {b,c}
//
// The intersection between a set and itself is itself, and thus
// effectively a copy operation:
//
// {a,b,c} INTERSECT {a,b,c} = {a,b,c}
//
// The intersection between two sets that share no elements is the empty
// set:
//
// {a,b,c} INTERSECT {d,e,f} = {}
//
func (s *Nodes) Intersect(a, b *Nodes) *Nodes {
if same(a, b) {
return s.Clone(a)
}
var swap *Nodes
switch {
default:
s.clear()
if len(*a) > len(*b) {
a, b = b, a
}
// Work is reflected into s from dst.
dst := *s
_b := *b
for e, n := range *a {
if _, ok := _b[e]; ok {
dst[e] = n
}
}
return s
case same(a, s):
swap = b
case same(b, s):
swap = a
}
// Work is reflected into s from dst.
dst := *s
_swap := *swap
for e := range dst {
if _, ok := _swap[e]; !ok {
delete(dst, e)
}
}
return s
}