mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 04:06:03 +00:00
Apply current parses the yaml object 3 times
This is super expensive and not needed at all since we don't have to reparse the entire object. Remove all allocations but the first one.
This commit is contained in:
parent
08f46e425b
commit
31c644a1e7
@ -216,7 +216,7 @@ func (f *fieldManager) Apply(liveObj runtime.Object, patch []byte, fieldManager
|
||||
}
|
||||
internal.RemoveObjectManagedFields(liveObjVersioned)
|
||||
|
||||
patchObjTyped, err := f.typeConverter.YAMLToTyped(patch)
|
||||
patchObjTyped, err := f.typeConverter.ObjectToTyped(patchObj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create typed patch object: %v", err)
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ go_library(
|
||||
"//vendor/sigs.k8s.io/structured-merge-diff/merge:go_default_library",
|
||||
"//vendor/sigs.k8s.io/structured-merge-diff/typed:go_default_library",
|
||||
"//vendor/sigs.k8s.io/structured-merge-diff/value:go_default_library",
|
||||
"//vendor/sigs.k8s.io/yaml:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -25,14 +25,12 @@ import (
|
||||
"k8s.io/kube-openapi/pkg/util/proto"
|
||||
"sigs.k8s.io/structured-merge-diff/typed"
|
||||
"sigs.k8s.io/structured-merge-diff/value"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
// TypeConverter allows you to convert from runtime.Object to
|
||||
// typed.TypedValue and the other way around.
|
||||
type TypeConverter interface {
|
||||
ObjectToTyped(runtime.Object) (*typed.TypedValue, error)
|
||||
YAMLToTyped([]byte) (*typed.TypedValue, error)
|
||||
TypedToObject(*typed.TypedValue) (runtime.Object, error)
|
||||
}
|
||||
|
||||
@ -58,11 +56,6 @@ func (DeducedTypeConverter) ObjectToTyped(obj runtime.Object) (*typed.TypedValue
|
||||
return typed.DeducedParseableType.FromUnstructured(u)
|
||||
}
|
||||
|
||||
// YAMLToTyped parses a yaml object into a TypedValue with a "deduced type".
|
||||
func (DeducedTypeConverter) YAMLToTyped(from []byte) (*typed.TypedValue, error) {
|
||||
return typed.DeducedParseableType.FromYAML(typed.YAMLObject(from))
|
||||
}
|
||||
|
||||
// TypedToObject transforms the typed value into a runtime.Object. That
|
||||
// is not specific to deduced type.
|
||||
func (DeducedTypeConverter) TypedToObject(value *typed.TypedValue) (runtime.Object, error) {
|
||||
@ -99,21 +92,6 @@ func (c *typeConverter) ObjectToTyped(obj runtime.Object) (*typed.TypedValue, er
|
||||
return t.FromUnstructured(u)
|
||||
}
|
||||
|
||||
func (c *typeConverter) YAMLToTyped(from []byte) (*typed.TypedValue, error) {
|
||||
unstructured := &unstructured.Unstructured{Object: map[string]interface{}{}}
|
||||
|
||||
if err := yaml.Unmarshal(from, &unstructured.Object); err != nil {
|
||||
return nil, fmt.Errorf("error decoding YAML: %v", err)
|
||||
}
|
||||
|
||||
gvk := unstructured.GetObjectKind().GroupVersionKind()
|
||||
t := c.parser.Type(gvk)
|
||||
if t == nil {
|
||||
return nil, newNoCorrespondingTypeError(gvk)
|
||||
}
|
||||
return t.FromYAML(typed.YAMLObject(string(from)))
|
||||
}
|
||||
|
||||
func (c *typeConverter) TypedToObject(value *typed.TypedValue) (runtime.Object, error) {
|
||||
return valueToObject(value.AsValue())
|
||||
}
|
||||
|
@ -124,9 +124,6 @@ spec:
|
||||
t.Run(fmt.Sprintf("%v ObjectToTyped with TypeConverter", testCase.name), func(t *testing.T) {
|
||||
testObjectToTyped(t, tc, testCase.yaml)
|
||||
})
|
||||
t.Run(fmt.Sprintf("%v YAMLToTyped with TypeConverter", testCase.name), func(t *testing.T) {
|
||||
testYAMLToTyped(t, tc, testCase.yaml)
|
||||
})
|
||||
t.Run(fmt.Sprintf("%v ObjectToTyped with DeducedTypeConverter", testCase.name), func(t *testing.T) {
|
||||
testObjectToTyped(t, dtc, testCase.yaml)
|
||||
})
|
||||
@ -155,31 +152,9 @@ Final object:
|
||||
}
|
||||
}
|
||||
|
||||
func testYAMLToTyped(t *testing.T, tc internal.TypeConverter, y string) {
|
||||
obj := &unstructured.Unstructured{Object: map[string]interface{}{}}
|
||||
if err := yaml.Unmarshal([]byte(y), &obj.Object); err != nil {
|
||||
t.Fatalf("Failed to parse yaml object: %v", err)
|
||||
}
|
||||
yamlTyped, err := tc.YAMLToTyped([]byte(y))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to convert yaml to typed: %v", err)
|
||||
}
|
||||
newObj, err := tc.TypedToObject(yamlTyped)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to convert typed to object: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(obj, newObj) {
|
||||
t.Errorf(`YAML conversion resulted in different object failed:
|
||||
Original object:
|
||||
%#v
|
||||
Final object:
|
||||
%#v`, obj, newObj)
|
||||
}
|
||||
}
|
||||
|
||||
var result typed.TypedValue
|
||||
|
||||
func BenchmarkYAMLToTyped(b *testing.B) {
|
||||
func BenchmarkObjectToTyped(b *testing.B) {
|
||||
y := `
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
|
Loading…
Reference in New Issue
Block a user