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.
This commit is contained in:
Kubernetes Submit Queue 2016-12-19 16:23:02 -08:00 committed by GitHub
commit 874fca652d
4 changed files with 35 additions and 20 deletions

View File

@ -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)

View File

@ -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)
}

View File

@ -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
}

View File

@ -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 {