Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sai/test slice set impl #534

Closed
wants to merge 12 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions contrib/pkg/sets/sets.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ func Key(id ezkube.ResourceId) string {
return ezkube.KeyWithSeparator(id, defaultSeparator)
}

func Hash(id ezkube.ResourceId) uint64 {
return ezkube.HashedKeyWithSeparator(id, defaultSeparator)
}

// 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("%s.%T", Key(id), id)
Expand All @@ -29,7 +33,8 @@ type ResourceSet interface {
Keys() sets.String
List(filterResource ...func(ezkube.ResourceId) bool) []ezkube.ResourceId
UnsortedList(filterResource ...func(ezkube.ResourceId) bool) []ezkube.ResourceId
Map() Resources
Map() map[string]ezkube.ResourceId
Set() *Resources
Insert(resource ...ezkube.ResourceId)
Equal(set ResourceSet) bool
Has(resource ezkube.ResourceId) bool
Expand All @@ -56,7 +61,7 @@ type ResourceDelta struct {

type threadSafeResourceSet struct {
lock sync.RWMutex
set Resources
set *Resources
}

func NewResourceSet(resources ...ezkube.ResourceId) ResourceSet {
Expand All @@ -69,6 +74,12 @@ func (t *threadSafeResourceSet) Keys() sets.String {
return t.set.Keys()
}

func (t *threadSafeResourceSet) Set() *Resources {
t.lock.RLock()
defer t.lock.RUnlock()
return t.set
}

func (t *threadSafeResourceSet) List(filterResource ...func(ezkube.ResourceId) bool) []ezkube.ResourceId {
t.lock.RLock()
defer t.lock.RUnlock()
Expand All @@ -81,7 +92,7 @@ func (t *threadSafeResourceSet) UnsortedList(filterResource ...func(ezkube.Resou
return t.set.UnsortedList(filterResource...)
}

func (t *threadSafeResourceSet) Map() Resources {
func (t *threadSafeResourceSet) Map() map[string]ezkube.ResourceId {
t.lock.RLock()
defer t.lock.RUnlock()
return t.set.Map()
Expand All @@ -103,24 +114,24 @@ func (t *threadSafeResourceSet) Has(resource ezkube.ResourceId) bool {

// Has returns true if and only if item is contained in the set.
func (s Resources) Has(item ezkube.ResourceId) bool {
_, contained := s[Key(item)]
return contained
_, found := s.m[Hash(item)]
return found
}

func (t *threadSafeResourceSet) IsSuperset(
set ResourceSet,
) bool {
t.lock.RLock()
defer t.lock.RUnlock()
return t.set.IsSuperset(set.Map())
return t.set.IsSuperset(set.Set())
}

func (t *threadSafeResourceSet) Equal(
set ResourceSet,
) bool {
t.lock.RLock()
defer t.lock.RUnlock()
return t.set.Equal(set.Map())
return t.set.Equal(set.Set())
}

func (t *threadSafeResourceSet) Delete(resource ezkube.ResourceId) {
Expand All @@ -132,19 +143,19 @@ func (t *threadSafeResourceSet) Delete(resource ezkube.ResourceId) {
func (t *threadSafeResourceSet) Union(set ResourceSet) ResourceSet {
t.lock.Lock()
defer t.lock.Unlock()
return &threadSafeResourceSet{set: t.set.Union(set.Map())}
return &threadSafeResourceSet{set: t.set.Union(set.Set())}
}

func (t *threadSafeResourceSet) Difference(set ResourceSet) ResourceSet {
t.lock.RLock()
defer t.lock.RUnlock()
return &threadSafeResourceSet{set: t.set.Difference(set.Map())}
return &threadSafeResourceSet{set: t.set.Difference(set.Set())}
}

func (t *threadSafeResourceSet) Intersection(set ResourceSet) ResourceSet {
t.lock.RLock()
defer t.lock.RUnlock()
return &threadSafeResourceSet{set: t.set.Intersection(set.Map())}
return &threadSafeResourceSet{set: t.set.Intersection(set.Set())}
}

func (t *threadSafeResourceSet) Find(
Expand Down
122 changes: 122 additions & 0 deletions contrib/pkg/sets/sets_benchmark_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package sets

import (
"fmt"
"testing"

v1 "github.com/solo-io/skv2/pkg/api/core.skv2.solo.io/v1"
"github.com/solo-io/skv2/pkg/ezkube"
)

// Define a global variable to prevent compiler optimizations
var result interface{}

var scale = 10000

func Benchmark(b *testing.B) {
b.Run("Resources_Insert", BenchmarkResources_Insert)
b.Run("Resources_Find", BenchmarkResources_Find)
b.Run("Resources_Delete", BenchmarkResources_Delete)
b.Run("Resources_List", BenchmarkResources_List)
b.Run("Resources_UnsortedList", BenchmarkResources_UnsortedList)
}

func BenchmarkResources_Insert(b *testing.B) {
var r *Resources
for i := 0; i < b.N; i++ {
r = newResources() // Assume newResources is corrected to initialize correctly
for j := 0; j < scale; j++ {
resource := &v1.ObjectRef{Namespace: "namespace", Name: "name" + fmt.Sprint(j)}
r.Insert(resource)
}
}
// Store the result to a package level variable
// so the compiler cannot eliminate the Benchmark itself.
result = r
}

func BenchmarkResources_Find(b *testing.B) {
r := newResources()
for j := 0; j < scale; j++ {
resource := &v1.ObjectRef{Namespace: "namespace", Name: "name" + fmt.Sprint(j)}
r.Insert(resource)
}

b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = r.Find(&v1.TypedObjectRef{}, &v1.ObjectRef{Namespace: "namespace", Name: "name500"})
}
}

func BenchmarkResources_Delete(b *testing.B) {
var r *Resources
for i := 0; i < b.N; i++ {
r = newResources()
for j := 0; j < scale; j++ {
resource := &v1.ObjectRef{Namespace: "namespace", Name: "name" + fmt.Sprint(j)}
r.Insert(resource)
}
b.ResetTimer()
for j := 0; j < scale; j++ {
r.Delete(&v1.ObjectRef{Namespace: "namespace", Name: "name" + fmt.Sprint(j)})
}
b.StopTimer()
}
result = r
}

func BenchmarkResources_List(b *testing.B) {
r := newResources()
for j := 0; j < scale; j++ {
resource := &v1.ObjectRef{Namespace: "namespace", Name: "name" + fmt.Sprint(j)}
r.Insert(resource)
}

b.ResetTimer()
var res []ezkube.ResourceId
for i := 0; i < b.N; i++ {
res = r.List()
}
// Store the result to prevent the compiler from optimizing the loop away.
result = res
}

func BenchmarkResources_UnsortedList(b *testing.B) {
r := newResources()
for j := 0; j < scale; j++ {
resource := &v1.ObjectRef{Namespace: "namespace", Name: "name" + fmt.Sprint(j)}
r.Insert(resource)
}

b.ResetTimer()
var res []ezkube.ResourceId
for i := 0; i < b.N; i++ {
res = r.UnsortedList()
}
// Store the result to prevent the compiler from optimizing the loop away.
result = res
}

// func BenchmarkResources_Delta(b *testing.B) {
// // Define the scale for the number of resources in each set.
// const scale = 1000

// // Create and populate the original set with resources.
// originalSet := newResources()
// for i := 0; i < scale; i++ {
// resource := &v1.ObjectRef{Namespace: "namespace", Name: "originalName" + fmt.Sprint(i)}
// originalSet.Insert(resource)
// }

// // Create and populate a new set with some overlapping and some unique resources.
// newSet := newResources()
// for i := scale / 2; i < scale+(scale/2); i++ {
// resource := &v1.ObjectRef{Namespace: "namespace", Name: "newName" + fmt.Sprint(i)}
// newSet.Insert(resource)
// }

// b.ResetTimer() // Start timing the benchmark loop.
// for i := 0; i < b.N; i++ {
// _ = originalSet.Delta(newSet)
// }
// }
Loading
Loading