java-topology/defects/cilium/patch/0001-requirement-hasvalue-use-map-set.patch

81 lines
2.9 KiB
Diff

# UNDF: UNDF-2026-000000030
diff --git a/pkg/k8s/slim/k8s/apis/labels/selector.go b/pkg/k8s/slim/k8s/apis/labels/selector.go
index 1234567..abcdef0 100644
--- a/pkg/k8s/slim/k8s/apis/labels/selector.go
+++ b/pkg/k8s/slim/k8s/apis/labels/selector.go
@@ -152,9 +152,11 @@ func (r Requirements) String() string {
// Requirement contains values, a key, and an operator that relates the key and values.
// The zero value of Requirement is invalid.
// Requirement implements both set based match and exact match.
// Requirement should be initialized via NewRequirement constructor for creating a valid Requirement.
type Requirement struct {
key string
operator selection.Operator
- // In huge majority of cases we have at most one value here.
- // It is generally faster to operate on a single-element slice
- // than on a single-element map, so we have a slice here.
- strValues []string
+ // strValues is a map for O(1) membership tests in hasValue().
+ // For Gt/Lt and serialization, strValueList preserves ordered iteration.
+ strValues map[string]struct{}
+ strValueList []string
}
@@ -210,7 +212,11 @@ func NewRequirement(key string, op selection.Operator, vals []string, opts ...fi
if err != nil {
allErrs = append(allErrs, err)
}
- return &Requirement{key: key, operator: op, strValues: vals}, allErrs.ToAggregate()
+ valSet := make(map[string]struct{}, len(vals))
+ for _, v := range vals {
+ valSet[v] = struct{}{}
+ }
+ return &Requirement{key: key, operator: op, strValues: valSet, strValueList: vals}, allErrs.ToAggregate()
}
@@ -216,7 +222,8 @@ func NewRequirement(key string, op selection.Operator, vals []string, opts ...fi
-func (r *Requirement) hasValue(value string) bool {
- return slices.Contains(r.strValues, value)
+// hasValue is O(1) via map lookup instead of O(n) slices.Contains.
+func (r *Requirement) hasValue(value string) bool {
+ _, ok := r.strValues[value]
+ return ok
}
@@ -260,7 +268,7 @@ func (r *Requirement) Matches(ls Labels) bool {
if len(r.strValues) != 1 {
...
}
- for i := range r.strValues {
- rValue, err = strconv.ParseInt(r.strValues[i], 10, 64)
+ for _, v := range r.strValueList {
+ rValue, err = strconv.ParseInt(v, 10, 64)
...
}
@@ -293,8 +301,8 @@ func (r *Requirement) Values() sets.String {
ret := sets.String{}
- for i := range r.strValues {
- ret.Insert(r.strValues[i])
+ for v := range r.strValues {
+ ret.Insert(v)
}
return ret
}
@@ -301,8 +309,7 @@ func (r *Requirement) ValuesUnsorted() []string {
- ret := make([]string, 0, len(r.strValues))
- ret = append(ret, r.strValues...)
- return ret
+ return append([]string(nil), r.strValueList...)
}
@@ -309,5 +317,5 @@ func (r *Requirement) String() string {
- return r.strValues
+ return r.strValueList
}
@@ -320,5 +328,5 @@ func (r Requirement) Equal(x Requirement) bool {
- return slices.Equal(r.strValues, x.strValues)
+ return slices.Equal(r.strValueList, x.strValueList)
}