Commit 874fca65 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #38086 from tianshapjq/reduce-decode-times

Automatic merge from submit-queue Reduce decode times by changing the kubectl.Filter(runtime.Object, *PrintOptions)'s return values **What this PR does / why we need it**: In kubectl/cmd/get.go, we use the function filterFuncs.Filter() to decode data and filter the object. But in the following function printer.PrintObj() decodes the data again. I made these modifications to reduce the decoding times by changing the filterFuncs.Filter()'s returned values. We can get the decoded object from this function and pass it to the following printer.PrintObj(), so not to waste time to decode again.
parents 9925b680 1453cd62
......@@ -458,8 +458,11 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [
lastMapping = mapping
}
// try to convert before apply filter func
decodedObj, _ := kubectl.DecodeUnknownObject(original)
// filter objects if filter has been defined for current object
if isFiltered, err := filterFuncs.Filter(original, filterOpts); isFiltered {
if isFiltered, err := filterFuncs.Filter(decodedObj, filterOpts); isFiltered {
if err == nil {
filteredResourceCount++
continue
......@@ -489,7 +492,7 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [
resourcePrinter.EnsurePrintWithKind(resourceName)
}
if err := printer.PrintObj(original, w); err != nil {
if err := printer.PrintObj(decodedObj, w); err != nil {
if !errs.Has(err.Error()) {
errs.Insert(err.Error())
allErrs = append(allErrs, err)
......@@ -497,7 +500,7 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [
}
continue
}
if err := printer.PrintObj(original, w); err != nil {
if err := printer.PrintObj(decodedObj, w); err != nil {
if !errs.Has(err.Error()) {
errs.Insert(err.Error())
allErrs = append(allErrs, err)
......
......@@ -257,13 +257,23 @@ func TestGetSortedObjects(t *testing.T) {
}
func verifyObjects(t *testing.T, expected, actual []runtime.Object) {
var actualObj runtime.Object
var err error
if len(actual) != len(expected) {
t.Fatal(actual)
}
for i, obj := range actual {
actualObj, err := runtime.Decode(
api.Codecs.UniversalDecoder(),
[]byte(runtime.EncodeOrDie(api.Codecs.LegacyCodec(), obj)))
switch obj.(type) {
case runtime.Unstructured, *runtime.Unknown:
actualObj, err = runtime.Decode(
api.Codecs.UniversalDecoder(),
[]byte(runtime.EncodeOrDie(api.Codecs.LegacyCodec(), obj)))
default:
actualObj = obj
err = nil
}
if err != nil {
t.Fatal(err)
}
......
......@@ -60,6 +60,20 @@ func filterPods(obj runtime.Object, options PrintOptions) bool {
func (f Filters) Filter(obj runtime.Object, opts *PrintOptions) (bool, error) {
// check if the object is unstructured. If so, let's attempt to convert it to a type we can understand
// before apply filter func.
obj, _ = DecodeUnknownObject(obj)
for _, filter := range f {
if ok := filter(obj, *opts); ok {
return true, nil
}
}
return false, nil
}
// check if the object is unstructured. If so, let's attempt to convert it to a type we can understand.
func DecodeUnknownObject(obj runtime.Object) (runtime.Object, error) {
var err error
switch obj.(type) {
case runtime.Unstructured, *runtime.Unknown:
if objBytes, err := runtime.Encode(api.Codecs.LegacyCodec(), obj); err == nil {
......@@ -69,10 +83,5 @@ func (f Filters) Filter(obj runtime.Object, opts *PrintOptions) (bool, error) {
}
}
for _, filter := range f {
if ok := filter(obj, *opts); ok {
return true, nil
}
}
return false, nil
return obj, err
}
......@@ -2394,14 +2394,7 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
// check if the object is unstructured. If so, let's attempt to convert it to a type we can understand before
// trying to print, since the printers are keyed by type. This is extremely expensive.
switch obj.(type) {
case runtime.Unstructured, *runtime.Unknown:
if objBytes, err := runtime.Encode(api.Codecs.LegacyCodec(), obj); err == nil {
if decodedObj, err := runtime.Decode(api.Codecs.UniversalDecoder(), objBytes); err == nil {
obj = decodedObj
}
}
}
obj, _ = DecodeUnknownObject(obj)
t := reflect.TypeOf(obj)
if handler := h.handlerMap[t]; handler != nil {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment