mirror of
https://github.com/kubernetes-csi/csi-driver-nvmf.git
synced 2025-09-01 13:17:15 +00:00
feat: implement volume allocation and release in device registry
Signed-off-by: cheolho.kang <cheolho.kang@samsung.com>
This commit is contained in:
1
go.mod
1
go.mod
@@ -7,6 +7,7 @@ require (
|
||||
github.com/kubernetes-csi/csi-lib-utils v0.13.0
|
||||
golang.org/x/net v0.5.0
|
||||
google.golang.org/grpc v1.51.0
|
||||
k8s.io/apimachinery v0.26.0
|
||||
k8s.io/klog/v2 v2.80.1
|
||||
k8s.io/utils v0.0.0-20230209194617-a36077c30491
|
||||
)
|
||||
|
2
go.sum
2
go.sum
@@ -148,6 +148,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
k8s.io/apimachinery v0.26.0 h1:1feANjElT7MvPqp0JT6F3Ss6TWDwmcjLypwoPpEf7zg=
|
||||
k8s.io/apimachinery v0.26.0/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74=
|
||||
k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
|
||||
k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY=
|
||||
|
@@ -25,6 +25,10 @@ import (
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
const (
|
||||
UseActualDeviceCapacity int64 = 0 // Use the actual device capacity
|
||||
)
|
||||
|
||||
type ControllerServer struct {
|
||||
Driver *driver
|
||||
deviceRegistry *DeviceRegistry
|
||||
@@ -64,11 +68,27 @@ func (c *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVolu
|
||||
return nil, status.Errorf(codes.Internal, "device discovery failed: %v", err)
|
||||
}
|
||||
|
||||
// TODO (cheolho.kang): In a future implementation, this method would:
|
||||
// 1. Allocate a device for the volume
|
||||
// 2. Store the allocation info in etcd
|
||||
// 3. Return the allocated device information in the response
|
||||
return nil, status.Errorf(codes.Unimplemented, "CreateVolume should implement by yourself. ")
|
||||
// Acquire volume lock to prevent concurrent operations
|
||||
if acquired := c.Driver.volumeLocks.TryAcquire(volumeName); !acquired {
|
||||
return nil, status.Errorf(codes.Aborted, "concurrent operation in progress for volume: %s", volumeName)
|
||||
}
|
||||
defer c.Driver.volumeLocks.Release(volumeName)
|
||||
|
||||
// Allocate a device
|
||||
allocatedDevice, err := c.deviceRegistry.AllocateDevice(volumeName)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to allocate device for volume %s: %v", volumeName, err)
|
||||
return nil, status.Errorf(codes.ResourceExhausted, "no suitable device available: %v", err)
|
||||
}
|
||||
|
||||
return &csi.CreateVolumeResponse{
|
||||
Volume: &csi.Volume{
|
||||
VolumeId: allocatedDevice.Nqn,
|
||||
CapacityBytes: UseActualDeviceCapacity, // PV will use the actual capacity
|
||||
VolumeContext: parameters,
|
||||
ContentSource: req.GetVolumeContentSource(),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteVolume deletes a volume
|
||||
@@ -80,7 +100,20 @@ func (c *ControllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVolu
|
||||
|
||||
klog.V(4).Infof("DeleteVolume called for volume ID %s", volumeID)
|
||||
|
||||
return nil, status.Errorf(codes.Unimplemented, "DeleteVolume should implement by yourself. ")
|
||||
// Acquire lock to prevent concurrent operations on this volume
|
||||
if acquired := c.Driver.volumeLocks.TryAcquire(volumeID); !acquired {
|
||||
return nil, status.Errorf(codes.Aborted, "concurrent operation in progress for volume: %s", volumeID)
|
||||
}
|
||||
defer c.Driver.volumeLocks.Release(volumeID)
|
||||
|
||||
// Find the volume by NQN
|
||||
// Note: volumeID is expected to be in NQN (NVMe Qualified Name) format.
|
||||
// This assumption is valid because in CreateVolume, we assigned the device's NQN
|
||||
// as the volumeID when returning the CreateVolumeResponse.
|
||||
nqn := volumeID
|
||||
c.deviceRegistry.ReleaseDevice(nqn)
|
||||
|
||||
return &csi.DeleteVolumeResponse{}, nil
|
||||
}
|
||||
|
||||
func (c *ControllerServer) ControllerExpandVolume(ctx context.Context, req *csi.ControllerExpandVolumeRequest) (*csi.ControllerExpandVolumeResponse, error) {
|
||||
|
@@ -92,6 +92,71 @@ func (r *DeviceRegistry) DiscoverDevices(params map[string]string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// AllocateDevice selects and allocates a device for a volume
|
||||
func (r *DeviceRegistry) AllocateDevice(volumeName string) (*VolumeInfo, error) {
|
||||
r.mutex.Lock()
|
||||
defer r.mutex.Unlock()
|
||||
|
||||
// Check this volume is already allocated
|
||||
if nqn, exists := r.volumeToNQN[volumeName]; exists {
|
||||
return nil, fmt.Errorf("already allocated. PV: %s, device: %s", volumeName, nqn)
|
||||
}
|
||||
|
||||
// Check if any devices are available
|
||||
if len(r.availableNQNs) == 0 {
|
||||
return nil, fmt.Errorf("no available devices found")
|
||||
}
|
||||
|
||||
var nqn string
|
||||
for n := range r.availableNQNs {
|
||||
if r.devices[n].IsAllocated {
|
||||
klog.Errorf("Device %s is marked as available but is already allocated. Device details: %+v", n, r.devices[n])
|
||||
continue
|
||||
}
|
||||
|
||||
nqn = n
|
||||
break
|
||||
}
|
||||
|
||||
if nqn == "" {
|
||||
return nil, fmt.Errorf("no available devices found")
|
||||
}
|
||||
|
||||
// Update tracking maps
|
||||
delete(r.availableNQNs, nqn)
|
||||
r.volumeToNQN[volumeName] = nqn
|
||||
device := r.devices[nqn]
|
||||
device.VolName = volumeName
|
||||
device.IsAllocated = true
|
||||
|
||||
klog.V(4).Infof("[%d/%d] Allocated volume %s (NQN %s)", len(r.devices) - len(r.availableNQNs), len(r.devices), volumeName, nqn)
|
||||
|
||||
return device, nil
|
||||
}
|
||||
|
||||
// ReleaseDevice releases a device allocation
|
||||
func (r *DeviceRegistry) ReleaseDevice(nqn string) {
|
||||
r.mutex.Lock()
|
||||
defer r.mutex.Unlock()
|
||||
|
||||
|
||||
device, exists := r.devices[nqn]
|
||||
if !exists {
|
||||
// CSI spec requires idempotency: return success even if volume doesn't exist
|
||||
// This allows safe retries and prevents errors when volume was already deleted
|
||||
klog.Infof("Volume %s not found", nqn)
|
||||
return
|
||||
}
|
||||
|
||||
// Update tracking maps
|
||||
device.IsAllocated = false
|
||||
delete(r.volumeToNQN, device.VolName)
|
||||
r.availableNQNs[nqn] = struct{}{}
|
||||
device.VolName = ""
|
||||
|
||||
klog.V(4).Infof("[%d/%d] Released volume %s", len(r.devices) - len(r.availableNQNs), len(r.devices), nqn)
|
||||
}
|
||||
|
||||
// discoverNVMeDevices runs NVMe discovery and returns available targets
|
||||
func discoverNVMeDevices(params map[string]string) (map[string]*nvmfDiskInfo, error) {
|
||||
if params == nil {
|
||||
|
@@ -21,6 +21,8 @@ import (
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/kubernetes-csi/csi-driver-nvmf/pkg/utils"
|
||||
)
|
||||
|
||||
type driver struct {
|
||||
@@ -30,6 +32,7 @@ type driver struct {
|
||||
|
||||
region string
|
||||
volumeMapDir string
|
||||
volumeLocks *utils.VolumeLocks
|
||||
|
||||
idServer *IdentityServer
|
||||
nodeServer *NodeServer
|
||||
@@ -53,6 +56,7 @@ func NewDriver(conf *GlobalConfig) *driver {
|
||||
nodeId: conf.NodeID,
|
||||
region: conf.Region,
|
||||
volumeMapDir: conf.NVMfVolumeMapDir,
|
||||
volumeLocks: utils.NewVolumeLocks(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -22,8 +22,22 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
)
|
||||
|
||||
type VolumeLocks struct {
|
||||
locks sets.String //nolint:staticcheck
|
||||
mux sync.Mutex
|
||||
}
|
||||
|
||||
func NewVolumeLocks() *VolumeLocks {
|
||||
return &VolumeLocks{
|
||||
locks: sets.NewString(),
|
||||
}
|
||||
}
|
||||
|
||||
// IsFileExisting check file exist in volume driver
|
||||
func IsFileExisting(filename string) bool {
|
||||
_, err := os.Stat(filename)
|
||||
@@ -37,6 +51,22 @@ func IsFileExisting(filename string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (vl *VolumeLocks) TryAcquire(volumeID string) bool {
|
||||
vl.mux.Lock()
|
||||
defer vl.mux.Unlock()
|
||||
if vl.locks.Has(volumeID) {
|
||||
return false
|
||||
}
|
||||
vl.locks.Insert(volumeID)
|
||||
return true
|
||||
}
|
||||
|
||||
func (vl *VolumeLocks) Release(volumeID string) {
|
||||
vl.mux.Lock()
|
||||
defer vl.mux.Unlock()
|
||||
vl.locks.Delete(volumeID)
|
||||
}
|
||||
|
||||
func ParseEndpoint(ep string) (string, string, error) {
|
||||
if strings.HasPrefix(strings.ToLower(ep), "unix://") || strings.HasPrefix(strings.ToLower(ep), "tcp://") {
|
||||
s := strings.SplitN(ep, "://", 2)
|
||||
|
202
vendor/k8s.io/apimachinery/LICENSE
generated
vendored
Normal file
202
vendor/k8s.io/apimachinery/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
137
vendor/k8s.io/apimachinery/pkg/util/sets/byte.go
generated
vendored
Normal file
137
vendor/k8s.io/apimachinery/pkg/util/sets/byte.go
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
Copyright 2022 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package sets
|
||||
|
||||
// Byte is a set of bytes, implemented via map[byte]struct{} for minimal memory consumption.
|
||||
//
|
||||
// Deprecated: use generic Set instead.
|
||||
// new ways:
|
||||
// s1 := Set[byte]{}
|
||||
// s2 := New[byte]()
|
||||
type Byte map[byte]Empty
|
||||
|
||||
// NewByte creates a Byte from a list of values.
|
||||
func NewByte(items ...byte) Byte {
|
||||
return Byte(New[byte](items...))
|
||||
}
|
||||
|
||||
// ByteKeySet creates a Byte from a keys of a map[byte](? extends interface{}).
|
||||
// If the value passed in is not actually a map, this will panic.
|
||||
func ByteKeySet[T any](theMap map[byte]T) Byte {
|
||||
return Byte(KeySet(theMap))
|
||||
}
|
||||
|
||||
// Insert adds items to the set.
|
||||
func (s Byte) Insert(items ...byte) Byte {
|
||||
return Byte(cast(s).Insert(items...))
|
||||
}
|
||||
|
||||
// Delete removes all items from the set.
|
||||
func (s Byte) Delete(items ...byte) Byte {
|
||||
return Byte(cast(s).Delete(items...))
|
||||
}
|
||||
|
||||
// Has returns true if and only if item is contained in the set.
|
||||
func (s Byte) Has(item byte) bool {
|
||||
return cast(s).Has(item)
|
||||
}
|
||||
|
||||
// HasAll returns true if and only if all items are contained in the set.
|
||||
func (s Byte) HasAll(items ...byte) bool {
|
||||
return cast(s).HasAll(items...)
|
||||
}
|
||||
|
||||
// HasAny returns true if any items are contained in the set.
|
||||
func (s Byte) HasAny(items ...byte) bool {
|
||||
return cast(s).HasAny(items...)
|
||||
}
|
||||
|
||||
// Clone returns a new set which is a copy of the current set.
|
||||
func (s Byte) Clone() Byte {
|
||||
return Byte(cast(s).Clone())
|
||||
}
|
||||
|
||||
// Difference returns a set of objects that are not in s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.Difference(s2) = {a3}
|
||||
// s2.Difference(s1) = {a4, a5}
|
||||
func (s1 Byte) Difference(s2 Byte) Byte {
|
||||
return Byte(cast(s1).Difference(cast(s2)))
|
||||
}
|
||||
|
||||
// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection.
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.SymmetricDifference(s2) = {a3, a4, a5}
|
||||
// s2.SymmetricDifference(s1) = {a3, a4, a5}
|
||||
func (s1 Byte) SymmetricDifference(s2 Byte) Byte {
|
||||
return Byte(cast(s1).SymmetricDifference(cast(s2)))
|
||||
}
|
||||
|
||||
// Union returns a new set which includes items in either s1 or s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a3, a4}
|
||||
// s1.Union(s2) = {a1, a2, a3, a4}
|
||||
// s2.Union(s1) = {a1, a2, a3, a4}
|
||||
func (s1 Byte) Union(s2 Byte) Byte {
|
||||
return Byte(cast(s1).Union(cast(s2)))
|
||||
}
|
||||
|
||||
// Intersection returns a new set which includes the item in BOTH s1 and s2
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a2, a3}
|
||||
// s1.Intersection(s2) = {a2}
|
||||
func (s1 Byte) Intersection(s2 Byte) Byte {
|
||||
return Byte(cast(s1).Intersection(cast(s2)))
|
||||
}
|
||||
|
||||
// IsSuperset returns true if and only if s1 is a superset of s2.
|
||||
func (s1 Byte) IsSuperset(s2 Byte) bool {
|
||||
return cast(s1).IsSuperset(cast(s2))
|
||||
}
|
||||
|
||||
// Equal returns true if and only if s1 is equal (as a set) to s2.
|
||||
// Two sets are equal if their membership is identical.
|
||||
// (In practice, this means same elements, order doesn't matter)
|
||||
func (s1 Byte) Equal(s2 Byte) bool {
|
||||
return cast(s1).Equal(cast(s2))
|
||||
}
|
||||
|
||||
// List returns the contents as a sorted byte slice.
|
||||
func (s Byte) List() []byte {
|
||||
return List(cast(s))
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s Byte) UnsortedList() []byte {
|
||||
return cast(s).UnsortedList()
|
||||
}
|
||||
|
||||
// PopAny returns a single element from the set.
|
||||
func (s Byte) PopAny() (byte, bool) {
|
||||
return cast(s).PopAny()
|
||||
}
|
||||
|
||||
// Len returns the size of the set.
|
||||
func (s Byte) Len() int {
|
||||
return len(s)
|
||||
}
|
19
vendor/k8s.io/apimachinery/pkg/util/sets/doc.go
generated
vendored
Normal file
19
vendor/k8s.io/apimachinery/pkg/util/sets/doc.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
Copyright 2022 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package sets has generic set and specified sets. Generic set will
|
||||
// replace specified ones over time. And specific ones are deprecated.
|
||||
package sets
|
21
vendor/k8s.io/apimachinery/pkg/util/sets/empty.go
generated
vendored
Normal file
21
vendor/k8s.io/apimachinery/pkg/util/sets/empty.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
Copyright 2022 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package sets
|
||||
|
||||
// Empty is public since it is used by some internal API objects for conversions between external
|
||||
// string arrays and internal sets, and conversion logic requires public types today.
|
||||
type Empty struct{}
|
137
vendor/k8s.io/apimachinery/pkg/util/sets/int.go
generated
vendored
Normal file
137
vendor/k8s.io/apimachinery/pkg/util/sets/int.go
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
Copyright 2022 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package sets
|
||||
|
||||
// Int is a set of ints, implemented via map[int]struct{} for minimal memory consumption.
|
||||
//
|
||||
// Deprecated: use generic Set instead.
|
||||
// new ways:
|
||||
// s1 := Set[int]{}
|
||||
// s2 := New[int]()
|
||||
type Int map[int]Empty
|
||||
|
||||
// NewInt creates a Int from a list of values.
|
||||
func NewInt(items ...int) Int {
|
||||
return Int(New[int](items...))
|
||||
}
|
||||
|
||||
// IntKeySet creates a Int from a keys of a map[int](? extends interface{}).
|
||||
// If the value passed in is not actually a map, this will panic.
|
||||
func IntKeySet[T any](theMap map[int]T) Int {
|
||||
return Int(KeySet(theMap))
|
||||
}
|
||||
|
||||
// Insert adds items to the set.
|
||||
func (s Int) Insert(items ...int) Int {
|
||||
return Int(cast(s).Insert(items...))
|
||||
}
|
||||
|
||||
// Delete removes all items from the set.
|
||||
func (s Int) Delete(items ...int) Int {
|
||||
return Int(cast(s).Delete(items...))
|
||||
}
|
||||
|
||||
// Has returns true if and only if item is contained in the set.
|
||||
func (s Int) Has(item int) bool {
|
||||
return cast(s).Has(item)
|
||||
}
|
||||
|
||||
// HasAll returns true if and only if all items are contained in the set.
|
||||
func (s Int) HasAll(items ...int) bool {
|
||||
return cast(s).HasAll(items...)
|
||||
}
|
||||
|
||||
// HasAny returns true if any items are contained in the set.
|
||||
func (s Int) HasAny(items ...int) bool {
|
||||
return cast(s).HasAny(items...)
|
||||
}
|
||||
|
||||
// Clone returns a new set which is a copy of the current set.
|
||||
func (s Int) Clone() Int {
|
||||
return Int(cast(s).Clone())
|
||||
}
|
||||
|
||||
// Difference returns a set of objects that are not in s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.Difference(s2) = {a3}
|
||||
// s2.Difference(s1) = {a4, a5}
|
||||
func (s1 Int) Difference(s2 Int) Int {
|
||||
return Int(cast(s1).Difference(cast(s2)))
|
||||
}
|
||||
|
||||
// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection.
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.SymmetricDifference(s2) = {a3, a4, a5}
|
||||
// s2.SymmetricDifference(s1) = {a3, a4, a5}
|
||||
func (s1 Int) SymmetricDifference(s2 Int) Int {
|
||||
return Int(cast(s1).SymmetricDifference(cast(s2)))
|
||||
}
|
||||
|
||||
// Union returns a new set which includes items in either s1 or s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a3, a4}
|
||||
// s1.Union(s2) = {a1, a2, a3, a4}
|
||||
// s2.Union(s1) = {a1, a2, a3, a4}
|
||||
func (s1 Int) Union(s2 Int) Int {
|
||||
return Int(cast(s1).Union(cast(s2)))
|
||||
}
|
||||
|
||||
// Intersection returns a new set which includes the item in BOTH s1 and s2
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a2, a3}
|
||||
// s1.Intersection(s2) = {a2}
|
||||
func (s1 Int) Intersection(s2 Int) Int {
|
||||
return Int(cast(s1).Intersection(cast(s2)))
|
||||
}
|
||||
|
||||
// IsSuperset returns true if and only if s1 is a superset of s2.
|
||||
func (s1 Int) IsSuperset(s2 Int) bool {
|
||||
return cast(s1).IsSuperset(cast(s2))
|
||||
}
|
||||
|
||||
// Equal returns true if and only if s1 is equal (as a set) to s2.
|
||||
// Two sets are equal if their membership is identical.
|
||||
// (In practice, this means same elements, order doesn't matter)
|
||||
func (s1 Int) Equal(s2 Int) bool {
|
||||
return cast(s1).Equal(cast(s2))
|
||||
}
|
||||
|
||||
// List returns the contents as a sorted int slice.
|
||||
func (s Int) List() []int {
|
||||
return List(cast(s))
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s Int) UnsortedList() []int {
|
||||
return cast(s).UnsortedList()
|
||||
}
|
||||
|
||||
// PopAny returns a single element from the set.
|
||||
func (s Int) PopAny() (int, bool) {
|
||||
return cast(s).PopAny()
|
||||
}
|
||||
|
||||
// Len returns the size of the set.
|
||||
func (s Int) Len() int {
|
||||
return len(s)
|
||||
}
|
137
vendor/k8s.io/apimachinery/pkg/util/sets/int32.go
generated
vendored
Normal file
137
vendor/k8s.io/apimachinery/pkg/util/sets/int32.go
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
Copyright 2022 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package sets
|
||||
|
||||
// Int32 is a set of int32s, implemented via map[int32]struct{} for minimal memory consumption.
|
||||
//
|
||||
// Deprecated: use generic Set instead.
|
||||
// new ways:
|
||||
// s1 := Set[int32]{}
|
||||
// s2 := New[int32]()
|
||||
type Int32 map[int32]Empty
|
||||
|
||||
// NewInt32 creates a Int32 from a list of values.
|
||||
func NewInt32(items ...int32) Int32 {
|
||||
return Int32(New[int32](items...))
|
||||
}
|
||||
|
||||
// Int32KeySet creates a Int32 from a keys of a map[int32](? extends interface{}).
|
||||
// If the value passed in is not actually a map, this will panic.
|
||||
func Int32KeySet[T any](theMap map[int32]T) Int32 {
|
||||
return Int32(KeySet(theMap))
|
||||
}
|
||||
|
||||
// Insert adds items to the set.
|
||||
func (s Int32) Insert(items ...int32) Int32 {
|
||||
return Int32(cast(s).Insert(items...))
|
||||
}
|
||||
|
||||
// Delete removes all items from the set.
|
||||
func (s Int32) Delete(items ...int32) Int32 {
|
||||
return Int32(cast(s).Delete(items...))
|
||||
}
|
||||
|
||||
// Has returns true if and only if item is contained in the set.
|
||||
func (s Int32) Has(item int32) bool {
|
||||
return cast(s).Has(item)
|
||||
}
|
||||
|
||||
// HasAll returns true if and only if all items are contained in the set.
|
||||
func (s Int32) HasAll(items ...int32) bool {
|
||||
return cast(s).HasAll(items...)
|
||||
}
|
||||
|
||||
// HasAny returns true if any items are contained in the set.
|
||||
func (s Int32) HasAny(items ...int32) bool {
|
||||
return cast(s).HasAny(items...)
|
||||
}
|
||||
|
||||
// Clone returns a new set which is a copy of the current set.
|
||||
func (s Int32) Clone() Int32 {
|
||||
return Int32(cast(s).Clone())
|
||||
}
|
||||
|
||||
// Difference returns a set of objects that are not in s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.Difference(s2) = {a3}
|
||||
// s2.Difference(s1) = {a4, a5}
|
||||
func (s1 Int32) Difference(s2 Int32) Int32 {
|
||||
return Int32(cast(s1).Difference(cast(s2)))
|
||||
}
|
||||
|
||||
// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection.
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.SymmetricDifference(s2) = {a3, a4, a5}
|
||||
// s2.SymmetricDifference(s1) = {a3, a4, a5}
|
||||
func (s1 Int32) SymmetricDifference(s2 Int32) Int32 {
|
||||
return Int32(cast(s1).SymmetricDifference(cast(s2)))
|
||||
}
|
||||
|
||||
// Union returns a new set which includes items in either s1 or s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a3, a4}
|
||||
// s1.Union(s2) = {a1, a2, a3, a4}
|
||||
// s2.Union(s1) = {a1, a2, a3, a4}
|
||||
func (s1 Int32) Union(s2 Int32) Int32 {
|
||||
return Int32(cast(s1).Union(cast(s2)))
|
||||
}
|
||||
|
||||
// Intersection returns a new set which includes the item in BOTH s1 and s2
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a2, a3}
|
||||
// s1.Intersection(s2) = {a2}
|
||||
func (s1 Int32) Intersection(s2 Int32) Int32 {
|
||||
return Int32(cast(s1).Intersection(cast(s2)))
|
||||
}
|
||||
|
||||
// IsSuperset returns true if and only if s1 is a superset of s2.
|
||||
func (s1 Int32) IsSuperset(s2 Int32) bool {
|
||||
return cast(s1).IsSuperset(cast(s2))
|
||||
}
|
||||
|
||||
// Equal returns true if and only if s1 is equal (as a set) to s2.
|
||||
// Two sets are equal if their membership is identical.
|
||||
// (In practice, this means same elements, order doesn't matter)
|
||||
func (s1 Int32) Equal(s2 Int32) bool {
|
||||
return cast(s1).Equal(cast(s2))
|
||||
}
|
||||
|
||||
// List returns the contents as a sorted int32 slice.
|
||||
func (s Int32) List() []int32 {
|
||||
return List(cast(s))
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s Int32) UnsortedList() []int32 {
|
||||
return cast(s).UnsortedList()
|
||||
}
|
||||
|
||||
// PopAny returns a single element from the set.
|
||||
func (s Int32) PopAny() (int32, bool) {
|
||||
return cast(s).PopAny()
|
||||
}
|
||||
|
||||
// Len returns the size of the set.
|
||||
func (s Int32) Len() int {
|
||||
return len(s)
|
||||
}
|
137
vendor/k8s.io/apimachinery/pkg/util/sets/int64.go
generated
vendored
Normal file
137
vendor/k8s.io/apimachinery/pkg/util/sets/int64.go
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
Copyright 2022 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package sets
|
||||
|
||||
// Int64 is a set of int64s, implemented via map[int64]struct{} for minimal memory consumption.
|
||||
//
|
||||
// Deprecated: use generic Set instead.
|
||||
// new ways:
|
||||
// s1 := Set[int64]{}
|
||||
// s2 := New[int64]()
|
||||
type Int64 map[int64]Empty
|
||||
|
||||
// NewInt64 creates a Int64 from a list of values.
|
||||
func NewInt64(items ...int64) Int64 {
|
||||
return Int64(New[int64](items...))
|
||||
}
|
||||
|
||||
// Int64KeySet creates a Int64 from a keys of a map[int64](? extends interface{}).
|
||||
// If the value passed in is not actually a map, this will panic.
|
||||
func Int64KeySet[T any](theMap map[int64]T) Int64 {
|
||||
return Int64(KeySet(theMap))
|
||||
}
|
||||
|
||||
// Insert adds items to the set.
|
||||
func (s Int64) Insert(items ...int64) Int64 {
|
||||
return Int64(cast(s).Insert(items...))
|
||||
}
|
||||
|
||||
// Delete removes all items from the set.
|
||||
func (s Int64) Delete(items ...int64) Int64 {
|
||||
return Int64(cast(s).Delete(items...))
|
||||
}
|
||||
|
||||
// Has returns true if and only if item is contained in the set.
|
||||
func (s Int64) Has(item int64) bool {
|
||||
return cast(s).Has(item)
|
||||
}
|
||||
|
||||
// HasAll returns true if and only if all items are contained in the set.
|
||||
func (s Int64) HasAll(items ...int64) bool {
|
||||
return cast(s).HasAll(items...)
|
||||
}
|
||||
|
||||
// HasAny returns true if any items are contained in the set.
|
||||
func (s Int64) HasAny(items ...int64) bool {
|
||||
return cast(s).HasAny(items...)
|
||||
}
|
||||
|
||||
// Clone returns a new set which is a copy of the current set.
|
||||
func (s Int64) Clone() Int64 {
|
||||
return Int64(cast(s).Clone())
|
||||
}
|
||||
|
||||
// Difference returns a set of objects that are not in s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.Difference(s2) = {a3}
|
||||
// s2.Difference(s1) = {a4, a5}
|
||||
func (s1 Int64) Difference(s2 Int64) Int64 {
|
||||
return Int64(cast(s1).Difference(cast(s2)))
|
||||
}
|
||||
|
||||
// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection.
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.SymmetricDifference(s2) = {a3, a4, a5}
|
||||
// s2.SymmetricDifference(s1) = {a3, a4, a5}
|
||||
func (s1 Int64) SymmetricDifference(s2 Int64) Int64 {
|
||||
return Int64(cast(s1).SymmetricDifference(cast(s2)))
|
||||
}
|
||||
|
||||
// Union returns a new set which includes items in either s1 or s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a3, a4}
|
||||
// s1.Union(s2) = {a1, a2, a3, a4}
|
||||
// s2.Union(s1) = {a1, a2, a3, a4}
|
||||
func (s1 Int64) Union(s2 Int64) Int64 {
|
||||
return Int64(cast(s1).Union(cast(s2)))
|
||||
}
|
||||
|
||||
// Intersection returns a new set which includes the item in BOTH s1 and s2
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a2, a3}
|
||||
// s1.Intersection(s2) = {a2}
|
||||
func (s1 Int64) Intersection(s2 Int64) Int64 {
|
||||
return Int64(cast(s1).Intersection(cast(s2)))
|
||||
}
|
||||
|
||||
// IsSuperset returns true if and only if s1 is a superset of s2.
|
||||
func (s1 Int64) IsSuperset(s2 Int64) bool {
|
||||
return cast(s1).IsSuperset(cast(s2))
|
||||
}
|
||||
|
||||
// Equal returns true if and only if s1 is equal (as a set) to s2.
|
||||
// Two sets are equal if their membership is identical.
|
||||
// (In practice, this means same elements, order doesn't matter)
|
||||
func (s1 Int64) Equal(s2 Int64) bool {
|
||||
return cast(s1).Equal(cast(s2))
|
||||
}
|
||||
|
||||
// List returns the contents as a sorted int64 slice.
|
||||
func (s Int64) List() []int64 {
|
||||
return List(cast(s))
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s Int64) UnsortedList() []int64 {
|
||||
return cast(s).UnsortedList()
|
||||
}
|
||||
|
||||
// PopAny returns a single element from the set.
|
||||
func (s Int64) PopAny() (int64, bool) {
|
||||
return cast(s).PopAny()
|
||||
}
|
||||
|
||||
// Len returns the size of the set.
|
||||
func (s Int64) Len() int {
|
||||
return len(s)
|
||||
}
|
53
vendor/k8s.io/apimachinery/pkg/util/sets/ordered.go
generated
vendored
Normal file
53
vendor/k8s.io/apimachinery/pkg/util/sets/ordered.go
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright 2022 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package sets
|
||||
|
||||
// ordered is a constraint that permits any ordered type: any type
|
||||
// that supports the operators < <= >= >.
|
||||
// If future releases of Go add new ordered types,
|
||||
// this constraint will be modified to include them.
|
||||
type ordered interface {
|
||||
integer | float | ~string
|
||||
}
|
||||
|
||||
// integer is a constraint that permits any integer type.
|
||||
// If future releases of Go add new predeclared integer types,
|
||||
// this constraint will be modified to include them.
|
||||
type integer interface {
|
||||
signed | unsigned
|
||||
}
|
||||
|
||||
// float is a constraint that permits any floating-point type.
|
||||
// If future releases of Go add new predeclared floating-point types,
|
||||
// this constraint will be modified to include them.
|
||||
type float interface {
|
||||
~float32 | ~float64
|
||||
}
|
||||
|
||||
// signed is a constraint that permits any signed integer type.
|
||||
// If future releases of Go add new predeclared signed integer types,
|
||||
// this constraint will be modified to include them.
|
||||
type signed interface {
|
||||
~int | ~int8 | ~int16 | ~int32 | ~int64
|
||||
}
|
||||
|
||||
// unsigned is a constraint that permits any unsigned integer type.
|
||||
// If future releases of Go add new predeclared unsigned integer types,
|
||||
// this constraint will be modified to include them.
|
||||
type unsigned interface {
|
||||
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
|
||||
}
|
227
vendor/k8s.io/apimachinery/pkg/util/sets/set.go
generated
vendored
Normal file
227
vendor/k8s.io/apimachinery/pkg/util/sets/set.go
generated
vendored
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
Copyright 2022 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package sets
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Set is a set of the same type elements, implemented via map[comparable]struct{} for minimal memory consumption.
|
||||
type Set[T comparable] map[T]Empty
|
||||
|
||||
// cast transforms specified set to generic Set[T].
|
||||
func cast[T comparable](s map[T]Empty) Set[T] { return s }
|
||||
|
||||
// New creates a Set from a list of values.
|
||||
// NOTE: type param must be explicitly instantiated if given items are empty.
|
||||
func New[T comparable](items ...T) Set[T] {
|
||||
ss := make(Set[T], len(items))
|
||||
ss.Insert(items...)
|
||||
return ss
|
||||
}
|
||||
|
||||
// KeySet creates a Set from a keys of a map[comparable](? extends interface{}).
|
||||
// If the value passed in is not actually a map, this will panic.
|
||||
func KeySet[T comparable, V any](theMap map[T]V) Set[T] {
|
||||
ret := Set[T]{}
|
||||
for keyValue := range theMap {
|
||||
ret.Insert(keyValue)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Insert adds items to the set.
|
||||
func (s Set[T]) Insert(items ...T) Set[T] {
|
||||
for _, item := range items {
|
||||
s[item] = Empty{}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func Insert[T comparable](set Set[T], items ...T) Set[T] {
|
||||
return set.Insert(items...)
|
||||
}
|
||||
|
||||
// Delete removes all items from the set.
|
||||
func (s Set[T]) Delete(items ...T) Set[T] {
|
||||
for _, item := range items {
|
||||
delete(s, item)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Has returns true if and only if item is contained in the set.
|
||||
func (s Set[T]) Has(item T) bool {
|
||||
_, contained := s[item]
|
||||
return contained
|
||||
}
|
||||
|
||||
// HasAll returns true if and only if all items are contained in the set.
|
||||
func (s Set[T]) HasAll(items ...T) bool {
|
||||
for _, item := range items {
|
||||
if !s.Has(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// HasAny returns true if any items are contained in the set.
|
||||
func (s Set[T]) HasAny(items ...T) bool {
|
||||
for _, item := range items {
|
||||
if s.Has(item) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Clone returns a new set which is a copy of the current set.
|
||||
func (s Set[T]) Clone() Set[T] {
|
||||
result := make(Set[T], len(s))
|
||||
for key := range s {
|
||||
result.Insert(key)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Difference returns a set of objects that are not in s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.Difference(s2) = {a3}
|
||||
// s2.Difference(s1) = {a4, a5}
|
||||
func (s1 Set[T]) Difference(s2 Set[T]) Set[T] {
|
||||
result := New[T]()
|
||||
for key := range s1 {
|
||||
if !s2.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection.
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.SymmetricDifference(s2) = {a3, a4, a5}
|
||||
// s2.SymmetricDifference(s1) = {a3, a4, a5}
|
||||
func (s1 Set[T]) SymmetricDifference(s2 Set[T]) Set[T] {
|
||||
return s1.Difference(s2).Union(s2.Difference(s1))
|
||||
}
|
||||
|
||||
// Union returns a new set which includes items in either s1 or s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a3, a4}
|
||||
// s1.Union(s2) = {a1, a2, a3, a4}
|
||||
// s2.Union(s1) = {a1, a2, a3, a4}
|
||||
func (s1 Set[T]) Union(s2 Set[T]) Set[T] {
|
||||
result := s1.Clone()
|
||||
for key := range s2 {
|
||||
result.Insert(key)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Intersection returns a new set which includes the item in BOTH s1 and s2
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a2, a3}
|
||||
// s1.Intersection(s2) = {a2}
|
||||
func (s1 Set[T]) Intersection(s2 Set[T]) Set[T] {
|
||||
var walk, other Set[T]
|
||||
result := New[T]()
|
||||
if s1.Len() < s2.Len() {
|
||||
walk = s1
|
||||
other = s2
|
||||
} else {
|
||||
walk = s2
|
||||
other = s1
|
||||
}
|
||||
for key := range walk {
|
||||
if other.Has(key) {
|
||||
result.Insert(key)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// IsSuperset returns true if and only if s1 is a superset of s2.
|
||||
func (s1 Set[T]) IsSuperset(s2 Set[T]) bool {
|
||||
for item := range s2 {
|
||||
if !s1.Has(item) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Equal returns true if and only if s1 is equal (as a set) to s2.
|
||||
// Two sets are equal if their membership is identical.
|
||||
// (In practice, this means same elements, order doesn't matter)
|
||||
func (s1 Set[T]) Equal(s2 Set[T]) bool {
|
||||
return len(s1) == len(s2) && s1.IsSuperset(s2)
|
||||
}
|
||||
|
||||
type sortableSliceOfGeneric[T ordered] []T
|
||||
|
||||
func (g sortableSliceOfGeneric[T]) Len() int { return len(g) }
|
||||
func (g sortableSliceOfGeneric[T]) Less(i, j int) bool { return less[T](g[i], g[j]) }
|
||||
func (g sortableSliceOfGeneric[T]) Swap(i, j int) { g[i], g[j] = g[j], g[i] }
|
||||
|
||||
// List returns the contents as a sorted T slice.
|
||||
//
|
||||
// This is a separate function and not a method because not all types supported
|
||||
// by Generic are ordered and only those can be sorted.
|
||||
func List[T ordered](s Set[T]) []T {
|
||||
res := make(sortableSliceOfGeneric[T], 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
sort.Sort(res)
|
||||
return res
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s Set[T]) UnsortedList() []T {
|
||||
res := make([]T, 0, len(s))
|
||||
for key := range s {
|
||||
res = append(res, key)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// PopAny returns a single element from the set.
|
||||
func (s Set[T]) PopAny() (T, bool) {
|
||||
for key := range s {
|
||||
s.Delete(key)
|
||||
return key, true
|
||||
}
|
||||
var zeroValue T
|
||||
return zeroValue, false
|
||||
}
|
||||
|
||||
// Len returns the size of the set.
|
||||
func (s Set[T]) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func less[T ordered](lhs, rhs T) bool {
|
||||
return lhs < rhs
|
||||
}
|
137
vendor/k8s.io/apimachinery/pkg/util/sets/string.go
generated
vendored
Normal file
137
vendor/k8s.io/apimachinery/pkg/util/sets/string.go
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
Copyright 2022 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package sets
|
||||
|
||||
// String is a set of strings, implemented via map[string]struct{} for minimal memory consumption.
|
||||
//
|
||||
// Deprecated: use generic Set instead.
|
||||
// new ways:
|
||||
// s1 := Set[string]{}
|
||||
// s2 := New[string]()
|
||||
type String map[string]Empty
|
||||
|
||||
// NewString creates a String from a list of values.
|
||||
func NewString(items ...string) String {
|
||||
return String(New[string](items...))
|
||||
}
|
||||
|
||||
// StringKeySet creates a String from a keys of a map[string](? extends interface{}).
|
||||
// If the value passed in is not actually a map, this will panic.
|
||||
func StringKeySet[T any](theMap map[string]T) String {
|
||||
return String(KeySet(theMap))
|
||||
}
|
||||
|
||||
// Insert adds items to the set.
|
||||
func (s String) Insert(items ...string) String {
|
||||
return String(cast(s).Insert(items...))
|
||||
}
|
||||
|
||||
// Delete removes all items from the set.
|
||||
func (s String) Delete(items ...string) String {
|
||||
return String(cast(s).Delete(items...))
|
||||
}
|
||||
|
||||
// Has returns true if and only if item is contained in the set.
|
||||
func (s String) Has(item string) bool {
|
||||
return cast(s).Has(item)
|
||||
}
|
||||
|
||||
// HasAll returns true if and only if all items are contained in the set.
|
||||
func (s String) HasAll(items ...string) bool {
|
||||
return cast(s).HasAll(items...)
|
||||
}
|
||||
|
||||
// HasAny returns true if any items are contained in the set.
|
||||
func (s String) HasAny(items ...string) bool {
|
||||
return cast(s).HasAny(items...)
|
||||
}
|
||||
|
||||
// Clone returns a new set which is a copy of the current set.
|
||||
func (s String) Clone() String {
|
||||
return String(cast(s).Clone())
|
||||
}
|
||||
|
||||
// Difference returns a set of objects that are not in s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.Difference(s2) = {a3}
|
||||
// s2.Difference(s1) = {a4, a5}
|
||||
func (s1 String) Difference(s2 String) String {
|
||||
return String(cast(s1).Difference(cast(s2)))
|
||||
}
|
||||
|
||||
// SymmetricDifference returns a set of elements which are in either of the sets, but not in their intersection.
|
||||
// For example:
|
||||
// s1 = {a1, a2, a3}
|
||||
// s2 = {a1, a2, a4, a5}
|
||||
// s1.SymmetricDifference(s2) = {a3, a4, a5}
|
||||
// s2.SymmetricDifference(s1) = {a3, a4, a5}
|
||||
func (s1 String) SymmetricDifference(s2 String) String {
|
||||
return String(cast(s1).SymmetricDifference(cast(s2)))
|
||||
}
|
||||
|
||||
// Union returns a new set which includes items in either s1 or s2.
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a3, a4}
|
||||
// s1.Union(s2) = {a1, a2, a3, a4}
|
||||
// s2.Union(s1) = {a1, a2, a3, a4}
|
||||
func (s1 String) Union(s2 String) String {
|
||||
return String(cast(s1).Union(cast(s2)))
|
||||
}
|
||||
|
||||
// Intersection returns a new set which includes the item in BOTH s1 and s2
|
||||
// For example:
|
||||
// s1 = {a1, a2}
|
||||
// s2 = {a2, a3}
|
||||
// s1.Intersection(s2) = {a2}
|
||||
func (s1 String) Intersection(s2 String) String {
|
||||
return String(cast(s1).Intersection(cast(s2)))
|
||||
}
|
||||
|
||||
// IsSuperset returns true if and only if s1 is a superset of s2.
|
||||
func (s1 String) IsSuperset(s2 String) bool {
|
||||
return cast(s1).IsSuperset(cast(s2))
|
||||
}
|
||||
|
||||
// Equal returns true if and only if s1 is equal (as a set) to s2.
|
||||
// Two sets are equal if their membership is identical.
|
||||
// (In practice, this means same elements, order doesn't matter)
|
||||
func (s1 String) Equal(s2 String) bool {
|
||||
return cast(s1).Equal(cast(s2))
|
||||
}
|
||||
|
||||
// List returns the contents as a sorted string slice.
|
||||
func (s String) List() []string {
|
||||
return List(cast(s))
|
||||
}
|
||||
|
||||
// UnsortedList returns the slice with contents in random order.
|
||||
func (s String) UnsortedList() []string {
|
||||
return cast(s).UnsortedList()
|
||||
}
|
||||
|
||||
// PopAny returns a single element from the set.
|
||||
func (s String) PopAny() (string, bool) {
|
||||
return cast(s).PopAny()
|
||||
}
|
||||
|
||||
// Len returns the size of the set.
|
||||
func (s String) Len() int {
|
||||
return len(s)
|
||||
}
|
Reference in New Issue
Block a user