Browse code

libnetwork: Drop golang-set dependency

Replace the setmatrix package's use of golang-set with a small local
map-backed set implementation. The package already serializes access with
its own mutex, so the external dependency was not buying us much and made
this small utility harder to keep self-contained.

Removing it trims the dependency surface and avoids carrying an otherwise
single-purpose module for a narrow internal use case.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>

Paweł Gronowski authored on 2026/04/16 18:55:04
Showing 13 changed files
... ...
@@ -1,17 +1,57 @@
1 1
 package setmatrix
2 2
 
3 3
 import (
4
+	"fmt"
4 5
 	"sync"
5
-
6
-	mapset "github.com/deckarep/golang-set/v2"
7 6
 )
8 7
 
8
+type set[V comparable] map[V]struct{}
9
+
10
+func newSet[V comparable](value V) set[V] {
11
+	s := make(set[V], 1)
12
+	s[value] = struct{}{}
13
+	return s
14
+}
15
+
16
+func (s set[V]) Add(value V) bool {
17
+	if _, ok := s[value]; ok {
18
+		return false
19
+	}
20
+	s[value] = struct{}{}
21
+	return true
22
+}
23
+
24
+func (s set[V]) Contains(value V) bool {
25
+	_, ok := s[value]
26
+	return ok
27
+}
28
+
29
+func (s set[V]) Remove(value V) {
30
+	delete(s, value)
31
+}
32
+
33
+func (s set[V]) Cardinality() int {
34
+	return len(s)
35
+}
36
+
37
+func (s set[V]) ToSlice() []V {
38
+	values := make([]V, 0, len(s))
39
+	for value := range s {
40
+		values = append(values, value)
41
+	}
42
+	return values
43
+}
44
+
45
+func (s set[V]) String() string {
46
+	return fmt.Sprint(s.ToSlice())
47
+}
48
+
9 49
 // SetMatrix is a map of Sets.
10 50
 // The zero value is an empty set matrix ready to use.
11 51
 //
12 52
 // SetMatrix values are safe for concurrent use.
13 53
 type SetMatrix[K, V comparable] struct {
14
-	matrix map[K]mapset.Set[V]
54
+	matrix map[K]set[V]
15 55
 
16 56
 	mu sync.Mutex
17 57
 }
