mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 08:17:26 +00:00
Optimize selector for single-matching items
This commit is contained in:
parent
48d0249a40
commit
f93a270edc
@ -1032,7 +1032,16 @@ func (e *Store) Watch(ctx genericapirequest.Context, options *metainternalversio
|
|||||||
func (e *Store) WatchPredicate(ctx genericapirequest.Context, p storage.SelectionPredicate, resourceVersion string) (watch.Interface, error) {
|
func (e *Store) WatchPredicate(ctx genericapirequest.Context, p storage.SelectionPredicate, resourceVersion string) (watch.Interface, error) {
|
||||||
if name, ok := p.MatchesSingle(); ok {
|
if name, ok := p.MatchesSingle(); ok {
|
||||||
if key, err := e.KeyFunc(ctx, name); err == nil {
|
if key, err := e.KeyFunc(ctx, name); err == nil {
|
||||||
w, err := e.Storage.Watch(ctx, key, resourceVersion, p)
|
// For performance reasons, we can optimize the further computations of
|
||||||
|
// selector, by removing then "matches-single" fields, because they are
|
||||||
|
// already satisfied by choosing appropriate key.
|
||||||
|
sp, err := p.RemoveMatchesSingleRequirements()
|
||||||
|
if err != nil {
|
||||||
|
glog.Warningf("Couldn't remove matches-single requirements: %v", err)
|
||||||
|
// Since we couldn't optimize selector, reset to the original one.
|
||||||
|
sp = p
|
||||||
|
}
|
||||||
|
w, err := e.Storage.Watch(ctx, key, resourceVersion, sp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -65,16 +65,41 @@ func (s *SelectionPredicate) MatchesLabelsAndFields(l labels.Set, f fields.Set)
|
|||||||
return matched
|
return matched
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const matchesSingleField = "metadata.name"
|
||||||
|
|
||||||
|
func removeMatchesSingleField(field, value string) (string, string, error) {
|
||||||
|
if field == matchesSingleField {
|
||||||
|
return "", "", nil
|
||||||
|
}
|
||||||
|
return field, value, nil
|
||||||
|
}
|
||||||
|
|
||||||
// MatchesSingle will return (name, true) if and only if s.Field matches on the object's
|
// MatchesSingle will return (name, true) if and only if s.Field matches on the object's
|
||||||
// name.
|
// name.
|
||||||
func (s *SelectionPredicate) MatchesSingle() (string, bool) {
|
func (s *SelectionPredicate) MatchesSingle() (string, bool) {
|
||||||
// TODO: should be namespace.name
|
if name, ok := s.Field.RequiresExactMatch(matchesSingleField); ok {
|
||||||
if name, ok := s.Field.RequiresExactMatch("metadata.name"); ok {
|
|
||||||
return name, true
|
return name, true
|
||||||
}
|
}
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SelectionPredicate) RemoveMatchesSingleRequirements() (SelectionPredicate, error) {
|
||||||
|
var fieldsSelector fields.Selector
|
||||||
|
if s.Field != nil {
|
||||||
|
var err error
|
||||||
|
fieldsSelector, err = s.Field.Transform(removeMatchesSingleField)
|
||||||
|
if err != nil {
|
||||||
|
return SelectionPredicate{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SelectionPredicate{
|
||||||
|
Label: s.Label,
|
||||||
|
Field: fieldsSelector,
|
||||||
|
GetAttrs: s.GetAttrs,
|
||||||
|
IndexFields: s.IndexFields,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// For any index defined by IndexFields, if a matcher can match only (a subset)
|
// For any index defined by IndexFields, if a matcher can match only (a subset)
|
||||||
// of objects that return <value> for a given index, a pair (<index name>, <value>)
|
// of objects that return <value> for a given index, a pair (<index name>, <value>)
|
||||||
// wil be returned.
|
// wil be returned.
|
||||||
|
Loading…
Reference in New Issue
Block a user