diff --git a/pkg/labels/labels.go b/pkg/labels/labels.go index 637a45fd38d..00139714be2 100644 --- a/pkg/labels/labels.go +++ b/pkg/labels/labels.go @@ -61,6 +61,15 @@ func (ls Set) AsSelector() Selector { return SelectorFromSet(ls) } +// ValidatedAsSelector converts labels into a selector, but +// assumes that labels are already validated and thus don't +// preform any validation. +// According to our measurements this is significantly faster +// in codepaths that matter at high sccale. +func (ls Set) AsSelectorPreValidated() Selector { + return SelectorFromValidatedSet(ls) +} + // FormatLables convert label map into plain string func FormatLabels(labelMap map[string]string) string { l := Set(labelMap).String() diff --git a/pkg/labels/selector.go b/pkg/labels/selector.go index 6551aba6016..703cf7aa1bf 100644 --- a/pkg/labels/selector.go +++ b/pkg/labels/selector.go @@ -796,6 +796,22 @@ func SelectorFromSet(ls Set) Selector { return internalSelector(requirements) } +// SelectorFromValidatedSet returns a Selector which will match exactly the given Set. +// A nil and empty Sets are considered equivalent to Everything(). +// It assumes that Set is already validated and doesn't do any validation. +func SelectorFromValidatedSet(ls Set) Selector { + if ls == nil { + return internalSelector{} + } + var requirements internalSelector + for label, value := range ls { + requirements = append(requirements, Requirement{key: label, operator: selection.Equals, strValues: sets.NewString(value)}) + } + // sort to have deterministic string representation + sort.Sort(ByKey(requirements)) + return internalSelector(requirements) +} + // ParseToRequirements takes a string representing a selector and returns a list of // requirements. This function is suitable for those callers that perform additional // processing on selector requirements.