diff --git a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go index a6867426c5d..d08a5ba78a5 100644 --- a/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go +++ b/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go @@ -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) { if name, ok := p.MatchesSingle(); ok { 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 { return nil, err } diff --git a/staging/src/k8s.io/apiserver/pkg/storage/selection_predicate.go b/staging/src/k8s.io/apiserver/pkg/storage/selection_predicate.go index c4f79288d94..8878245d1f2 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/selection_predicate.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/selection_predicate.go @@ -65,16 +65,41 @@ func (s *SelectionPredicate) MatchesLabelsAndFields(l labels.Set, f fields.Set) 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 // name. func (s *SelectionPredicate) MatchesSingle() (string, bool) { - // TODO: should be namespace.name - if name, ok := s.Field.RequiresExactMatch("metadata.name"); ok { + if name, ok := s.Field.RequiresExactMatch(matchesSingleField); ok { return name, true } 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) // of objects that return for a given index, a pair (, ) // wil be returned.