mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 09:22:44 +00:00
Optimize computing fields in pod
This commit is contained in:
parent
d7e70bd448
commit
c54d09d14e
@ -26,7 +26,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/labels"
|
"k8s.io/kubernetes/pkg/labels"
|
||||||
"k8s.io/kubernetes/pkg/registry/generic"
|
"k8s.io/kubernetes/pkg/registry/generic"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
apistorage "k8s.io/kubernetes/pkg/storage"
|
pkgstorage "k8s.io/kubernetes/pkg/storage"
|
||||||
"k8s.io/kubernetes/pkg/util/validation/field"
|
"k8s.io/kubernetes/pkg/util/validation/field"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -80,16 +80,31 @@ func (endpointsStrategy) AllowUnconditionalUpdate() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MatchEndpoints returns a generic matcher for a given label and field selector.
|
// MatchEndpoints returns a generic matcher for a given label and field selector.
|
||||||
func MatchEndpoints(label labels.Selector, field fields.Selector) apistorage.SelectionPredicate {
|
func MatchEndpoints(label labels.Selector, field fields.Selector) pkgstorage.SelectionPredicate {
|
||||||
return apistorage.SelectionPredicate{Label: label, Field: field, GetAttrs: EndpointsAttributes}
|
return pkgstorage.SelectionPredicate{
|
||||||
|
Label: label,
|
||||||
|
Field: field,
|
||||||
|
GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) {
|
||||||
|
endpoints, ok := obj.(*api.Endpoints)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil, fmt.Errorf("invalid object type %#v", obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute fields only if field selectors is non-empty
|
||||||
|
// (otherwise those won't be used).
|
||||||
|
// Those are generally also not needed if label selector does
|
||||||
|
// not match labels, but additional computation of it is expensive.
|
||||||
|
var endpointsFields fields.Set
|
||||||
|
if !field.Empty() {
|
||||||
|
endpointsFields = EndpointsToSelectableFields(endpoints)
|
||||||
|
}
|
||||||
|
return endpoints.Labels, endpointsFields, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EndpointsAttributes returns the attributes of an endpoint such that a
|
// EndpointsToSelectableFields returns a field set that represents the object
|
||||||
// SelectionPredicate can match appropriately.
|
// TODO: fields are not labels, and the validation rules for them do not apply.
|
||||||
func EndpointsAttributes(obj runtime.Object) (objLabels labels.Set, objFields fields.Set, err error) {
|
func EndpointsToSelectableFields(endpoints *api.Endpoints) fields.Set {
|
||||||
endpoints, ok := obj.(*api.Endpoints)
|
return generic.ObjectMetaFieldsSet(&endpoints.ObjectMeta, true)
|
||||||
if !ok {
|
|
||||||
return nil, nil, fmt.Errorf("invalid object type %#v", obj)
|
|
||||||
}
|
|
||||||
return endpoints.Labels, generic.ObjectMetaFieldsSet(&endpoints.ObjectMeta, true), nil
|
|
||||||
}
|
}
|
||||||
|
@ -25,14 +25,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestSelectableFieldLabelConversions(t *testing.T) {
|
func TestSelectableFieldLabelConversions(t *testing.T) {
|
||||||
_, fieldsSet, err := EndpointsAttributes(&api.Endpoints{})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
apitesting.TestSelectableFieldLabelConversionsOfKind(t,
|
apitesting.TestSelectableFieldLabelConversionsOfKind(t,
|
||||||
registered.GroupOrDie(api.GroupName).GroupVersion.String(),
|
registered.GroupOrDie(api.GroupName).GroupVersion.String(),
|
||||||
"Endpoints",
|
"Endpoints",
|
||||||
fieldsSet,
|
EndpointsToSelectableFields(&api.Endpoints{}),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,16 @@ func MatchNode(label labels.Selector, field fields.Selector) pkgstorage.Selectio
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil, fmt.Errorf("not a node")
|
return nil, nil, fmt.Errorf("not a node")
|
||||||
}
|
}
|
||||||
return labels.Set(nodeObj.ObjectMeta.Labels), NodeToSelectableFields(nodeObj), nil
|
|
||||||
|
// Compute fields only if field selectors is non-empty
|
||||||
|
// (otherwise those won't be used).
|
||||||
|
// Those are generally also not needed if label selector does
|
||||||
|
// not match labels, but additional computation of it is expensive.
|
||||||
|
var nodeFields fields.Set
|
||||||
|
if !field.Empty() {
|
||||||
|
nodeFields = NodeToSelectableFields(nodeObj)
|
||||||
|
}
|
||||||
|
return labels.Set(nodeObj.ObjectMeta.Labels), nodeFields, nil
|
||||||
},
|
},
|
||||||
IndexFields: []string{"metadata.name"},
|
IndexFields: []string{"metadata.name"},
|
||||||
}
|
}
|
||||||
|
@ -166,18 +166,15 @@ func MatchPod(label labels.Selector, field fields.Selector) storage.SelectionPre
|
|||||||
return nil, nil, fmt.Errorf("not a pod")
|
return nil, nil, fmt.Errorf("not a pod")
|
||||||
}
|
}
|
||||||
|
|
||||||
// podLabels is already sitting there ready to be used.
|
// Compute fields only if field selectors is non-empty
|
||||||
// podFields is not available directly and requires allocation of a map.
|
// (otherwise those won't be used).
|
||||||
// Only bother if the fields might be useful to determining the match.
|
// Those are generally also not needed if label selector does
|
||||||
// One common case is for a replication controller to set up a watch
|
// not match labels, but additional computation of it is expensive.
|
||||||
// based on labels alone; in that case we can avoid allocating the field map.
|
|
||||||
// This is especially important in the apiserver.
|
|
||||||
podLabels := labels.Set(pod.ObjectMeta.Labels)
|
|
||||||
var podFields fields.Set
|
var podFields fields.Set
|
||||||
if !field.Empty() && label.Matches(podLabels) {
|
if !field.Empty() {
|
||||||
podFields = PodToSelectableFields(pod)
|
podFields = PodToSelectableFields(pod)
|
||||||
}
|
}
|
||||||
return podLabels, podFields, nil
|
return labels.Set(pod.ObjectMeta.Labels), podFields, nil
|
||||||
},
|
},
|
||||||
IndexFields: []string{"spec.nodeName"},
|
IndexFields: []string{"spec.nodeName"},
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user