From cb0a46ec0e965d44aa21f932c36de2cd040afb69 Mon Sep 17 00:00:00 2001 From: Markus Lehtonen Date: Wed, 13 Dec 2023 11:38:06 +0200 Subject: [PATCH] Use generics for maps and slices --- go.mod | 2 +- pkg/apis/nfd/v1alpha1/expression.go | 6 ++---- pkg/apis/nfd/v1alpha1/feature.go | 18 ++++++---------- pkg/apis/nfd/v1alpha1/rule.go | 21 +++++++++--------- pkg/nfd-master/nfd-master.go | 33 +++++++++-------------------- pkg/nfd-worker/nfd-worker.go | 15 ++++--------- pkg/utils/flags.go | 7 +++--- pkg/utils/memory_resources.go | 5 ++--- source/pci/pci.go | 7 ++---- source/usb/usb.go | 7 ++---- 10 files changed, 42 insertions(+), 79 deletions(-) diff --git a/go.mod b/go.mod index acbbeaeda..ae84c05ba 100644 --- a/go.mod +++ b/go.mod @@ -20,6 +20,7 @@ require ( github.com/smartystreets/goconvey v1.6.4 github.com/stretchr/testify v1.8.4 github.com/vektra/errors v0.0.0-20140903201135-c64d83aba85a + golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb golang.org/x/net v0.19.0 golang.org/x/time v0.5.0 google.golang.org/grpc v1.59.0 @@ -163,7 +164,6 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect golang.org/x/crypto v0.16.0 // indirect - golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/oauth2 v0.14.0 // indirect golang.org/x/sync v0.5.0 // indirect diff --git a/pkg/apis/nfd/v1alpha1/expression.go b/pkg/apis/nfd/v1alpha1/expression.go index b80654b40..dc31efe7c 100644 --- a/pkg/apis/nfd/v1alpha1/expression.go +++ b/pkg/apis/nfd/v1alpha1/expression.go @@ -24,6 +24,7 @@ import ( "strconv" "strings" + "golang.org/x/exp/maps" "k8s.io/klog/v2" ) @@ -259,10 +260,7 @@ func (m *MatchExpression) MatchKeys(name string, keys map[string]Nil) (bool, err if klogV := klog.V(3); klogV.Enabled() { klogV.InfoS("matched keys", "matchResult", matched, "matchKey", name, "matchOp", m.Op) } else if klogV := klog.V(4); klogV.Enabled() { - k := make([]string, 0, len(keys)) - for n := range keys { - k = append(k, n) - } + k := maps.Keys(keys) sort.Strings(k) klogV.InfoS("matched keys", "matchResult", matched, "matchKey", name, "matchOp", m.Op, "inputKeys", k) } diff --git a/pkg/apis/nfd/v1alpha1/feature.go b/pkg/apis/nfd/v1alpha1/feature.go index b3a9b1d5d..a3d066bd4 100644 --- a/pkg/apis/nfd/v1alpha1/feature.go +++ b/pkg/apis/nfd/v1alpha1/feature.go @@ -16,6 +16,8 @@ limitations under the License. package v1alpha1 +import "maps" + // NewNodeFeatureSpec creates a new emprty instance of NodeFeatureSpec type, // initializing all fields to proper empty values. func NewNodeFeatureSpec() *NodeFeatureSpec { @@ -75,9 +77,7 @@ func (f *Features) InsertAttributeFeatures(domain, feature string, values map[st return } - for k, v := range values { - f.Attributes[key].Elements[k] = v - } + maps.Copy(f.Attributes[key].Elements, values) } // Exists returns a non-empty string if a feature exists. The return value is @@ -103,9 +103,7 @@ func (in *NodeFeatureSpec) MergeInto(out *NodeFeatureSpec) { if out.Labels == nil { out.Labels = make(map[string]string, len(in.Labels)) } - for key, val := range in.Labels { - out.Labels[key] = val - } + maps.Copy(out.Labels, in.Labels) } } @@ -151,9 +149,7 @@ func (in *FlagFeatureSet) MergeInto(out *FlagFeatureSet) { if out.Elements == nil { out.Elements = make(map[string]Nil, len(in.Elements)) } - for key, val := range in.Elements { - out.Elements[key] = val - } + maps.Copy(out.Elements, in.Elements) } } @@ -163,9 +159,7 @@ func (in *AttributeFeatureSet) MergeInto(out *AttributeFeatureSet) { if out.Elements == nil { out.Elements = make(map[string]string, len(in.Elements)) } - for key, val := range in.Elements { - out.Elements[key] = val - } + maps.Copy(out.Elements, in.Elements) } } diff --git a/pkg/apis/nfd/v1alpha1/rule.go b/pkg/apis/nfd/v1alpha1/rule.go index 3ac58658b..7aeac42d8 100644 --- a/pkg/apis/nfd/v1alpha1/rule.go +++ b/pkg/apis/nfd/v1alpha1/rule.go @@ -19,6 +19,8 @@ package v1alpha1 import ( "bytes" "fmt" + "maps" + "slices" "strings" "text/template" @@ -40,7 +42,6 @@ type RuleOutput struct { // Execute the rule against a set of input features. func (r *Rule) Execute(features *Features) (RuleOutput, error) { - extendedResources := make(map[string]string) labels := make(map[string]string) vars := make(map[string]string) @@ -92,18 +93,16 @@ func (r *Rule) Execute(features *Features) (RuleOutput, error) { } } - for k, v := range r.ExtendedResources { - extendedResources[k] = v - } + maps.Copy(labels, r.Labels) + maps.Copy(vars, r.Vars) - for k, v := range r.Labels { - labels[k] = v + ret := RuleOutput{ + Labels: labels, + Vars: vars, + Annotations: maps.Clone(r.Annotations), + ExtendedResources: maps.Clone(r.ExtendedResources), + Taints: slices.Clone(r.Taints), } - for k, v := range r.Vars { - vars[k] = v - } - - ret := RuleOutput{ExtendedResources: extendedResources, Labels: labels, Vars: vars, Taints: r.Taints, Annotations: r.Annotations} klog.V(2).InfoS("rule matched", "ruleName", r.Name, "ruleOutput", utils.DelayedDumper(ret)) return ret, nil } diff --git a/pkg/nfd-master/nfd-master.go b/pkg/nfd-master/nfd-master.go index 9d6fe3952..09f9582ae 100644 --- a/pkg/nfd-master/nfd-master.go +++ b/pkg/nfd-master/nfd-master.go @@ -20,6 +20,7 @@ import ( "crypto/tls" "crypto/x509" "fmt" + "maps" "net" "os" "path" @@ -477,11 +478,9 @@ func (m *nfdMaster) prune() error { if err != nil { return err } - for a := range node.Annotations { - if strings.HasPrefix(a, m.instanceAnnotation(nfdv1alpha1.AnnotationNs)) { - delete(node.Annotations, a) - } - } + maps.DeleteFunc(node.Annotations, func(k, v string) bool { + return strings.HasPrefix(k, m.instanceAnnotation(nfdv1alpha1.AnnotationNs)) + }) err = m.apihelper.UpdateNode(cli, node) if err != nil { return fmt.Errorf("failed to prune annotations from node %q: %v", node.Name, err) @@ -812,18 +811,14 @@ func (m *nfdMaster) refreshNodeFeatures(cli *kubernetes.Clientset, nodeName stri crLabels, crAnnotations, crExtendedResources, crTaints := m.processNodeFeatureRule(nodeName, features) // Mix in CR-originated labels - for k, v := range crLabels { - labels[k] = v - } + maps.Copy(labels, crLabels) // Remove labels which are intended to be extended resources via // -resource-labels or their NS is not whitelisted labels, extendedResources := m.filterFeatureLabels(labels, features) // Mix in CR-originated extended resources with -resource-labels - for k, v := range crExtendedResources { - extendedResources[k] = v - } + maps.Copy(extendedResources, crExtendedResources) extendedResources = m.filterExtendedResources(features, extendedResources) // Annotations @@ -991,15 +986,9 @@ func (m *nfdMaster) processNodeFeatureRule(nodeName string, features *nfdv1alpha e = addNsToMapKeys(ruleOut.ExtendedResources, nfdv1alpha1.ExtendedResourceNs) a = addNsToMapKeys(ruleOut.Annotations, nfdv1alpha1.FeatureAnnotationNs) } - for k, v := range l { - labels[k] = v - } - for k, v := range e { - extendedResources[k] = v - } - for k, v := range a { - annotations[k] = v - } + maps.Copy(labels, l) + maps.Copy(extendedResources, e) + maps.Copy(annotations, a) // Feed back rule output to features map for subsequent rules to match features.InsertAttributeFeatures(nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Labels) @@ -1061,9 +1050,7 @@ func (m *nfdMaster) updateNodeObject(cli *kubernetes.Clientset, nodeName string, } sort.Strings(annotationKeys) annotations[m.instanceAnnotation(nfdv1alpha1.FeatureAnnotationsTrackingAnnotation)] = strings.Join(annotationKeys, ",") - for k, v := range featureAnnotations { - annotations[k] = v - } + maps.Copy(annotations, featureAnnotations) } // Create JSON patches for changes in labels and annotations diff --git a/pkg/nfd-worker/nfd-worker.go b/pkg/nfd-worker/nfd-worker.go index 9ef72573f..428b7e10f 100644 --- a/pkg/nfd-worker/nfd-worker.go +++ b/pkg/nfd-worker/nfd-worker.go @@ -28,6 +28,7 @@ import ( "strings" "time" + "golang.org/x/exp/maps" "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/credentials" @@ -415,10 +416,7 @@ func (w *nfdWorker) configureCore(c coreConfig) error { } } - w.featureSources = make([]source.FeatureSource, 0, len(featureSources)) - for _, s := range featureSources { - w.featureSources = append(w.featureSources, s) - } + w.featureSources = maps.Values(featureSources) sort.Slice(w.featureSources, func(i, j int) bool { return w.featureSources[i].Name() < w.featureSources[j].Name() }) @@ -450,10 +448,7 @@ func (w *nfdWorker) configureCore(c coreConfig) error { } } - w.labelSources = make([]source.LabelSource, 0, len(labelSources)) - for _, s := range labelSources { - w.labelSources = append(w.labelSources, s) - } + w.labelSources = maps.Values(labelSources) sort.Slice(w.labelSources, func(i, j int) bool { iP, jP := w.labelSources[i].Priority(), w.labelSources[j].Priority() @@ -560,9 +555,7 @@ func createFeatureLabels(sources []source.LabelSource, labelWhiteList regexp.Reg continue } - for name, value := range labelsFromSource { - labels[name] = value - } + maps.Copy(labels, labelsFromSource) } if klogV := klog.V(1); klogV.Enabled() { klogV.InfoS("feature discovery completed", "labels", utils.DelayedDumper(labels)) diff --git a/pkg/utils/flags.go b/pkg/utils/flags.go index ab9379c05..1038b5156 100644 --- a/pkg/utils/flags.go +++ b/pkg/utils/flags.go @@ -24,6 +24,8 @@ import ( "sort" "strings" "time" + + "golang.org/x/exp/maps" ) // RegexpVal is a wrapper for regexp command line flags @@ -77,10 +79,7 @@ func (a *StringSetVal) String() string { if *a == nil { return "" } - vals := make([]string, 0, len(*a)) - for val := range *a { - vals = append(vals, val) - } + vals := maps.Keys(*a) sort.Strings(vals) return strings.Join(vals, ",") } diff --git a/pkg/utils/memory_resources.go b/pkg/utils/memory_resources.go index ab6447a75..b969a6b21 100644 --- a/pkg/utils/memory_resources.go +++ b/pkg/utils/memory_resources.go @@ -18,6 +18,7 @@ package utils import ( "fmt" + "maps" "os" "path/filepath" "strconv" @@ -75,9 +76,7 @@ func GetNumaMemoryResources() (NumaMemoryResources, error) { return nil, err } } - for n, s := range hugepageBytes { - info[n] = s - } + maps.Copy(info, hugepageBytes) memoryResources[nodeID] = info } diff --git a/source/pci/pci.go b/source/pci/pci.go index d2c7be92d..39be031fc 100644 --- a/source/pci/pci.go +++ b/source/pci/pci.go @@ -20,6 +20,7 @@ import ( "fmt" "strings" + "golang.org/x/exp/maps" "k8s.io/klog/v2" nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1" @@ -102,11 +103,7 @@ func (s *pciSource) GetLabels() (source.FeatureLabels, error) { } } if len(configLabelFields) > 0 { - keys := []string{} - for key := range configLabelFields { - keys = append(keys, key) - } - klog.InfoS("ignoring invalid fields in deviceLabelFields", "invalidFieldNames", keys) + klog.InfoS("ignoring invalid fields in deviceLabelFields", "invalidFieldNames", maps.Keys(configLabelFields)) } if len(deviceLabelFields) == 0 { deviceLabelFields = []string{"class", "vendor"} diff --git a/source/usb/usb.go b/source/usb/usb.go index 198c9d817..ab3febcb1 100644 --- a/source/usb/usb.go +++ b/source/usb/usb.go @@ -20,6 +20,7 @@ import ( "fmt" "strings" + "golang.org/x/exp/maps" "k8s.io/klog/v2" nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1" @@ -105,11 +106,7 @@ func (s *usbSource) GetLabels() (source.FeatureLabels, error) { } } if len(configLabelFields) > 0 { - keys := []string{} - for key := range configLabelFields { - keys = append(keys, key) - } - klog.InfoS("ignoring invalid fields in deviceLabelFields", "invalidFieldNames", keys) + klog.InfoS("ignoring invalid fields in deviceLabelFields", "invalidFieldNames", maps.Keys(configLabelFields)) } if len(deviceLabelFields) == 0 { deviceLabelFields = defaultDeviceLabelFields()