... ...
@@ -43,16 +83,16 @@ func (s *SetMatrix[K, V]) Contains(key K, value V) (containsElement, setExists b
43 43
 func (s *SetMatrix[K, V]) Insert(key K, value V) (inserted bool, cardinality int) {
44 44
 	s.mu.Lock()
45 45
 	defer s.mu.Unlock()
46
-	set, ok := s.matrix[key]
46
+	values, ok := s.matrix[key]
47 47
 	if !ok {
48 48
 		if s.matrix == nil {
49
-			s.matrix = make(map[K]mapset.Set[V])
49
+			s.matrix = make(map[K]set[V])
50 50
 		}
51
-		s.matrix[key] = mapset.NewThreadUnsafeSet(value)
51
+		s.matrix[key] = newSet(value)
52 52
 		return true, 1
53 53
 	}
54 54
 
55
-	return set.Add(value), set.Cardinality()
55
+	return values.Add(value), values.Cardinality()
56 56
 }
57 57
 
58 58
 // Remove removes the value in the set for a specific key.
... ...
@@ -32,7 +32,6 @@ require (
32 32
 	github.com/coreos/go-systemd/v22 v22.7.0
33 33
 	github.com/cpuguy83/tar2go v0.3.1
34 34
 	github.com/creack/pty v1.1.24
35
-	github.com/deckarep/golang-set/v2 v2.8.0
36 35
 	github.com/distribution/reference v0.6.0
37 36
 	github.com/docker/distribution v2.8.3+incompatible
38 37
 	github.com/docker/go-connections v0.7.0
... ...
@@ -216,8 +216,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
216 216
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
217 217
 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
218 218
 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
219
-github.com/deckarep/golang-set/v2 v2.8.0 h1:swm0rlPCmdWn9mESxKOjWk8hXSqoxOp+ZlfuyaAdFlQ=
220
-github.com/deckarep/golang-set/v2 v2.8.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
221 219
 github.com/digitorus/pkcs7 v0.0.0-20230713084857-e76b763bdc49/go.mod h1:SKVExuS+vpu2l9IoOc0RwqE7NYnb0JlcFHFnEJkVDzc=
222 220
 github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 h1:ge14PCmCvPjpMQMIAH7uKg0lrtNSOdpYsRXlwk3QbaE=
223 221
 github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352/go.mod h1:SKVExuS+vpu2l9IoOc0RwqE7NYnb0JlcFHFnEJkVDzc=
224 222
deleted file mode 100644
... ...
@@ -1,23 +0,0 @@
1
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
2
-*.o
3
-*.a
4
-*.so
5
-
6
-# Folders
7
-_obj
8
-_test
9
-
10
-# Architecture specific extensions/prefixes
11
-*.[568vq]
12
-[568vq].out
13
-
14
-*.cgo1.go
15
-*.cgo2.c
16
-_cgo_defun.c
17
-_cgo_gotypes.go
18
-_cgo_export.*
19
-
20
-_testmain.go
21
-
22
-*.exe
23
-.idea
24 1
\ No newline at end of file
25 2
deleted file mode 100644
... ...
@@ -1,22 +0,0 @@
1
-Open Source Initiative OSI - The MIT License (MIT):Licensing
2
-
3
-The MIT License (MIT)
4
-Copyright (c) 2013 - 2022 Ralph Caraveo (deckarep@gmail.com)
5
-
6
-Permission is hereby granted, free of charge, to any person obtaining a copy of
7
-this software and associated documentation files (the "Software"), to deal in
8
-the Software without restriction, including without limitation the rights to
9
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10
-of the Software, and to permit persons to whom the Software is furnished to do
11
-so, subject to the following conditions:
12
-
13
-The above copyright notice and this permission notice shall be included in all
14
-copies or substantial portions of the Software.
15
-
16
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
-SOFTWARE.
23 1
\ No newline at end of file
24 2
deleted file mode 100644
... ...
@@ -1,195 +0,0 @@
1
-![example workflow](https://github.com/deckarep/golang-set/actions/workflows/ci.yml/badge.svg)
2
-[![Go Report Card](https://goreportcard.com/badge/github.com/deckarep/golang-set/v2)](https://goreportcard.com/report/github.com/deckarep/golang-set/v2)
3
-[![GoDoc](https://godoc.org/github.com/deckarep/golang-set/v2?status.svg)](http://godoc.org/github.com/deckarep/golang-set/v2)
4
-
5
-# golang-set
6
-
7
-The missing `generic` set collection for the Go language.  Until Go has sets built-in...use this.
8
-
9
-## Psst
10
-* Hi there, 👋! Do you use or have interest in the [Zig programming language](https://ziglang.org/) created by Andrew Kelley? If so, the golang-set project has a new sibling project: [ziglang-set](https://github.com/deckarep/ziglang-set)! Come check it out!
11
-
12
-## Update 3/14/2025
13
-* Packaged version: `2.8.0` introduces support for true iterators for Go 1.23+. Please see [issue #141](https://github.com/deckarep/golang-set/issues/141)
14
-for further details on the implications of how iterations work between older Go versions vs newer Go versions. Additionally, this
15
-release has a minor unit-test spelling fix.
16
-
17
-## Update 12/3/2024
18
-* Packaged version: `2.7.0` fixes a long-standing bug with *JSON Unmarshaling*. A large refactor in the interest of performance
19
-introduced this bug and there was no way around it but to revert the code back to how it was previously. The performance
20
-difference was likely negligible to begin with. JSON Marshaling and Unmarshaling is now properly supported again without
21
-needing to do workarounds.
22
-
23
-## Update 3/5/2023
24
-* Packaged version: `2.2.0` release includes a refactor to minimize pointer indirection, better method documentation standards and a few constructor convenience methods to increase ergonomics when appending items `Append` or creating a new set from an exist `Map`.
25
-* supports `new generic` syntax
26
-* Go `1.18.0` or higher
27
-* Workflow tested on Go `1.20`
28
-
29
-![With Generics](new_improved.jpeg)
30
-
31
-Coming from Python one of the things I miss is the superbly wonderful set collection.  This is my attempt to mimic the primary features of the set collection from Python.
32
-You can of course argue that there is no need for a set in Go, otherwise the creators would have added one to the standard library.  To those I say simply ignore this repository and carry-on and to the rest that find this useful please contribute in helping me make it better by contributing with suggestions or PRs.
33
-
34
-## Install
35
-
36
-Use `go get` to install this package.
37
-
38
-```shell
39
-go get github.com/deckarep/golang-set/v2
40
-```
41
-
42
-## Features
43
-
44
-* *NEW* [Generics](https://go.dev/doc/tutorial/generics) based implementation (requires [Go 1.18](https://go.dev/blog/go1.18beta1) or higher)
45
-* One common *interface* to both implementations
46
-  * a **non threadsafe** implementation favoring *performance*
47
-  * a **threadsafe** implementation favoring *concurrent* use
48
-* Feature complete set implementation modeled after [Python's set implementation](https://docs.python.org/3/library/stdtypes.html#set).
49
-* Exhaustive unit-test and benchmark suite
50
-
51
-## Trusted by
52
-
53
-This package is trusted by many companies and thousands of open-source packages. Here are just a few sample users of this package.
54
-
55
-* Notable projects/companies using this package
56
-  * Ethereum
57
-  * Docker
58
-  * 1Password
59
-  * Hashicorp
60
-
61
-## Star History
62
-
63
-[![Star History Chart](https://api.star-history.com/svg?repos=deckarep/golang-set&type=Date)](https://star-history.com/#deckarep/golang-set&Date)
64
-
65
-
66
-## Usage
67
-
68
-The code below demonstrates how a Set collection can better manage data and actually minimize boilerplate and needless loops in code. This package now fully supports *generic* syntax so you are now able to instantiate a collection for any [comparable](https://flaviocopes.com/golang-comparing-values/) type object.
69
-
70
-What is considered comparable in Go? 
71
-* `Booleans`, `integers`, `strings`, `floats` or basically primitive types.
72
-* `Pointers`
73
-* `Arrays`
74
-* `Structs` if *all of their fields* are also comparable independently
75
-
76
-Using this library is as simple as creating either a threadsafe or non-threadsafe set and providing a `comparable` type for instantiation of the collection.
77
-
78
-```go
79
-// Syntax example, doesn't compile.
80
-mySet := mapset.NewSet[T]() // where T is some concrete comparable type.
81
-
82
-// Therefore this code creates an int set
83
-mySet := mapset.NewSet[int]()
84
-
85
-// Or perhaps you want a string set
86
-mySet := mapset.NewSet[string]()
87
-
88
-type myStruct struct {
89
-  name string
90
-  age uint8
91
-}
92
-
93
-// Alternatively a set of structs
94
-mySet := mapset.NewSet[myStruct]()
95
-
96
-// Lastly a set that can hold anything using the any or empty interface keyword: interface{}. This is effectively removes type safety.
97
-mySet := mapset.NewSet[any]()
98
-```
99
-
100
-## Comprehensive Example
101
-
102
-```go
103
-package main
104
-
105
-import (
106
-  "fmt"
107
-  mapset "github.com/deckarep/golang-set/v2"
108
-)
109
-
110
-func main() {
111
-  // Create a string-based set of required classes.
112
-  required := mapset.NewSet[string]()
113
-  required.Add("cooking")
114
-  required.Add("english")
115
-  required.Add("math")
116
-  required.Add("biology")
117
-
118
-  // Create a string-based set of science classes.
119
-  sciences := mapset.NewSet[string]()
120
-  sciences.Add("biology")
121
-  sciences.Add("chemistry")
122
-  
123
-  // Create a string-based set of electives.
124
-  electives := mapset.NewSet[string]()
125
-  electives.Add("welding")
126
-  electives.Add("music")
127
-  electives.Add("automotive")
128
-
129
-  // Create a string-based set of bonus programming classes.
130
-  bonus := mapset.NewSet[string]()
131
-  bonus.Add("beginner go")
132
-  bonus.Add("python for dummies")
133
-}
134
-```
135
-
136
-Create a set of all unique classes.
137
-Sets will *automatically* deduplicate the same data.
138
-
139
-```go
140
-  all := required
141
-    .Union(sciences)
142
-    .Union(electives)
143
-    .Union(bonus)
144
-  
145
-  fmt.Println(all)
146
-```
147
-
148
-Output:
149
-```sh
150
-Set{cooking, english, math, chemistry, welding, biology, music, automotive, beginner go, python for dummies}
151
-```
152
-
153
-Is cooking considered a science class?
154
-```go
155
-result := sciences.Contains("cooking")
156
-fmt.Println(result)
157
-```
158
-
159
-Output:
160
-```false
161
-false
162
-```
163
-
164
-Show me all classes that are not science classes, since I don't enjoy science.
165
-```go
166
-notScience := all.Difference(sciences)
167
-fmt.Println(notScience)
168
-```
169
-
170
-```sh
171
-Set{ music, automotive, beginner go, python for dummies, cooking, english, math, welding }
172
-```
173
-
174
-Which science classes are also required classes?
175
-```go
176
-reqScience := sciences.Intersect(required)
177
-```
178
-
179
-Output:
180
-```sh
181
-Set{biology}
182
-```
183
-
184
-How many bonus classes do you offer?
185
-```go
186
-fmt.Println(bonus.Cardinality())
187
-```
188
-Output:
189
-```sh
190
-2
191
-```
192
-
193
-Thanks for visiting!
194
-
195
--deckarep
196 1
deleted file mode 100644
... ...
@@ -1,58 +0,0 @@
1
-/*
2
-Open Source Initiative OSI - The MIT License (MIT):Licensing
3
-
4
-The MIT License (MIT)
5
-Copyright (c) 2013 - 2022 Ralph Caraveo (deckarep@gmail.com)
6
-
7
-Permission is hereby granted, free of charge, to any person obtaining a copy of
8
-this software and associated documentation files (the "Software"), to deal in
9
-the Software without restriction, including without limitation the rights to
10
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11
-of the Software, and to permit persons to whom the Software is furnished to do
12
-so, subject to the following conditions:
13
-
14
-The above copyright notice and this permission notice shall be included in all
15
-copies or substantial portions of the Software.
16
-
17
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
-SOFTWARE.
24
-*/
25
-
26
-package mapset
27
-
28
-// Iterator defines an iterator over a Set, its C channel can be used to range over the Set's
29
-// elements.
30
-type Iterator[T comparable] struct {
31
-	C    <-chan T
32
-	stop chan struct{}
33
-}
34
-
35
-// Stop stops the Iterator, no further elements will be received on C, C will be closed.
36
-func (i *Iterator[T]) Stop() {
37
-	// Allows for Stop() to be called multiple times
38
-	// (close() panics when called on already closed channel)
39
-	defer func() {
40
-		recover()
41
-	}()
42
-
43
-	close(i.stop)
44
-
45
-	// Exhaust any remaining elements.
46
-	for range i.C {
47
-	}
48
-}
49
-
50
-// newIterator returns a new Iterator instance together with its item and stop channels.
51
-func newIterator[T comparable]() (*Iterator[T], chan<- T, <-chan struct{}) {
52
-	itemChan := make(chan T)
53
-	stopChan := make(chan struct{})
54
-	return &Iterator[T]{
55
-		C:    itemChan,
56
-		stop: stopChan,
57
-	}, itemChan, stopChan
58
-}
59 1
deleted file mode 100644
60 2
Binary files a/vendor/github.com/deckarep/golang-set/v2/new_improved.jpeg and /dev/null differ
61 3
deleted file mode 100644
... ...
@@ -1,269 +0,0 @@
1
-/*
2
-Open Source Initiative OSI - The MIT License (MIT):Licensing
3
-
4
-The MIT License (MIT)
5
-Copyright (c) 2013 - 2022 Ralph Caraveo (deckarep@gmail.com)
6
-
7
-Permission is hereby granted, free of charge, to any person obtaining a copy of
8
-this software and associated documentation files (the "Software"), to deal in
9
-the Software without restriction, including without limitation the rights to
10
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11
-of the Software, and to permit persons to whom the Software is furnished to do
12
-so, subject to the following conditions:
13
-
14
-The above copyright notice and this permission notice shall be included in all
15
-copies or substantial portions of the Software.
16
-
17
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
-SOFTWARE.
24
-*/
25
-
26
-// Package mapset implements a simple and  set collection.
27
-// Items stored within it are unordered and unique. It supports
28
-// typical set operations: membership testing, intersection, union,
29
-// difference, symmetric difference and cloning.
30
-//
31
-// Package mapset provides two implementations of the Set
32
-// interface. The default implementation is safe for concurrent
33
-// access, but a non-thread-safe implementation is also provided for
34
-// programs that can benefit from the slight speed improvement and
35
-// that can enforce mutual exclusion through other means.
36
-package mapset
37
-
38
-// Set is the primary interface provided by the mapset package.  It
39
-// represents an unordered set of data and a large number of
40
-// operations that can be applied to that set.
41
-type Set[T comparable] interface {
42
-	// Add adds an element to the set. Returns whether
43
-	// the item was added.
44
-	Add(val T) bool
45
-
46
-	// Append multiple elements to the set. Returns
47
-	// the number of elements added.
48
-	Append(val ...T) int
49
-
50
-	// Cardinality returns the number of elements in the set.
51
-	Cardinality() int
52
-
53
-	// Clear removes all elements from the set, leaving
54
-	// the empty set.
55
-	Clear()
56
-
57
-	// Clone returns a clone of the set using the same
58
-	// implementation, duplicating all keys.
59
-	Clone() Set[T]
60
-
61
-	// Contains returns whether the given items
62
-	// are all in the set.
63
-	Contains(val ...T) bool
64
-
65
-	// ContainsOne returns whether the given item
66
-	// is in the set.
67
-	//
68
-	// Contains may cause the argument to escape to the heap.
69
-	// See: https://github.com/deckarep/golang-set/issues/118
70
-	ContainsOne(val T) bool
71
-
72
-	// ContainsAny returns whether at least one of the
73
-	// given items are in the set.
74
-	ContainsAny(val ...T) bool
75
-
76
-	// ContainsAnyElement returns whether at least one of the
77
-	// given element are in the set.
78
-	ContainsAnyElement(other Set[T]) bool
79
-
80
-	// Difference returns the difference between this set
81
-	// and other. The returned set will contain
82
-	// all elements of this set that are not also
83
-	// elements of other.
84
-	//
85
-	// Note that the argument to Difference
86
-	// must be of the same type as the receiver
87
-	// of the method. Otherwise, Difference will
88
-	// panic.
89
-	Difference(other Set[T]) Set[T]
90
-
91
-	// Equal determines if two sets are equal to each
92
-	// other. If they have the same cardinality
93
-	// and contain the same elements, they are
94
-	// considered equal. The order in which
95
-	// the elements were added is irrelevant.
96
-	//
97
-	// Note that the argument to Equal must be
98
-	// of the same type as the receiver of the
99
-	// method. Otherwise, Equal will panic.
100
-	Equal(other Set[T]) bool
101
-
102
-	// Intersect returns a new set containing only the elements
103
-	// that exist only in both sets.
104
-	//
105
-	// Note that the argument to Intersect
106
-	// must be of the same type as the receiver
107
-	// of the method. Otherwise, Intersect will
108
-	// panic.
109
-	Intersect(other Set[T]) Set[T]
110
-
111
-	// IsEmpty determines if there are elements in the set.
112
-	IsEmpty() bool
113
-
114
-	// IsProperSubset determines if every element in this set is in
115
-	// the other set but the two sets are not equal.
116
-	//
117
-	// Note that the argument to IsProperSubset
118
-	// must be of the same type as the receiver
119
-	// of the method. Otherwise, IsProperSubset
120
-	// will panic.
121
-	IsProperSubset(other Set[T]) bool
122
-
123
-	// IsProperSuperset determines if every element in the other set
124
-	// is in this set but the two sets are not
125
-	// equal.
126
-	//
127
-	// Note that the argument to IsSuperset
128
-	// must be of the same type as the receiver
129
-	// of the method. Otherwise, IsSuperset will
130
-	// panic.
131
-	IsProperSuperset(other Set[T]) bool
132
-
133
-	// IsSubset determines if every element in this set is in
134
-	// the other set.
135
-	//
136
-	// Note that the argument to IsSubset
137
-	// must be of the same type as the receiver
138
-	// of the method. Otherwise, IsSubset will
139
-	// panic.
140
-	IsSubset(other Set[T]) bool
141
-
142
-	// IsSuperset determines if every element in the other set
143
-	// is in this set.
144
-	//
145
-	// Note that the argument to IsSuperset
146
-	// must be of the same type as the receiver
147
-	// of the method. Otherwise, IsSuperset will
148
-	// panic.
149
-	IsSuperset(other Set[T]) bool
150
-
151
-	// Each iterates over elements and executes the passed func against each element.
152
-	// If passed func returns true, stop iteration at the time.
153
-	Each(func(T) bool)
154
-
155
-	// Iter returns a channel of elements that you can
156
-	// range over.
157
-	Iter() <-chan T
158
-
159
-	// Iterator returns an Iterator object that you can
160
-	// use to range over the set.
161
-	Iterator() *Iterator[T]
162
-
163
-	// Remove removes a single element from the set.
164
-	Remove(i T)
165
-
166
-	// RemoveAll removes multiple elements from the set.
167
-	RemoveAll(i ...T)
168
-
169
-	// String provides a convenient string representation
170
-	// of the current state of the set.
171
-	String() string
172
-
173
-	// SymmetricDifference returns a new set with all elements which are
174
-	// in either this set or the other set but not in both.
175
-	//
176
-	// Note that the argument to SymmetricDifference
177
-	// must be of the same type as the receiver
178
-	// of the method. Otherwise, SymmetricDifference
179
-	// will panic.
180
-	SymmetricDifference(other Set[T]) Set[T]
181
-
182
-	// Union returns a new set with all elements in both sets.
183
-	//
184
-	// Note that the argument to Union must be of the
185
-	// same type as the receiver of the method.
186
-	// Otherwise, Union will panic.
187
-	Union(other Set[T]) Set[T]
188
-
189
-	// Pop removes and returns an arbitrary item from the set.
190
-	Pop() (T, bool)
191
-
192
-	// ToSlice returns the members of the set as a slice.
193
-	ToSlice() []T
194
-
195
-	// MarshalJSON will marshal the set into a JSON-based representation.
196
-	MarshalJSON() ([]byte, error)
197
-
198
-	// UnmarshalJSON will unmarshal a JSON-based byte slice into a full Set datastructure.
199
-	// For this to work, set subtypes must implemented the Marshal/Unmarshal interface.
200
-	UnmarshalJSON(b []byte) error
201
-}
202
-
203
-// NewSet creates and returns a new set with the given elements.
204
-// Operations on the resulting set are thread-safe.
205
-func NewSet[T comparable](vals ...T) Set[T] {
206
-	s := newThreadSafeSetWithSize[T](len(vals))
207
-	for _, item := range vals {
208
-		s.Add(item)
209
-	}
210
-	return s
211
-}
212
-
213
-// NewSetWithSize creates and returns a reference to an empty set with a specified
214
-// capacity. Operations on the resulting set are thread-safe.
215
-func NewSetWithSize[T comparable](cardinality int) Set[T] {
216
-	s := newThreadSafeSetWithSize[T](cardinality)
217
-	return s
218
-}
219
-
220
-// NewThreadUnsafeSet creates and returns a new set with the given elements.
221
-// Operations on the resulting set are not thread-safe.
222
-func NewThreadUnsafeSet[T comparable](vals ...T) Set[T] {
223
-	s := newThreadUnsafeSetWithSize[T](len(vals))
224
-	for _, item := range vals {
225
-		s.Add(item)
226
-	}
227
-	return s
228
-}
229
-
230
-// NewThreadUnsafeSetWithSize creates and returns a reference to an empty set with
231
-// a specified capacity. Operations on the resulting set are not thread-safe.
232
-func NewThreadUnsafeSetWithSize[T comparable](cardinality int) Set[T] {
233
-	s := newThreadUnsafeSetWithSize[T](cardinality)
234
-	return s
235
-}
236
-
237
-// NewSetFromMapKeys creates and returns a new set with the given keys of the map.
238
-// Operations on the resulting set are thread-safe.
239
-func NewSetFromMapKeys[T comparable, V any](val map[T]V) Set[T] {
240
-	s := NewSetWithSize[T](len(val))
241
-
242
-	for k := range val {
243
-		s.Add(k)
244
-	}
245
-
246
-	return s
247
-}
248
-
249
-// NewThreadUnsafeSetFromMapKeys creates and returns a new set with the given keys of the map.
250
-// Operations on the resulting set are not thread-safe.
251
-func NewThreadUnsafeSetFromMapKeys[T comparable, V any](val map[T]V) Set[T] {
252
-	s := NewThreadUnsafeSetWithSize[T](len(val))
253
-
254
-	for k := range val {
255
-		s.Add(k)
256
-	}
257
-
258
-	return s
259
-}
260
-
261
-// Elements returns an iterator that yields the elements of the set. Starting
262
-// with Go 1.23, users can use a for loop to iterate over it.
263
-func Elements[T comparable](s Set[T]) func(func(element T) bool) {
264
-	return func(yield func(element T) bool) {
265
-		s.Each(func(t T) bool {
266
-			return !yield(t)
267
-		})
268
-	}
269
-}
270 1
deleted file mode 100644
... ...
@@ -1,42 +0,0 @@
1
-//go:build go1.21
2
-// +build go1.21
3
-
4
-/*
5
-Open Source Initiative OSI - The MIT License (MIT):Licensing
6
-
7
-The MIT License (MIT)
8
-Copyright (c) 2013 - 2023 Ralph Caraveo (deckarep@gmail.com)
9
-
10
-Permission is hereby granted, free of charge, to any person obtaining a copy of
11
-this software and associated documentation files (the "Software"), to deal in
12
-the Software without restriction, including without limitation the rights to
13
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
14
-of the Software, and to permit persons to whom the Software is furnished to do
15
-so, subject to the following conditions:
16
-
17
-The above copyright notice and this permission notice shall be included in all
18
-copies or substantial portions of the Software.
19
-
20
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
-SOFTWARE.
27
-*/
28
-
29
-package mapset
30
-
31
-import (
32
-	"cmp"
33
-	"slices"
34
-)
35
-
36
-// Sorted returns a sorted slice of a set of any ordered type in ascending order.
37
-// When sorting floating-point numbers, NaNs are ordered before other values.
38
-func Sorted[E cmp.Ordered](set Set[E]) []E {
39
-	s := set.ToSlice()
40
-	slices.Sort(s)
41
-	return s
42
-}
43 1
deleted file mode 100644
... ...
@@ -1,312 +0,0 @@
1
-/*
2
-Open Source Initiative OSI - The MIT License (MIT):Licensing
3
-
4
-The MIT License (MIT)
5
-Copyright (c) 2013 - 2022 Ralph Caraveo (deckarep@gmail.com)
6
-
7
-Permission is hereby granted, free of charge, to any person obtaining a copy of
8
-this software and associated documentation files (the "Software"), to deal in
9
-the Software without restriction, including without limitation the rights to
10
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11
-of the Software, and to permit persons to whom the Software is furnished to do
12
-so, subject to the following conditions:
13
-
14
-The above copyright notice and this permission notice shall be included in all
15
-copies or substantial portions of the Software.
16
-
17
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
-SOFTWARE.
24
-*/
25
-
26
-package mapset
27
-
28
-import "sync"
29
-
30
-type threadSafeSet[T comparable] struct {
31
-	sync.RWMutex
32
-	uss *threadUnsafeSet[T]
33
-}
34
-
35
-func newThreadSafeSet[T comparable]() *threadSafeSet[T] {
36
-	return &threadSafeSet[T]{
37
-		uss: newThreadUnsafeSet[T](),
38
-	}
39
-}
40
-
41
-func newThreadSafeSetWithSize[T comparable](cardinality int) *threadSafeSet[T] {
42
-	return &threadSafeSet[T]{
43
-		uss: newThreadUnsafeSetWithSize[T](cardinality),
44
-	}
45
-}
46
-
47
-func (t *threadSafeSet[T]) Add(v T) bool {
48
-	t.Lock()
49
-	ret := t.uss.Add(v)
50
-	t.Unlock()
51
-	return ret
52
-}
53
-
54
-func (t *threadSafeSet[T]) Append(v ...T) int {
55
-	t.Lock()
56
-	ret := t.uss.Append(v...)
57
-	t.Unlock()
58
-	return ret
59
-}
60
-
61
-func (t *threadSafeSet[T]) Contains(v ...T) bool {
62
-	t.RLock()
63
-	ret := t.uss.Contains(v...)
64
-	t.RUnlock()
65
-
66
-	return ret
67
-}
68
-
69
-func (t *threadSafeSet[T]) ContainsOne(v T) bool {
70
-	t.RLock()
71
-	ret := t.uss.ContainsOne(v)
72
-	t.RUnlock()
73
-
74
-	return ret
75
-}
76
-
77
-func (t *threadSafeSet[T]) ContainsAny(v ...T) bool {
78
-	t.RLock()
79
-	ret := t.uss.ContainsAny(v...)
80
-	t.RUnlock()
81
-
82
-	return ret
83
-}
84
-
85
-func (t *threadSafeSet[T]) ContainsAnyElement(other Set[T]) bool {
86
-	o := other.(*threadSafeSet[T])
87
-
88
-	t.RLock()
89
-	o.RLock()
90
-
91
-	ret := t.uss.ContainsAnyElement(o.uss)
92
-
93
-	t.RUnlock()
94
-	o.RUnlock()
95
-	return ret
96
-}
97
-
98
-func (t *threadSafeSet[T]) IsEmpty() bool {
99
-	return t.Cardinality() == 0
100
-}
101
-
102
-func (t *threadSafeSet[T]) IsSubset(other Set[T]) bool {
103
-	o := other.(*threadSafeSet[T])
104
-
105
-	t.RLock()
106
-	o.RLock()
107
-
108
-	ret := t.uss.IsSubset(o.uss)
109
-	t.RUnlock()
110
-	o.RUnlock()
111
-	return ret
112
-}
113
-
114
-func (t *threadSafeSet[T]) IsProperSubset(other Set[T]) bool {
115
-	o := other.(*threadSafeSet[T])
116
-
117
-	t.RLock()
118
-	defer t.RUnlock()
119
-	o.RLock()
120
-	defer o.RUnlock()
121
-
122
-	return t.uss.IsProperSubset(o.uss)
123
-}
124
-
125
-func (t *threadSafeSet[T]) IsSuperset(other Set[T]) bool {
126
-	return other.IsSubset(t)
127
-}
128
-
129
-func (t *threadSafeSet[T]) IsProperSuperset(other Set[T]) bool {
130
-	return other.IsProperSubset(t)
131
-}
132
-
133
-func (t *threadSafeSet[T]) Union(other Set[T]) Set[T] {
134
-	o := other.(*threadSafeSet[T])
135
-
136
-	t.RLock()
137
-	o.RLock()
138
-
139
-	unsafeUnion := t.uss.Union(o.uss).(*threadUnsafeSet[T])
140
-	ret := &threadSafeSet[T]{uss: unsafeUnion}
141
-	t.RUnlock()
142
-	o.RUnlock()
143
-	return ret
144
-}
145
-
146
-func (t *threadSafeSet[T]) Intersect(other Set[T]) Set[T] {
147
-	o := other.(*threadSafeSet[T])
148
-
149
-	t.RLock()
150
-	o.RLock()
151
-
152
-	unsafeIntersection := t.uss.Intersect(o.uss).(*threadUnsafeSet[T])
153
-	ret := &threadSafeSet[T]{uss: unsafeIntersection}
154
-	t.RUnlock()
155
-	o.RUnlock()
156
-	return ret
157
-}
158
-
159
-func (t *threadSafeSet[T]) Difference(other Set[T]) Set[T] {
160
-	o := other.(*threadSafeSet[T])
161
-
162
-	t.RLock()
163
-	o.RLock()
164
-
165
-	unsafeDifference := t.uss.Difference(o.uss).(*threadUnsafeSet[T])
166
-	ret := &threadSafeSet[T]{uss: unsafeDifference}
167
-	t.RUnlock()
168
-	o.RUnlock()
169
-	return ret
170
-}
171
-
172
-func (t *threadSafeSet[T]) SymmetricDifference(other Set[T]) Set[T] {
173
-	o := other.(*threadSafeSet[T])
174
-
175
-	t.RLock()
176
-	o.RLock()
177
-
178
-	unsafeDifference := t.uss.SymmetricDifference(o.uss).(*threadUnsafeSet[T])
179
-	ret := &threadSafeSet[T]{uss: unsafeDifference}
180
-	t.RUnlock()
181
-	o.RUnlock()
182
-	return ret
183
-}
184
-
185
-func (t *threadSafeSet[T]) Clear() {
186
-	t.Lock()
187
-	t.uss.Clear()
188
-	t.Unlock()
189
-}
190
-
191
-func (t *threadSafeSet[T]) Remove(v T) {
192
-	t.Lock()
193
-	delete(*t.uss, v)
194
-	t.Unlock()
195
-}
196
-
197
-func (t *threadSafeSet[T]) RemoveAll(i ...T) {
198
-	t.Lock()
199
-	t.uss.RemoveAll(i...)
200
-	t.Unlock()
201
-}
202
-
203
-func (t *threadSafeSet[T]) Cardinality() int {
204
-	t.RLock()
205
-	defer t.RUnlock()
206
-	return len(*t.uss)
207
-}
208
-
209
-func (t *threadSafeSet[T]) Each(cb func(T) bool) {
210
-	t.RLock()
211
-	for elem := range *t.uss {
212
-		if cb(elem) {
213
-			break
214
-		}
215
-	}
216
-	t.RUnlock()
217
-}
218
-
219
-func (t *threadSafeSet[T]) Iter() <-chan T {
220
-	ch := make(chan T)
221
-	go func() {
222
-		t.RLock()
223
-
224
-		for elem := range *t.uss {
225
-			ch <- elem
226
-		}
227
-		close(ch)
228
-		t.RUnlock()
229
-	}()
230
-
231
-	return ch
232
-}
233
-
234
-func (t *threadSafeSet[T]) Iterator() *Iterator[T] {
235
-	iterator, ch, stopCh := newIterator[T]()
236
-
237
-	go func() {
238
-		t.RLock()
239
-	L:
240
-		for elem := range *t.uss {
241
-			select {
242
-			case <-stopCh:
243
-				break L
244
-			case ch <- elem:
245
-			}
246
-		}
247
-		close(ch)
248
-		t.RUnlock()
249
-	}()
250
-
251
-	return iterator
252
-}
253
-
254
-func (t *threadSafeSet[T]) Equal(other Set[T]) bool {
255
-	o := other.(*threadSafeSet[T])
256
-
257
-	t.RLock()
258
-	o.RLock()
259
-
260
-	ret := t.uss.Equal(o.uss)
261
-	t.RUnlock()
262
-	o.RUnlock()
263
-	return ret
264
-}
265
-
266
-func (t *threadSafeSet[T]) Clone() Set[T] {
267
-	t.RLock()
268
-
269
-	unsafeClone := t.uss.Clone().(*threadUnsafeSet[T])
270
-	ret := &threadSafeSet[T]{uss: unsafeClone}
271
-	t.RUnlock()
272
-	return ret
273
-}
274
-
275
-func (t *threadSafeSet[T]) String() string {
276
-	t.RLock()
277
-	ret := t.uss.String()
278
-	t.RUnlock()
279
-	return ret
280
-}
281
-
282
-func (t *threadSafeSet[T]) Pop() (T, bool) {
283
-	t.Lock()
284
-	defer t.Unlock()
285
-	return t.uss.Pop()
286
-}
287
-
288
-func (t *threadSafeSet[T]) ToSlice() []T {
289
-	keys := make([]T, 0, t.Cardinality())
290
-	t.RLock()
291
-	for elem := range *t.uss {
292
-		keys = append(keys, elem)
293
-	}
294
-	t.RUnlock()
295
-	return keys
296
-}
297
-
298
-func (t *threadSafeSet[T]) MarshalJSON() ([]byte, error) {
299
-	t.RLock()
300
-	b, err := t.uss.MarshalJSON()
301
-	t.RUnlock()
302
-
303
-	return b, err
304
-}
305
-
306
-func (t *threadSafeSet[T]) UnmarshalJSON(p []byte) error {
307
-	t.RLock()
308
-	err := t.uss.UnmarshalJSON(p)
309
-	t.RUnlock()
310
-
311
-	return err
312
-}
313 1
deleted file mode 100644
... ...
@@ -1,352 +0,0 @@
1
-/*
2
-Open Source Initiative OSI - The MIT License (MIT):Licensing
3
-
4
-The MIT License (MIT)
5
-Copyright (c) 2013 - 2022 Ralph Caraveo (deckarep@gmail.com)
6
-
7
-Permission is hereby granted, free of charge, to any person obtaining a copy of
8
-this software and associated documentation files (the "Software"), to deal in
9
-the Software without restriction, including without limitation the rights to
10
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11
-of the Software, and to permit persons to whom the Software is furnished to do
12
-so, subject to the following conditions:
13
-
14
-The above copyright notice and this permission notice shall be included in all
15
-copies or substantial portions of the Software.
16
-
17
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
-SOFTWARE.
24
-*/
25
-
26
-package mapset
27
-
28
-import (
29
-	"encoding/json"
30
-	"fmt"
31
-	"strings"
32
-)
33
-
34
-type threadUnsafeSet[T comparable] map[T]struct{}
35
-
36
-// Assert concrete type:threadUnsafeSet adheres to Set interface.
37
-var _ Set[string] = (*threadUnsafeSet[string])(nil)
38
-
39
-func newThreadUnsafeSet[T comparable]() *threadUnsafeSet[T] {
40
-	t := make(threadUnsafeSet[T])
41
-	return &t
42
-}
43
-
44
-func newThreadUnsafeSetWithSize[T comparable](cardinality int) *threadUnsafeSet[T] {
45
-	t := make(threadUnsafeSet[T], cardinality)
46
-	return &t
47
-}
48
-
49
-func (s threadUnsafeSet[T]) Add(v T) bool {
50
-	prevLen := len(s)
51
-	s[v] = struct{}{}
52
-	return prevLen != len(s)
53
-}
54
-
55
-func (s *threadUnsafeSet[T]) Append(v ...T) int {
56
-	prevLen := len(*s)
57
-	for _, val := range v {
58
-		(*s)[val] = struct{}{}
59
-	}
60
-	return len(*s) - prevLen
61
-}
62
-
63
-// private version of Add which doesn't return a value
64
-func (s *threadUnsafeSet[T]) add(v T) {
65
-	(*s)[v] = struct{}{}
66
-}
67
-
68
-func (s *threadUnsafeSet[T]) Cardinality() int {
69
-	return len(*s)
70
-}
71
-
72
-func (s *threadUnsafeSet[T]) Clear() {
73
-	// Constructions like this are optimised by compiler, and replaced by
74
-	// mapclear() function, defined in
75
-	// https://github.com/golang/go/blob/29bbca5c2c1ad41b2a9747890d183b6dd3a4ace4/src/runtime/map.go#L993)
76
-	for key := range *s {
77
-		delete(*s, key)
78
-	}
79
-}
80
-
81
-func (s *threadUnsafeSet[T]) Clone() Set[T] {
82
-	clonedSet := newThreadUnsafeSetWithSize[T](s.Cardinality())
83
-	for elem := range *s {
84
-		clonedSet.add(elem)
85
-	}
86
-	return clonedSet
87
-}
88
-
89
-func (s *threadUnsafeSet[T]) Contains(v ...T) bool {
90
-	for _, val := range v {
91
-		if _, ok := (*s)[val]; !ok {
92
-			return false
93
-		}
94
-	}
95
-	return true
96
-}
97
-
98
-func (s *threadUnsafeSet[T]) ContainsOne(v T) bool {
99
-	_, ok := (*s)[v]
100
-	return ok
101
-}
102
-
103
-func (s *threadUnsafeSet[T]) ContainsAny(v ...T) bool {
104
-	for _, val := range v {
105
-		if _, ok := (*s)[val]; ok {
106
-			return true
107
-		}
108
-	}
109
-	return false
110
-}
111
-
112
-func (s *threadUnsafeSet[T]) ContainsAnyElement(other Set[T]) bool {
113
-	o := other.(*threadUnsafeSet[T])
114
-
115
-	// loop over smaller set
116
-	if s.Cardinality() < other.Cardinality() {
117
-		for elem := range *s {
118
-			if o.contains(elem) {
119
-				return true
120
-			}
121
-		}
122
-	} else {
123
-		for elem := range *o {
124
-			if s.contains(elem) {
125
-				return true
126
-			}
127
-		}
128
-	}
129
-	return false
130
-}
131
-
132
-// private version of Contains for a single element v
133
-func (s *threadUnsafeSet[T]) contains(v T) (ok bool) {
134
-	_, ok = (*s)[v]
135
-	return ok
136
-}
137
-
138
-func (s *threadUnsafeSet[T]) Difference(other Set[T]) Set[T] {
139
-	o := other.(*threadUnsafeSet[T])
140
-
141
-	diff := newThreadUnsafeSet[T]()
142
-	for elem := range *s {
143
-		if !o.contains(elem) {
144
-			diff.add(elem)
145
-		}
146
-	}
147
-	return diff
148
-}
149
-
150
-func (s *threadUnsafeSet[T]) Each(cb func(T) bool) {
151
-	for elem := range *s {
152
-		if cb(elem) {
153
-			break
154
-		}
155
-	}
156
-}
157
-
158
-func (s *threadUnsafeSet[T]) Equal(other Set[T]) bool {
159
-	o := other.(*threadUnsafeSet[T])
160
-
161
-	if s.Cardinality() != other.Cardinality() {
162
-		return false
163
-	}
164
-	for elem := range *s {
165
-		if !o.contains(elem) {
166
-			return false
167
-		}
168
-	}
169
-	return true
170
-}
171
-
172
-func (s *threadUnsafeSet[T]) Intersect(other Set[T]) Set[T] {
173
-	o := other.(*threadUnsafeSet[T])
174
-
175
-	intersection := newThreadUnsafeSet[T]()
176
-	// loop over smaller set
177
-	if s.Cardinality() < other.Cardinality() {
178
-		for elem := range *s {
179
-			if o.contains(elem) {
180
-				intersection.add(elem)
181
-			}
182
-		}
183
-	} else {
184
-		for elem := range *o {
185
-			if s.contains(elem) {
186
-				intersection.add(elem)
187
-			}
188
-		}
189
-	}
190
-	return intersection
191
-}
192
-
193
-func (s *threadUnsafeSet[T]) IsEmpty() bool {
194
-	return s.Cardinality() == 0
195
-}
196
-
197
-func (s *threadUnsafeSet[T]) IsProperSubset(other Set[T]) bool {
198
-	return s.Cardinality() < other.Cardinality() && s.IsSubset(other)
199
-}
200
-
201
-func (s *threadUnsafeSet[T]) IsProperSuperset(other Set[T]) bool {
202
-	return s.Cardinality() > other.Cardinality() && s.IsSuperset(other)
203
-}
204
-
205
-func (s *threadUnsafeSet[T]) IsSubset(other Set[T]) bool {
206
-	o := other.(*threadUnsafeSet[T])
207
-	if s.Cardinality() > other.Cardinality() {
208
-		return false
209
-	}
210
-	for elem := range *s {
211
-		if !o.contains(elem) {
212
-			return false
213
-		}
214
-	}
215
-	return true
216
-}
217
-
218
-func (s *threadUnsafeSet[T]) IsSuperset(other Set[T]) bool {
219
-	return other.IsSubset(s)
220
-}
221
-
222
-func (s *threadUnsafeSet[T]) Iter() <-chan T {
223
-	ch := make(chan T)
224
-	go func() {
225
-		for elem := range *s {
226
-			ch <- elem
227
-		}
228
-		close(ch)
229
-	}()
230
-
231
-	return ch
232
-}
233
-
234
-func (s *threadUnsafeSet[T]) Iterator() *Iterator[T] {
235
-	iterator, ch, stopCh := newIterator[T]()
236
-
237
-	go func() {
238
-	L:
239
-		for elem := range *s {
240
-			select {
241
-			case <-stopCh:
242
-				break L
243
-			case ch <- elem:
244
-			}
245
-		}
246
-		close(ch)
247
-	}()
248
-
249
-	return iterator
250
-}
251
-
252
-// Pop returns a popped item in case set is not empty, or nil-value of T
253
-// if set is already empty
254
-func (s *threadUnsafeSet[T]) Pop() (v T, ok bool) {
255
-	for item := range *s {
256
-		delete(*s, item)
257
-		return item, true
258
-	}
259
-	return v, false
260
-}
261
-
262
-func (s threadUnsafeSet[T]) Remove(v T) {
263
-	delete(s, v)
264
-}
265
-
266
-func (s threadUnsafeSet[T]) RemoveAll(i ...T) {
267
-	for _, elem := range i {
268
-		delete(s, elem)
269
-	}
270
-}
271
-
272
-func (s threadUnsafeSet[T]) String() string {
273
-	items := make([]string, 0, len(s))
274
-
275
-	for elem := range s {
276
-		items = append(items, fmt.Sprintf("%v", elem))
277
-	}
278
-	return fmt.Sprintf("Set{%s}", strings.Join(items, ", "))
279
-}
280
-
281
-func (s *threadUnsafeSet[T]) SymmetricDifference(other Set[T]) Set[T] {
282
-	o := other.(*threadUnsafeSet[T])
283
-
284
-	sd := newThreadUnsafeSet[T]()
285
-	for elem := range *s {
286
-		if !o.contains(elem) {
287
-			sd.add(elem)
288
-		}
289
-	}
290
-	for elem := range *o {
291
-		if !s.contains(elem) {
292
-			sd.add(elem)
293
-		}
294
-	}
295
-	return sd
296
-}
297
-
298
-func (s threadUnsafeSet[T]) ToSlice() []T {
299
-	keys := make([]T, 0, s.Cardinality())
300
-	for elem := range s {
301
-		keys = append(keys, elem)
302
-	}
303
-
304
-	return keys
305
-}
306
-
307
-func (s threadUnsafeSet[T]) Union(other Set[T]) Set[T] {
308
-	o := other.(*threadUnsafeSet[T])
309
-
310
-	n := s.Cardinality()
311
-	if o.Cardinality() > n {
312
-		n = o.Cardinality()
313
-	}
314
-	unionedSet := make(threadUnsafeSet[T], n)
315
-
316
-	for elem := range s {
317
-		unionedSet.add(elem)
318
-	}
319
-	for elem := range *o {
320
-		unionedSet.add(elem)
321
-	}
322
-	return &unionedSet
323
-}
324
-
325
-// MarshalJSON creates a JSON array from the set, it marshals all elements
326
-func (s threadUnsafeSet[T]) MarshalJSON() ([]byte, error) {
327
-	items := make([]string, 0, s.Cardinality())
328
-
329
-	for elem := range s {
330
-		b, err := json.Marshal(elem)
331
-		if err != nil {
332
-			return nil, err
333
-		}
334
-
335
-		items = append(items, string(b))
336
-	}
337
-
338
-	return []byte(fmt.Sprintf("[%s]", strings.Join(items, ","))), nil
339
-}
340
-
341
-// UnmarshalJSON recreates a set from a JSON array, it only decodes
342
-// primitive types. Numbers are decoded as json.Number.
343
-func (s *threadUnsafeSet[T]) UnmarshalJSON(b []byte) error {
344
-	var i []T
345
-	err := json.Unmarshal(b, &i)
346
-	if err != nil {
347
-		return err
348
-	}
349
-	s.Append(i...)
350
-
351
-	return nil
352
-}
... ...
@@ -589,9 +589,6 @@ github.com/cyphar/filepath-securejoin/pathrs-lite/procfs
589 589
 # github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
590 590
 ## explicit
591 591
 github.com/davecgh/go-spew/spew
592
-# github.com/deckarep/golang-set/v2 v2.8.0
593
-## explicit; go 1.18
594
-github.com/deckarep/golang-set/v2
595 592
 # github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352
596 593
 ## explicit; go 1.13
597 594
 github.com/digitorus/pkcs7