Merge pull request #126204 from vrutkovs/unsafeRecordQueried-atomicPointer
feature_gate: avoid extra copy when queried feature is already stored, use Set instead of map
This commit is contained in:
		@@ -30,6 +30,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	utilerrors "k8s.io/apimachinery/pkg/util/errors"
 | 
						utilerrors "k8s.io/apimachinery/pkg/util/errors"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/naming"
 | 
						"k8s.io/apimachinery/pkg/util/naming"
 | 
				
			||||||
 | 
						"k8s.io/apimachinery/pkg/util/sets"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/version"
 | 
						"k8s.io/apimachinery/pkg/util/version"
 | 
				
			||||||
	featuremetrics "k8s.io/component-base/metrics/prometheus/feature"
 | 
						featuremetrics "k8s.io/component-base/metrics/prometheus/feature"
 | 
				
			||||||
	baseversion "k8s.io/component-base/version"
 | 
						baseversion "k8s.io/component-base/version"
 | 
				
			||||||
@@ -265,7 +266,7 @@ func NewVersionedFeatureGate(emulationVersion *version.Version) *featureGate {
 | 
				
			|||||||
	f.enabled.Store(map[Feature]bool{})
 | 
						f.enabled.Store(map[Feature]bool{})
 | 
				
			||||||
	f.enabledRaw.Store(map[string]bool{})
 | 
						f.enabledRaw.Store(map[string]bool{})
 | 
				
			||||||
	f.emulationVersion.Store(emulationVersion)
 | 
						f.emulationVersion.Store(emulationVersion)
 | 
				
			||||||
	f.queriedFeatures.Store(map[Feature]struct{}{})
 | 
						f.queriedFeatures.Store(sets.Set[Feature]{})
 | 
				
			||||||
	klog.V(1).Infof("new feature gate with emulationVersion=%s", f.emulationVersion.Load().String())
 | 
						klog.V(1).Infof("new feature gate with emulationVersion=%s", f.emulationVersion.Load().String())
 | 
				
			||||||
	return f
 | 
						return f
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -530,7 +531,7 @@ func (f *featureGate) SetEmulationVersion(emulationVersion *version.Version) err
 | 
				
			|||||||
	enabled := map[Feature]bool{}
 | 
						enabled := map[Feature]bool{}
 | 
				
			||||||
	errs := f.unsafeSetFromMap(enabled, enabledRaw, emulationVersion)
 | 
						errs := f.unsafeSetFromMap(enabled, enabledRaw, emulationVersion)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	queriedFeatures := f.queriedFeatures.Load().(map[Feature]struct{})
 | 
						queriedFeatures := f.queriedFeatures.Load().(sets.Set[Feature])
 | 
				
			||||||
	known := f.known.Load().(map[Feature]VersionedSpecs)
 | 
						known := f.known.Load().(map[Feature]VersionedSpecs)
 | 
				
			||||||
	for feature := range queriedFeatures {
 | 
						for feature := range queriedFeatures {
 | 
				
			||||||
		newVal := featureEnabled(feature, enabled, known, emulationVersion)
 | 
							newVal := featureEnabled(feature, enabled, known, emulationVersion)
 | 
				
			||||||
@@ -544,7 +545,7 @@ func (f *featureGate) SetEmulationVersion(emulationVersion *version.Version) err
 | 
				
			|||||||
		// Persist changes
 | 
							// Persist changes
 | 
				
			||||||
		f.enabled.Store(enabled)
 | 
							f.enabled.Store(enabled)
 | 
				
			||||||
		f.emulationVersion.Store(emulationVersion)
 | 
							f.emulationVersion.Store(emulationVersion)
 | 
				
			||||||
		f.queriedFeatures.Store(map[Feature]struct{}{})
 | 
							f.queriedFeatures.Store(sets.Set[Feature]{})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return utilerrors.NewAggregate(errs)
 | 
						return utilerrors.NewAggregate(errs)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -564,15 +565,14 @@ func (f *featureGate) featureSpec(key Feature) (FeatureSpec, error) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f *featureGate) unsafeRecordQueried(key Feature) {
 | 
					func (f *featureGate) unsafeRecordQueried(key Feature) {
 | 
				
			||||||
	queriedFeatures := map[Feature]struct{}{}
 | 
						queriedFeatures := f.queriedFeatures.Load().(sets.Set[Feature])
 | 
				
			||||||
	for k := range f.queriedFeatures.Load().(map[Feature]struct{}) {
 | 
					 | 
				
			||||||
		queriedFeatures[k] = struct{}{}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if _, ok := queriedFeatures[key]; ok {
 | 
						if _, ok := queriedFeatures[key]; ok {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	queriedFeatures[key] = struct{}{}
 | 
						// Clone items from queriedFeatures before mutating it
 | 
				
			||||||
	f.queriedFeatures.Store(queriedFeatures)
 | 
						newQueriedFeatures := queriedFeatures.Clone()
 | 
				
			||||||
 | 
						newQueriedFeatures.Insert(key)
 | 
				
			||||||
 | 
						f.queriedFeatures.Store(newQueriedFeatures)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func featureEnabled(key Feature, enabled map[Feature]bool, known map[Feature]VersionedSpecs, emulationVersion *version.Version) bool {
 | 
					func featureEnabled(key Feature, enabled map[Feature]bool, known map[Feature]VersionedSpecs, emulationVersion *version.Version) bool {
 | 
				
			||||||
@@ -700,7 +700,7 @@ func (f *featureGate) DeepCopy() MutableVersionedFeatureGate {
 | 
				
			|||||||
	fg.known.Store(known)
 | 
						fg.known.Store(known)
 | 
				
			||||||
	fg.enabled.Store(enabled)
 | 
						fg.enabled.Store(enabled)
 | 
				
			||||||
	fg.enabledRaw.Store(enabledRaw)
 | 
						fg.enabledRaw.Store(enabledRaw)
 | 
				
			||||||
	fg.queriedFeatures.Store(map[Feature]struct{}{})
 | 
						fg.queriedFeatures.Store(sets.Set[Feature]{})
 | 
				
			||||||
	return fg
 | 
						return fg
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user