Optimize selector for single-matching items
Kubernetes-commit: f93a270edcefc3780247ae89eea02cd13b81237b
This commit is contained in:
		
							parent
							
								
									afe291fde8
								
							
						
					
					
						commit
						d84eb10096
					
				|  | @ -1036,7 +1036,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 | ||||
| 			} | ||||
|  |  | |||
|  | @ -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 <value> for a given index, a pair (<index name>, <value>)
 | ||||
| // wil be returned.
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue