Skip to content

Commit

Permalink
Mem efficient set keys (#384)
Browse files Browse the repository at this point in the history
* ...

* one more

* use strings.Builder

* changelog

* Adding changelog file to new location

* Deleting changelog file from old location

Co-authored-by: changelog-bot <changelog-bot>
  • Loading branch information
EItanya authored Oct 4, 2022
1 parent 570a3e3 commit 74885ac
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
6 changes: 6 additions & 0 deletions changelog/v0.23.7/mem-efficient-set-keys.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
changelog:
- type: NON_USER_FACING
description: Make `sets.Key()` much more memory efficient by using a `sync.Pool` to
reuse buffers, and switching from string concatenation to `strings.Builder`.


29 changes: 26 additions & 3 deletions contrib/pkg/sets/sets.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package sets

import (
"fmt"
"strings"
"sync"

"github.com/rotisserie/eris"
Expand All @@ -13,22 +14,44 @@ var NotFoundErr = func(resourceType ezkube.ResourceId, id ezkube.ResourceId) err
return eris.Errorf("%T with id %v not found", resourceType, Key(id))
}

const separator = "."

var builderPool = sync.Pool{
New: func() any {
return &strings.Builder{}
},
}

// k8s resources are uniquely identified by their name and namespace
func Key(id ezkube.ResourceId) string {
b := builderPool.Get().(*strings.Builder)
defer func() {
b.Reset()
builderPool.Put(b)
}()
// When kubernetes objects are passed in here, a call to the GetX() functions will panic, so
// this will return "<unknown>" always if the input is nil.
if id == nil {
return "<unknown>"
}
if clusterId, ok := id.(ezkube.ClusterResourceId); ok {
return clusterId.GetName() + "." + clusterId.GetNamespace() + "." + clusterId.GetClusterName()
b.WriteString(clusterId.GetName())
b.WriteString(separator)
b.WriteString(clusterId.GetNamespace())
b.WriteString(separator)
b.WriteString(clusterId.GetClusterName())
return b.String()
}
return id.GetName() + "." + id.GetNamespace() + "."
b.WriteString(id.GetName())
b.WriteString(separator)
b.WriteString(id.GetNamespace())
b.WriteString(separator)
return b.String()
}

// typed keys are helpful for logging; currently unused in the Set implementation but placed here for convenience
func TypedKey(id ezkube.ResourceId) string {
return fmt.Sprintf("%v.%T", Key(id), id)
return fmt.Sprintf("%s.%T", Key(id), id)
}

type ResourceSet interface {
Expand Down

0 comments on commit 74885ac

Please sign in to comment.