mirror of
https://github.com/moby/moby.git
synced 2026-08-04 23:21:00 +00:00
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>
This commit is contained in:
@@ -1,17 +1,57 @@
|
||||
package setmatrix
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
)
|
||||
|
||||
type set[V comparable] map[V]struct{}
|
||||
|
||||
func newSet[V comparable](value V) set[V] {
|
||||
s := make(set[V], 1)
|
||||
s[value] = struct{}{}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s set[V]) Add(value V) bool {
|
||||
if _, ok := s[value]; ok {
|
||||
return false
|
||||
}
|
||||
s[value] = struct{}{}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s set[V]) Contains(value V) bool {
|
||||
_, ok := s[value]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (s set[V]) Remove(value V) {
|
||||
delete(s, value)
|
||||
}
|
||||
|
||||
func (s set[V]) Cardinality() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func (s set[V]) ToSlice() []V {
|
||||
values := make([]V, 0, len(s))
|
||||
for value := range s {
|
||||
values = append(values, value)
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
func (s set[V]) String() string {
|
||||
return fmt.Sprint(s.ToSlice())
|
||||
}
|
||||
|
||||
// SetMatrix is a map of Sets.
|
||||
// The zero value is an empty set matrix ready to use.
|
||||
//
|
||||
// SetMatrix values are safe for concurrent use.
|
||||
type SetMatrix[K, V comparable] struct {
|
||||
matrix map[K]mapset.Set[V]
|
||||
matrix map[K]set[V]
|
||||
|
||||
mu sync.Mutex
|
||||
}
|
||||
@@ -43,16 +83,16 @@ func (s *SetMatrix[K, V]) Contains(key K, value V) (containsElement, setExists b
|
||||
func (s *SetMatrix[K, V]) Insert(key K, value V) (inserted bool, cardinality int) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
set, ok := s.matrix[key]
|
||||
values, ok := s.matrix[key]
|
||||
if !ok {
|
||||
if s.matrix == nil {
|
||||
s.matrix = make(map[K]mapset.Set[V])
|
||||
s.matrix = make(map[K]set[V])
|
||||
}
|
||||
s.matrix[key] = mapset.NewThreadUnsafeSet(value)
|
||||
s.matrix[key] = newSet(value)
|
||||
return true, 1
|
||||
}
|
||||
|
||||
return set.Add(value), set.Cardinality()
|
||||
return values.Add(value), values.Cardinality()
|
||||
}
|
||||
|
||||
// Remove removes the value in the set for a specific key.
|
||||
|
||||
1
go.mod
1
go.mod
@@ -32,7 +32,6 @@ require (
|
||||
github.com/coreos/go-systemd/v22 v22.7.0
|
||||
github.com/cpuguy83/tar2go v0.3.1
|
||||
github.com/creack/pty v1.1.24
|
||||
github.com/deckarep/golang-set/v2 v2.8.0
|
||||
github.com/distribution/reference v0.6.0
|
||||
github.com/docker/distribution v2.8.3+incompatible
|
||||
github.com/docker/go-connections v0.7.0
|
||||
|
||||
2
go.sum
2
go.sum
@@ -216,8 +216,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/deckarep/golang-set/v2 v2.8.0 h1:swm0rlPCmdWn9mESxKOjWk8hXSqoxOp+ZlfuyaAdFlQ=
|
||||
github.com/deckarep/golang-set/v2 v2.8.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
|
||||
github.com/digitorus/pkcs7 v0.0.0-20230713084857-e76b763bdc49/go.mod h1:SKVExuS+vpu2l9IoOc0RwqE7NYnb0JlcFHFnEJkVDzc=
|
||||
github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 h1:ge14PCmCvPjpMQMIAH7uKg0lrtNSOdpYsRXlwk3QbaE=
|
||||
github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352/go.mod h1:SKVExuS+vpu2l9IoOc0RwqE7NYnb0JlcFHFnEJkVDzc=
|
||||
|
||||
23
vendor/github.com/deckarep/golang-set/v2/.gitignore
generated
vendored
23
vendor/github.com/deckarep/golang-set/v2/.gitignore
generated
vendored
@@ -1,23 +0,0 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
.idea
|
||||
22
vendor/github.com/deckarep/golang-set/v2/LICENSE
generated
vendored
22
vendor/github.com/deckarep/golang-set/v2/LICENSE
generated
vendored
@@ -1,22 +0,0 @@
|
||||
Open Source Initiative OSI - The MIT License (MIT):Licensing
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2013 - 2022 Ralph Caraveo (deckarep@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
195
vendor/github.com/deckarep/golang-set/v2/README.md
generated
vendored
195
vendor/github.com/deckarep/golang-set/v2/README.md
generated
vendored
@@ -1,195 +0,0 @@
|
||||

|
||||
[](https://goreportcard.com/report/github.com/deckarep/golang-set/v2)
|
||||
[](http://godoc.org/github.com/deckarep/golang-set/v2)
|
||||
|
||||
# golang-set
|
||||
|
||||
The missing `generic` set collection for the Go language. Until Go has sets built-in...use this.
|
||||
|
||||
## Psst
|
||||
* 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!
|
||||
|
||||
## Update 3/14/2025
|
||||
* 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)
|
||||
for further details on the implications of how iterations work between older Go versions vs newer Go versions. Additionally, this
|
||||
release has a minor unit-test spelling fix.
|
||||
|
||||
## Update 12/3/2024
|
||||
* Packaged version: `2.7.0` fixes a long-standing bug with *JSON Unmarshaling*. A large refactor in the interest of performance
|
||||
introduced this bug and there was no way around it but to revert the code back to how it was previously. The performance
|
||||
difference was likely negligible to begin with. JSON Marshaling and Unmarshaling is now properly supported again without
|
||||
needing to do workarounds.
|
||||
|
||||
## Update 3/5/2023
|
||||
* 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`.
|
||||
* supports `new generic` syntax
|
||||
* Go `1.18.0` or higher
|
||||
* Workflow tested on Go `1.20`
|
||||
|
||||

|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
## Install
|
||||
|
||||
Use `go get` to install this package.
|
||||
|
||||
```shell
|
||||
go get github.com/deckarep/golang-set/v2
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
* *NEW* [Generics](https://go.dev/doc/tutorial/generics) based implementation (requires [Go 1.18](https://go.dev/blog/go1.18beta1) or higher)
|
||||
* One common *interface* to both implementations
|
||||
* a **non threadsafe** implementation favoring *performance*
|
||||
* a **threadsafe** implementation favoring *concurrent* use
|
||||
* Feature complete set implementation modeled after [Python's set implementation](https://docs.python.org/3/library/stdtypes.html#set).
|
||||
* Exhaustive unit-test and benchmark suite
|
||||
|
||||
## Trusted by
|
||||
|
||||
This package is trusted by many companies and thousands of open-source packages. Here are just a few sample users of this package.
|
||||
|
||||
* Notable projects/companies using this package
|
||||
* Ethereum
|
||||
* Docker
|
||||
* 1Password
|
||||
* Hashicorp
|
||||
|
||||
## Star History
|
||||
|
||||
[](https://star-history.com/#deckarep/golang-set&Date)
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
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.
|
||||
|
||||
What is considered comparable in Go?
|
||||
* `Booleans`, `integers`, `strings`, `floats` or basically primitive types.
|
||||
* `Pointers`
|
||||
* `Arrays`
|
||||
* `Structs` if *all of their fields* are also comparable independently
|
||||
|
||||
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.
|
||||
|
||||
```go
|
||||
// Syntax example, doesn't compile.
|
||||
mySet := mapset.NewSet[T]() // where T is some concrete comparable type.
|
||||
|
||||
// Therefore this code creates an int set
|
||||
mySet := mapset.NewSet[int]()
|
||||
|
||||
// Or perhaps you want a string set
|
||||
mySet := mapset.NewSet[string]()
|
||||
|
||||
type myStruct struct {
|
||||
name string
|
||||
age uint8
|
||||
}
|
||||
|
||||
// Alternatively a set of structs
|
||||
mySet := mapset.NewSet[myStruct]()
|
||||
|
||||
// Lastly a set that can hold anything using the any or empty interface keyword: interface{}. This is effectively removes type safety.
|
||||
mySet := mapset.NewSet[any]()
|
||||
```
|
||||
|
||||
## Comprehensive Example
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Create a string-based set of required classes.
|
||||
required := mapset.NewSet[string]()
|
||||
required.Add("cooking")
|
||||
required.Add("english")
|
||||
required.Add("math")
|
||||
required.Add("biology")
|
||||
|
||||
// Create a string-based set of science classes.
|
||||
sciences := mapset.NewSet[string]()
|
||||
sciences.Add("biology")
|
||||
sciences.Add("chemistry")
|
||||
|
||||
// Create a string-based set of electives.
|
||||
electives := mapset.NewSet[string]()
|
||||
electives.Add("welding")
|
||||
electives.Add("music")
|
||||
electives.Add("automotive")
|
||||
|
||||
// Create a string-based set of bonus programming classes.
|
||||
bonus := mapset.NewSet[string]()
|
||||
bonus.Add("beginner go")
|
||||
bonus.Add("python for dummies")
|
||||
}
|
||||
```
|
||||
|
||||
Create a set of all unique classes.
|
||||
Sets will *automatically* deduplicate the same data.
|
||||
|
||||
```go
|
||||
all := required
|
||||
.Union(sciences)
|
||||
.Union(electives)
|
||||
.Union(bonus)
|
||||
|
||||
fmt.Println(all)
|
||||
```
|
||||
|
||||
Output:
|
||||
```sh
|
||||
Set{cooking, english, math, chemistry, welding, biology, music, automotive, beginner go, python for dummies}
|
||||
```
|
||||
|
||||
Is cooking considered a science class?
|
||||
```go
|
||||
result := sciences.Contains("cooking")
|
||||
fmt.Println(result)
|
||||
```
|
||||
|
||||
Output:
|
||||
```false
|
||||
false
|
||||
```
|
||||
|
||||
Show me all classes that are not science classes, since I don't enjoy science.
|
||||
```go
|
||||
notScience := all.Difference(sciences)
|
||||
fmt.Println(notScience)
|
||||
```
|
||||
|
||||
```sh
|
||||
Set{ music, automotive, beginner go, python for dummies, cooking, english, math, welding }
|
||||
```
|
||||
|
||||
Which science classes are also required classes?
|
||||
```go
|
||||
reqScience := sciences.Intersect(required)
|
||||
```
|
||||
|
||||
Output:
|
||||
```sh
|
||||
Set{biology}
|
||||
```
|
||||
|
||||
How many bonus classes do you offer?
|
||||
```go
|
||||
fmt.Println(bonus.Cardinality())
|
||||
```
|
||||
Output:
|
||||
```sh
|
||||
2
|
||||
```
|
||||
|
||||
Thanks for visiting!
|
||||
|
||||
-deckarep
|
||||
58
vendor/github.com/deckarep/golang-set/v2/iterator.go
generated
vendored
58
vendor/github.com/deckarep/golang-set/v2/iterator.go
generated
vendored
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
Open Source Initiative OSI - The MIT License (MIT):Licensing
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2013 - 2022 Ralph Caraveo (deckarep@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package mapset
|
||||
|
||||
// Iterator defines an iterator over a Set, its C channel can be used to range over the Set's
|
||||
// elements.
|
||||
type Iterator[T comparable] struct {
|
||||
C <-chan T
|
||||
stop chan struct{}
|
||||
}
|
||||
|
||||
// Stop stops the Iterator, no further elements will be received on C, C will be closed.
|
||||
func (i *Iterator[T]) Stop() {
|
||||
// Allows for Stop() to be called multiple times
|
||||
// (close() panics when called on already closed channel)
|
||||
defer func() {
|
||||
recover()
|
||||
}()
|
||||
|
||||
close(i.stop)
|
||||
|
||||
// Exhaust any remaining elements.
|
||||
for range i.C {
|
||||
}
|
||||
}
|
||||
|
||||
// newIterator returns a new Iterator instance together with its item and stop channels.
|
||||
func newIterator[T comparable]() (*Iterator[T], chan<- T, <-chan struct{}) {
|
||||
itemChan := make(chan T)
|
||||
stopChan := make(chan struct{})
|
||||
return &Iterator[T]{
|
||||
C: itemChan,
|
||||
stop: stopChan,
|
||||
}, itemChan, stopChan
|
||||
}
|
||||
BIN
vendor/github.com/deckarep/golang-set/v2/new_improved.jpeg
generated
vendored
BIN
vendor/github.com/deckarep/golang-set/v2/new_improved.jpeg
generated
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 118 KiB |
269
vendor/github.com/deckarep/golang-set/v2/set.go
generated
vendored
269
vendor/github.com/deckarep/golang-set/v2/set.go
generated
vendored
@@ -1,269 +0,0 @@
|
||||
/*
|
||||
Open Source Initiative OSI - The MIT License (MIT):Licensing
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2013 - 2022 Ralph Caraveo (deckarep@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
// Package mapset implements a simple and set collection.
|
||||
// Items stored within it are unordered and unique. It supports
|
||||
// typical set operations: membership testing, intersection, union,
|
||||
// difference, symmetric difference and cloning.
|
||||
//
|
||||
// Package mapset provides two implementations of the Set
|
||||
// interface. The default implementation is safe for concurrent
|
||||
// access, but a non-thread-safe implementation is also provided for
|
||||
// programs that can benefit from the slight speed improvement and
|
||||
// that can enforce mutual exclusion through other means.
|
||||
package mapset
|
||||
|
||||
// Set is the primary interface provided by the mapset package. It
|
||||
// represents an unordered set of data and a large number of
|
||||
// operations that can be applied to that set.
|
||||
type Set[T comparable] interface {
|
||||
// Add adds an element to the set. Returns whether
|
||||
// the item was added.
|
||||
Add(val T) bool
|
||||
|
||||
// Append multiple elements to the set. Returns
|
||||
// the number of elements added.
|
||||
Append(val ...T) int
|
||||
|
||||
// Cardinality returns the number of elements in the set.
|
||||
Cardinality() int
|
||||
|
||||
// Clear removes all elements from the set, leaving
|
||||
// the empty set.
|
||||
Clear()
|
||||
|
||||
// Clone returns a clone of the set using the same
|
||||
// implementation, duplicating all keys.
|
||||
Clone() Set[T]
|
||||
|
||||
// Contains returns whether the given items
|
||||
// are all in the set.
|
||||
Contains(val ...T) bool
|
||||
|
||||
// ContainsOne returns whether the given item
|
||||
// is in the set.
|
||||
//
|
||||
// Contains may cause the argument to escape to the heap.
|
||||
// See: https://github.com/deckarep/golang-set/issues/118
|
||||
ContainsOne(val T) bool
|
||||
|
||||
// ContainsAny returns whether at least one of the
|
||||
// given items are in the set.
|
||||
ContainsAny(val ...T) bool
|
||||
|
||||
// ContainsAnyElement returns whether at least one of the
|
||||
// given element are in the set.
|
||||
ContainsAnyElement(other Set[T]) bool
|
||||
|
||||
// Difference returns the difference between this set
|
||||
// and other. The returned set will contain
|
||||
// all elements of this set that are not also
|
||||
// elements of other.
|
||||
//
|
||||
// Note that the argument to Difference
|
||||
// must be of the same type as the receiver
|
||||
// of the method. Otherwise, Difference will
|
||||
// panic.
|
||||
Difference(other Set[T]) Set[T]
|
||||
|
||||
// Equal determines if two sets are equal to each
|
||||
// other. If they have the same cardinality
|
||||
// and contain the same elements, they are
|
||||
// considered equal. The order in which
|
||||
// the elements were added is irrelevant.
|
||||
//
|
||||
// Note that the argument to Equal must be
|
||||
// of the same type as the receiver of the
|
||||
// method. Otherwise, Equal will panic.
|
||||
Equal(other Set[T]) bool
|
||||
|
||||
// Intersect returns a new set containing only the elements
|
||||
// that exist only in both sets.
|
||||
//
|
||||
// Note that the argument to Intersect
|
||||
// must be of the same type as the receiver
|
||||
// of the method. Otherwise, Intersect will
|
||||
// panic.
|
||||
Intersect(other Set[T]) Set[T]
|
||||
|
||||
// IsEmpty determines if there are elements in the set.
|
||||
IsEmpty() bool
|
||||
|
||||
// IsProperSubset determines if every element in this set is in
|
||||
// the other set but the two sets are not equal.
|
||||
//
|
||||
// Note that the argument to IsProperSubset
|
||||
// must be of the same type as the receiver
|
||||
// of the method. Otherwise, IsProperSubset
|
||||
// will panic.
|
||||
IsProperSubset(other Set[T]) bool
|
||||
|
||||
// IsProperSuperset determines if every element in the other set
|
||||
// is in this set but the two sets are not
|
||||
// equal.
|
||||
//
|
||||
// Note that the argument to IsSuperset
|
||||
// must be of the same type as the receiver
|
||||
// of the method. Otherwise, IsSuperset will
|
||||
// panic.
|
||||
IsProperSuperset(other Set[T]) bool
|
||||
|
||||
// IsSubset determines if every element in this set is in
|
||||
// the other set.
|
||||
//
|
||||
// Note that the argument to IsSubset
|
||||
// must be of the same type as the receiver
|
||||
// of the method. Otherwise, IsSubset will
|
||||
// panic.
|
||||
IsSubset(other Set[T]) bool
|
||||
|
||||
// IsSuperset determines if every element in the other set
|
||||
// is in this set.
|
||||
//
|
||||
// Note that the argument to IsSuperset
|
||||
// must be of the same type as the receiver
|
||||
// of the method. Otherwise, IsSuperset will
|
||||
// panic.
|
||||
IsSuperset(other Set[T]) bool
|
||||
|
||||
// Each iterates over elements and executes the passed func against each element.
|
||||
// If passed func returns true, stop iteration at the time.
|
||||
Each(func(T) bool)
|
||||
|
||||
// Iter returns a channel of elements that you can
|
||||
// range over.
|
||||
Iter() <-chan T
|
||||
|
||||
// Iterator returns an Iterator object that you can
|
||||
// use to range over the set.
|
||||
Iterator() *Iterator[T]
|
||||
|
||||
// Remove removes a single element from the set.
|
||||
Remove(i T)
|
||||
|
||||
// RemoveAll removes multiple elements from the set.
|
||||
RemoveAll(i ...T)
|
||||
|
||||
// String provides a convenient string representation
|
||||
// of the current state of the set.
|
||||
String() string
|
||||
|
||||
// SymmetricDifference returns a new set with all elements which are
|
||||
// in either this set or the other set but not in both.
|
||||
//
|
||||
// Note that the argument to SymmetricDifference
|
||||
// must be of the same type as the receiver
|
||||
// of the method. Otherwise, SymmetricDifference
|
||||
// will panic.
|
||||
SymmetricDifference(other Set[T]) Set[T]
|
||||
|
||||
// Union returns a new set with all elements in both sets.
|
||||
//
|
||||
// Note that the argument to Union must be of the
|
||||
// same type as the receiver of the method.
|
||||
// Otherwise, Union will panic.
|
||||
Union(other Set[T]) Set[T]
|
||||
|
||||
// Pop removes and returns an arbitrary item from the set.
|
||||
Pop() (T, bool)
|
||||
|
||||
// ToSlice returns the members of the set as a slice.
|
||||
ToSlice() []T
|
||||
|
||||
// MarshalJSON will marshal the set into a JSON-based representation.
|
||||
MarshalJSON() ([]byte, error)
|
||||
|
||||
// UnmarshalJSON will unmarshal a JSON-based byte slice into a full Set datastructure.
|
||||
// For this to work, set subtypes must implemented the Marshal/Unmarshal interface.
|
||||
UnmarshalJSON(b []byte) error
|
||||
}
|
||||
|
||||
// NewSet creates and returns a new set with the given elements.
|
||||
// Operations on the resulting set are thread-safe.
|
||||
func NewSet[T comparable](vals ...T) Set[T] {
|
||||
s := newThreadSafeSetWithSize[T](len(vals))
|
||||
for _, item := range vals {
|
||||
s.Add(item)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// NewSetWithSize creates and returns a reference to an empty set with a specified
|
||||
// capacity. Operations on the resulting set are thread-safe.
|
||||
func NewSetWithSize[T comparable](cardinality int) Set[T] {
|
||||
s := newThreadSafeSetWithSize[T](cardinality)
|
||||
return s
|
||||
}
|
||||
|
||||
// NewThreadUnsafeSet creates and returns a new set with the given elements.
|
||||
// Operations on the resulting set are not thread-safe.
|
||||
func NewThreadUnsafeSet[T comparable](vals ...T) Set[T] {
|
||||
s := newThreadUnsafeSetWithSize[T](len(vals))
|
||||
for _, item := range vals {
|
||||
s.Add(item)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// NewThreadUnsafeSetWithSize creates and returns a reference to an empty set with
|
||||
// a specified capacity. Operations on the resulting set are not thread-safe.
|
||||
func NewThreadUnsafeSetWithSize[T comparable](cardinality int) Set[T] {
|
||||
s := newThreadUnsafeSetWithSize[T](cardinality)
|
||||
return s
|
||||
}
|
||||
|
||||
// NewSetFromMapKeys creates and returns a new set with the given keys of the map.
|
||||
// Operations on the resulting set are thread-safe.
|
||||
func NewSetFromMapKeys[T comparable, V any](val map[T]V) Set[T] {
|
||||
s := NewSetWithSize[T](len(val))
|
||||
|
||||
for k := range val {
|
||||
s.Add(k)
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// NewThreadUnsafeSetFromMapKeys creates and returns a new set with the given keys of the map.
|
||||
// Operations on the resulting set are not thread-safe.
|
||||
func NewThreadUnsafeSetFromMapKeys[T comparable, V any](val map[T]V) Set[T] {
|
||||
s := NewThreadUnsafeSetWithSize[T](len(val))
|
||||
|
||||
for k := range val {
|
||||
s.Add(k)
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// Elements returns an iterator that yields the elements of the set. Starting
|
||||
// with Go 1.23, users can use a for loop to iterate over it.
|
||||
func Elements[T comparable](s Set[T]) func(func(element T) bool) {
|
||||
return func(yield func(element T) bool) {
|
||||
s.Each(func(t T) bool {
|
||||
return !yield(t)
|
||||
})
|
||||
}
|
||||
}
|
||||
42
vendor/github.com/deckarep/golang-set/v2/sorted.go
generated
vendored
42
vendor/github.com/deckarep/golang-set/v2/sorted.go
generated
vendored
@@ -1,42 +0,0 @@
|
||||
//go:build go1.21
|
||||
// +build go1.21
|
||||
|
||||
/*
|
||||
Open Source Initiative OSI - The MIT License (MIT):Licensing
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2013 - 2023 Ralph Caraveo (deckarep@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package mapset
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"slices"
|
||||
)
|
||||
|
||||
// Sorted returns a sorted slice of a set of any ordered type in ascending order.
|
||||
// When sorting floating-point numbers, NaNs are ordered before other values.
|
||||
func Sorted[E cmp.Ordered](set Set[E]) []E {
|
||||
s := set.ToSlice()
|
||||
slices.Sort(s)
|
||||
return s
|
||||
}
|
||||
312
vendor/github.com/deckarep/golang-set/v2/threadsafe.go
generated
vendored
312
vendor/github.com/deckarep/golang-set/v2/threadsafe.go
generated
vendored
@@ -1,312 +0,0 @@
|
||||
/*
|
||||
Open Source Initiative OSI - The MIT License (MIT):Licensing
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2013 - 2022 Ralph Caraveo (deckarep@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package mapset
|
||||
|
||||
import "sync"
|
||||
|
||||
type threadSafeSet[T comparable] struct {
|
||||
sync.RWMutex
|
||||
uss *threadUnsafeSet[T]
|
||||
}
|
||||
|
||||
func newThreadSafeSet[T comparable]() *threadSafeSet[T] {
|
||||
return &threadSafeSet[T]{
|
||||
uss: newThreadUnsafeSet[T](),
|
||||
}
|
||||
}
|
||||
|
||||
func newThreadSafeSetWithSize[T comparable](cardinality int) *threadSafeSet[T] {
|
||||
return &threadSafeSet[T]{
|
||||
uss: newThreadUnsafeSetWithSize[T](cardinality),
|
||||
}
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) Add(v T) bool {
|
||||
t.Lock()
|
||||
ret := t.uss.Add(v)
|
||||
t.Unlock()
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) Append(v ...T) int {
|
||||
t.Lock()
|
||||
ret := t.uss.Append(v...)
|
||||
t.Unlock()
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) Contains(v ...T) bool {
|
||||
t.RLock()
|
||||
ret := t.uss.Contains(v...)
|
||||
t.RUnlock()
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) ContainsOne(v T) bool {
|
||||
t.RLock()
|
||||
ret := t.uss.ContainsOne(v)
|
||||
t.RUnlock()
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) ContainsAny(v ...T) bool {
|
||||
t.RLock()
|
||||
ret := t.uss.ContainsAny(v...)
|
||||
t.RUnlock()
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) ContainsAnyElement(other Set[T]) bool {
|
||||
o := other.(*threadSafeSet[T])
|
||||
|
||||
t.RLock()
|
||||
o.RLock()
|
||||
|
||||
ret := t.uss.ContainsAnyElement(o.uss)
|
||||
|
||||
t.RUnlock()
|
||||
o.RUnlock()
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) IsEmpty() bool {
|
||||
return t.Cardinality() == 0
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) IsSubset(other Set[T]) bool {
|
||||
o := other.(*threadSafeSet[T])
|
||||
|
||||
t.RLock()
|
||||
o.RLock()
|
||||
|
||||
ret := t.uss.IsSubset(o.uss)
|
||||
t.RUnlock()
|
||||
o.RUnlock()
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) IsProperSubset(other Set[T]) bool {
|
||||
o := other.(*threadSafeSet[T])
|
||||
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
o.RLock()
|
||||
defer o.RUnlock()
|
||||
|
||||
return t.uss.IsProperSubset(o.uss)
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) IsSuperset(other Set[T]) bool {
|
||||
return other.IsSubset(t)
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) IsProperSuperset(other Set[T]) bool {
|
||||
return other.IsProperSubset(t)
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) Union(other Set[T]) Set[T] {
|
||||
o := other.(*threadSafeSet[T])
|
||||
|
||||
t.RLock()
|
||||
o.RLock()
|
||||
|
||||
unsafeUnion := t.uss.Union(o.uss).(*threadUnsafeSet[T])
|
||||
ret := &threadSafeSet[T]{uss: unsafeUnion}
|
||||
t.RUnlock()
|
||||
o.RUnlock()
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) Intersect(other Set[T]) Set[T] {
|
||||
o := other.(*threadSafeSet[T])
|
||||
|
||||
t.RLock()
|
||||
o.RLock()
|
||||
|
||||
unsafeIntersection := t.uss.Intersect(o.uss).(*threadUnsafeSet[T])
|
||||
ret := &threadSafeSet[T]{uss: unsafeIntersection}
|
||||
t.RUnlock()
|
||||
o.RUnlock()
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) Difference(other Set[T]) Set[T] {
|
||||
o := other.(*threadSafeSet[T])
|
||||
|
||||
t.RLock()
|
||||
o.RLock()
|
||||
|
||||
unsafeDifference := t.uss.Difference(o.uss).(*threadUnsafeSet[T])
|
||||
ret := &threadSafeSet[T]{uss: unsafeDifference}
|
||||
t.RUnlock()
|
||||
o.RUnlock()
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) SymmetricDifference(other Set[T]) Set[T] {
|
||||
o := other.(*threadSafeSet[T])
|
||||
|
||||
t.RLock()
|
||||
o.RLock()
|
||||
|
||||
unsafeDifference := t.uss.SymmetricDifference(o.uss).(*threadUnsafeSet[T])
|
||||
ret := &threadSafeSet[T]{uss: unsafeDifference}
|
||||
t.RUnlock()
|
||||
o.RUnlock()
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) Clear() {
|
||||
t.Lock()
|
||||
t.uss.Clear()
|
||||
t.Unlock()
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) Remove(v T) {
|
||||
t.Lock()
|
||||
delete(*t.uss, v)
|
||||
t.Unlock()
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) RemoveAll(i ...T) {
|
||||
t.Lock()
|
||||
t.uss.RemoveAll(i...)
|
||||
t.Unlock()
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) Cardinality() int {
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
return len(*t.uss)
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) Each(cb func(T) bool) {
|
||||
t.RLock()
|
||||
for elem := range *t.uss {
|
||||
if cb(elem) {
|
||||
break
|
||||
}
|
||||
}
|
||||
t.RUnlock()
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) Iter() <-chan T {
|
||||
ch := make(chan T)
|
||||
go func() {
|
||||
t.RLock()
|
||||
|
||||
for elem := range *t.uss {
|
||||
ch <- elem
|
||||
}
|
||||
close(ch)
|
||||
t.RUnlock()
|
||||
}()
|
||||
|
||||
return ch
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) Iterator() *Iterator[T] {
|
||||
iterator, ch, stopCh := newIterator[T]()
|
||||
|
||||
go func() {
|
||||
t.RLock()
|
||||
L:
|
||||
for elem := range *t.uss {
|
||||
select {
|
||||
case <-stopCh:
|
||||
break L
|
||||
case ch <- elem:
|
||||
}
|
||||
}
|
||||
close(ch)
|
||||
t.RUnlock()
|
||||
}()
|
||||
|
||||
return iterator
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) Equal(other Set[T]) bool {
|
||||
o := other.(*threadSafeSet[T])
|
||||
|
||||
t.RLock()
|
||||
o.RLock()
|
||||
|
||||
ret := t.uss.Equal(o.uss)
|
||||
t.RUnlock()
|
||||
o.RUnlock()
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) Clone() Set[T] {
|
||||
t.RLock()
|
||||
|
||||
unsafeClone := t.uss.Clone().(*threadUnsafeSet[T])
|
||||
ret := &threadSafeSet[T]{uss: unsafeClone}
|
||||
t.RUnlock()
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) String() string {
|
||||
t.RLock()
|
||||
ret := t.uss.String()
|
||||
t.RUnlock()
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) Pop() (T, bool) {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
return t.uss.Pop()
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) ToSlice() []T {
|
||||
keys := make([]T, 0, t.Cardinality())
|
||||
t.RLock()
|
||||
for elem := range *t.uss {
|
||||
keys = append(keys, elem)
|
||||
}
|
||||
t.RUnlock()
|
||||
return keys
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) MarshalJSON() ([]byte, error) {
|
||||
t.RLock()
|
||||
b, err := t.uss.MarshalJSON()
|
||||
t.RUnlock()
|
||||
|
||||
return b, err
|
||||
}
|
||||
|
||||
func (t *threadSafeSet[T]) UnmarshalJSON(p []byte) error {
|
||||
t.RLock()
|
||||
err := t.uss.UnmarshalJSON(p)
|
||||
t.RUnlock()
|
||||
|
||||
return err
|
||||
}
|
||||
352
vendor/github.com/deckarep/golang-set/v2/threadunsafe.go
generated
vendored
352
vendor/github.com/deckarep/golang-set/v2/threadunsafe.go
generated
vendored
@@ -1,352 +0,0 @@
|
||||
/*
|
||||
Open Source Initiative OSI - The MIT License (MIT):Licensing
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2013 - 2022 Ralph Caraveo (deckarep@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package mapset
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type threadUnsafeSet[T comparable] map[T]struct{}
|
||||
|
||||
// Assert concrete type:threadUnsafeSet adheres to Set interface.
|
||||
var _ Set[string] = (*threadUnsafeSet[string])(nil)
|
||||
|
||||
func newThreadUnsafeSet[T comparable]() *threadUnsafeSet[T] {
|
||||
t := make(threadUnsafeSet[T])
|
||||
return &t
|
||||
}
|
||||
|
||||
func newThreadUnsafeSetWithSize[T comparable](cardinality int) *threadUnsafeSet[T] {
|
||||
t := make(threadUnsafeSet[T], cardinality)
|
||||
return &t
|
||||
}
|
||||
|
||||
func (s threadUnsafeSet[T]) Add(v T) bool {
|
||||
prevLen := len(s)
|
||||
s[v] = struct{}{}
|
||||
return prevLen != len(s)
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) Append(v ...T) int {
|
||||
prevLen := len(*s)
|
||||
for _, val := range v {
|
||||
(*s)[val] = struct{}{}
|
||||
}
|
||||
return len(*s) - prevLen
|
||||
}
|
||||
|
||||
// private version of Add which doesn't return a value
|
||||
func (s *threadUnsafeSet[T]) add(v T) {
|
||||
(*s)[v] = struct{}{}
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) Cardinality() int {
|
||||
return len(*s)
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) Clear() {
|
||||
// Constructions like this are optimised by compiler, and replaced by
|
||||
// mapclear() function, defined in
|
||||
// https://github.com/golang/go/blob/29bbca5c2c1ad41b2a9747890d183b6dd3a4ace4/src/runtime/map.go#L993)
|
||||
for key := range *s {
|
||||
delete(*s, key)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) Clone() Set[T] {
|
||||
clonedSet := newThreadUnsafeSetWithSize[T](s.Cardinality())
|
||||
for elem := range *s {
|
||||
clonedSet.add(elem)
|
||||
}
|
||||
return clonedSet
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) Contains(v ...T) bool {
|
||||
for _, val := range v {
|
||||
if _, ok := (*s)[val]; !ok {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) ContainsOne(v T) bool {
|
||||
_, ok := (*s)[v]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) ContainsAny(v ...T) bool {
|
||||
for _, val := range v {
|
||||
if _, ok := (*s)[val]; ok {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) ContainsAnyElement(other Set[T]) bool {
|
||||
o := other.(*threadUnsafeSet[T])
|
||||
|
||||
// loop over smaller set
|
||||
if s.Cardinality() < other.Cardinality() {
|
||||
for elem := range *s {
|
||||
if o.contains(elem) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for elem := range *o {
|
||||
if s.contains(elem) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// private version of Contains for a single element v
|
||||
func (s *threadUnsafeSet[T]) contains(v T) (ok bool) {
|
||||
_, ok = (*s)[v]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) Difference(other Set[T]) Set[T] {
|
||||
o := other.(*threadUnsafeSet[T])
|
||||
|
||||
diff := newThreadUnsafeSet[T]()
|
||||
for elem := range *s {
|
||||
if !o.contains(elem) {
|
||||
diff.add(elem)
|
||||
}
|
||||
}
|
||||
return diff
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) Each(cb func(T) bool) {
|
||||
for elem := range *s {
|
||||
if cb(elem) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) Equal(other Set[T]) bool {
|
||||
o := other.(*threadUnsafeSet[T])
|
||||
|
||||
if s.Cardinality() != other.Cardinality() {
|
||||
return false
|
||||
}
|
||||
for elem := range *s {
|
||||
if !o.contains(elem) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) Intersect(other Set[T]) Set[T] {
|
||||
o := other.(*threadUnsafeSet[T])
|
||||
|
||||
intersection := newThreadUnsafeSet[T]()
|
||||
// loop over smaller set
|
||||
if s.Cardinality() < other.Cardinality() {
|
||||
for elem := range *s {
|
||||
if o.contains(elem) {
|
||||
intersection.add(elem)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for elem := range *o {
|
||||
if s.contains(elem) {
|
||||
intersection.add(elem)
|
||||
}
|
||||
}
|
||||
}
|
||||
return intersection
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) IsEmpty() bool {
|
||||
return s.Cardinality() == 0
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) IsProperSubset(other Set[T]) bool {
|
||||
return s.Cardinality() < other.Cardinality() && s.IsSubset(other)
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) IsProperSuperset(other Set[T]) bool {
|
||||
return s.Cardinality() > other.Cardinality() && s.IsSuperset(other)
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) IsSubset(other Set[T]) bool {
|
||||
o := other.(*threadUnsafeSet[T])
|
||||
if s.Cardinality() > other.Cardinality() {
|
||||
return false
|
||||
}
|
||||
for elem := range *s {
|
||||
if !o.contains(elem) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) IsSuperset(other Set[T]) bool {
|
||||
return other.IsSubset(s)
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) Iter() <-chan T {
|
||||
ch := make(chan T)
|
||||
go func() {
|
||||
for elem := range *s {
|
||||
ch <- elem
|
||||
}
|
||||
close(ch)
|
||||
}()
|
||||
|
||||
return ch
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) Iterator() *Iterator[T] {
|
||||
iterator, ch, stopCh := newIterator[T]()
|
||||
|
||||
go func() {
|
||||
L:
|
||||
for elem := range *s {
|
||||
select {
|
||||
case <-stopCh:
|
||||
break L
|
||||
case ch <- elem:
|
||||
}
|
||||
}
|
||||
close(ch)
|
||||
}()
|
||||
|
||||
return iterator
|
||||
}
|
||||
|
||||
// Pop returns a popped item in case set is not empty, or nil-value of T
|
||||
// if set is already empty
|
||||
func (s *threadUnsafeSet[T]) Pop() (v T, ok bool) {
|
||||
for item := range *s {
|
||||
delete(*s, item)
|
||||
return item, true
|
||||
}
|
||||
return v, false
|
||||
}
|
||||
|
||||
func (s threadUnsafeSet[T]) Remove(v T) {
|
||||
delete(s, v)
|
||||
}
|
||||
|
||||
func (s threadUnsafeSet[T]) RemoveAll(i ...T) {
|
||||
for _, elem := range i {
|
||||
delete(s, elem)
|
||||
}
|
||||
}
|
||||
|
||||
func (s threadUnsafeSet[T]) String() string {
|
||||
items := make([]string, 0, len(s))
|
||||
|
||||
for elem := range s {
|
||||
items = append(items, fmt.Sprintf("%v", elem))
|
||||
}
|
||||
return fmt.Sprintf("Set{%s}", strings.Join(items, ", "))
|
||||
}
|
||||
|
||||
func (s *threadUnsafeSet[T]) SymmetricDifference(other Set[T]) Set[T] {
|
||||
o := other.(*threadUnsafeSet[T])
|
||||
|
||||
sd := newThreadUnsafeSet[T]()
|
||||
for elem := range *s {
|
||||
if !o.contains(elem) {
|
||||
sd.add(elem)
|
||||
}
|
||||
}
|
||||
for elem := range *o {
|
||||
if !s.contains(elem) {
|
||||
sd.add(elem)
|
||||
}
|
||||
}
|
||||
return sd
|
||||
}
|
||||
|
||||
func (s threadUnsafeSet[T]) ToSlice() []T {
|
||||
keys := make([]T, 0, s.Cardinality())
|
||||
for elem := range s {
|
||||
keys = append(keys, elem)
|
||||
}
|
||||
|
||||
return keys
|
||||
}
|
||||
|
||||
func (s threadUnsafeSet[T]) Union(other Set[T]) Set[T] {
|
||||
o := other.(*threadUnsafeSet[T])
|
||||
|
||||
n := s.Cardinality()
|
||||
if o.Cardinality() > n {
|
||||
n = o.Cardinality()
|
||||
}
|
||||
unionedSet := make(threadUnsafeSet[T], n)
|
||||
|
||||
for elem := range s {
|
||||
unionedSet.add(elem)
|
||||
}
|
||||
for elem := range *o {
|
||||
unionedSet.add(elem)
|
||||
}
|
||||
return &unionedSet
|
||||
}
|
||||
|
||||
// MarshalJSON creates a JSON array from the set, it marshals all elements
|
||||
func (s threadUnsafeSet[T]) MarshalJSON() ([]byte, error) {
|
||||
items := make([]string, 0, s.Cardinality())
|
||||
|
||||
for elem := range s {
|
||||
b, err := json.Marshal(elem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
items = append(items, string(b))
|
||||
}
|
||||
|
||||
return []byte(fmt.Sprintf("[%s]", strings.Join(items, ","))), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON recreates a set from a JSON array, it only decodes
|
||||
// primitive types. Numbers are decoded as json.Number.
|
||||
func (s *threadUnsafeSet[T]) UnmarshalJSON(b []byte) error {
|
||||
var i []T
|
||||
err := json.Unmarshal(b, &i)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Append(i...)
|
||||
|
||||
return nil
|
||||
}
|
||||
3
vendor/modules.txt
vendored
3
vendor/modules.txt
vendored
@@ -589,9 +589,6 @@ github.com/cyphar/filepath-securejoin/pathrs-lite/procfs
|
||||
# github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
|
||||
## explicit
|
||||
github.com/davecgh/go-spew/spew
|
||||
# github.com/deckarep/golang-set/v2 v2.8.0
|
||||
## explicit; go 1.18
|
||||
github.com/deckarep/golang-set/v2
|
||||
# github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352
|
||||
## explicit; go 1.13
|
||||
github.com/digitorus/pkcs7
|
||||
|
||||
Reference in New Issue
Block a user