Skip to content

Commit

Permalink
perf: cache Resource.CurId & PrevIds return value
Browse files Browse the repository at this point in the history
Cache the return value for both Resource.CurId and Resource.PrevIds
to improve overall performance. These changes have minor effects on
small kustomize runs, but can provide significant benefits for
larger runs.
  • Loading branch information
ephesused committed Dec 7, 2023
1 parent 557d6cb commit a2a0e54
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 11 deletions.
1 change: 1 addition & 0 deletions api/internal/accumulator/refvartransformer.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func (rv *refVarTransformer) Transform(m resmap.ResMap) error {
return err
}
}
res.InvalidateIdCaches()
}
return nil
}
2 changes: 2 additions & 0 deletions api/resmap/reswrangler.go
Original file line number Diff line number Diff line change
Expand Up @@ -577,13 +577,15 @@ func (m *resWrangler) appendReplaceOrMerge(res *resource.Resource) error {
}
switch res.Behavior() {
case types.BehaviorReplace:
res.InvalidateIdCaches()
res.CopyMergeMetaDataFieldsFrom(old)
case types.BehaviorMerge:
// ensure the origin annotation doesn't get overwritten
orig, err := old.GetOrigin()
if err != nil {
return err
}
res.InvalidateIdCaches()
res.CopyMergeMetaDataFieldsFrom(old)
res.MergeDataMapFrom(old)
res.MergeBinaryDataMapFrom(old)
Expand Down
54 changes: 43 additions & 11 deletions api/resource/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ import (
// paired with metadata used by kustomize.
type Resource struct {
kyaml.RNode
refVarNames []string
refVarNames []string
curIdCache *resid.ResId
prevIdsIsCached bool
prevIdsCache []resid.ResId
}

var BuildAnnotations = []string{
Expand Down Expand Up @@ -311,7 +314,11 @@ func (r *Resource) RemoveBuildAnnotations() {
}
}

// setPreviousId adds the given namespace, name, and kind combination as a
// previous ID for the resource. Since storing a previous ID likely means that
// the current ID is about to change, setPreviousId also calls InvalidateIdCaches.
func (r *Resource) setPreviousId(ns string, n string, k string) *Resource {
r.InvalidateIdCaches()
r.appendCsvAnnotation(utils.BuildAnnotationPreviousNames, n)
r.appendCsvAnnotation(utils.BuildAnnotationPreviousNamespaces, ns)
r.appendCsvAnnotation(utils.BuildAnnotationPreviousKinds, k)
Expand Down Expand Up @@ -427,26 +434,51 @@ func (r *Resource) OrgId() resid.ResId {
// The returned array does not include the resource's current
// ID. If there are no previous IDs, this will return nil.
func (r *Resource) PrevIds() []resid.ResId {
prevIds, err := utils.PrevIds(&r.RNode)
if err != nil {
// this should never happen
panic(err)
if !r.prevIdsIsCached {
var err error
r.prevIdsCache, err = utils.PrevIds(&r.RNode)
if err != nil {
// this should never happen
panic(err)
}
r.prevIdsIsCached = true
}
return prevIds
if r.prevIdsCache == nil {
return nil
}
defensiveCopy := make([]resid.ResId, len(r.prevIdsCache))
copy(defensiveCopy, r.prevIdsCache)
return defensiveCopy
}

// StorePreviousId stores the resource's current ID via build annotations.
// Storing the current ID as a previous ID implies the current ID is about to
// change, so StorePreviousId calls InvalidateIdCaches.
func (r *Resource) StorePreviousId() {
id := r.CurId()
r.setPreviousId(id.EffectiveNamespace(), id.Name, id.Kind)
}

// CurId returns a ResId for the resource using the
// mutable parts of the resource.
// This should be unique in any ResMap.
// CurId returns a ResId for the resource using the mutable parts of the
// resource. This should be unique in any ResMap.
//
// CurId is called heavily, so it caches its return value to speed up overall
// execution. Call InvalidateIdCaches to invalidate the cache.
func (r *Resource) CurId() resid.ResId {
return resid.NewResIdWithNamespace(
r.GetGvk(), r.GetName(), r.GetNamespace())
if r.curIdCache == nil {
newCurId := resid.NewResIdWithNamespace(
r.GetGvk(), r.GetName(), r.GetNamespace())
r.curIdCache = &newCurId
}
return *r.curIdCache
}

// InvalidateIdCaches invalidates the resource's caches for the current and
// previous IDs.
func (r *Resource) InvalidateIdCaches() {
r.curIdCache = nil
r.prevIdsCache = nil
r.prevIdsIsCached = false
}

// GetRefBy returns the ResIds that referred to current resource
Expand Down

0 comments on commit a2a0e54

Please sign in to comment.