Skip to content

Commit

Permalink
Merge pull request #53 from xmidt-org/feature/benchmarks
Browse files Browse the repository at this point in the history
Feature/benchmarks
  • Loading branch information
johnabass authored Dec 27, 2024
2 parents e90e9e6 + 5b13bdb commit 18065ec
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 27 deletions.
43 changes: 43 additions & 0 deletions consistent/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-FileCopyrightText: 2025 Comcast Cable Communications Management, LLC
// SPDX-License-Identifier: Apache-2.0

package consistent

import (
"fmt"
"math/rand"
"testing"
)

const (
// objectSeed is the random number seed we use to create objects to hash
objectSeed int64 = 7245298734452934458

// objectCount is the number of random objects we generate for hash inputs
objectCount int = 1000

// serviceCount is the number of random service names to generate for hashes
serviceCount int = 100
)

// hashObjects contains a standard set of random objects to hash to services.
var hashObjects [objectCount][16]byte

// services contains a number of service names to use in tests and benchmarks.
var services [serviceCount]string

func TestMain(m *testing.M) {
random := rand.New(
rand.NewSource(objectSeed),
)

for i := range len(hashObjects) {
random.Read(hashObjects[i][:])
}

for i := range len(services) {
services[i] = fmt.Sprintf("service-%d.example.net", i)
}

m.Run()
}
43 changes: 43 additions & 0 deletions consistent/ring_benchmarks_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-FileCopyrightText: 2025 Comcast Cable Communications Management, LLC
// SPDX-License-Identifier: Apache-2.0

package consistent

import (
"fmt"
"testing"

"github.com/billhathaway/consistentHash"
)

var benchmarkVnodes = []int{50, 100, 200}

func BenchmarkRingCreation(b *testing.B) {
for _, vnodes := range benchmarkVnodes {
b.Run(
fmt.Sprintf("vnodes-%d", vnodes),
func(b *testing.B) {
for range b.N {
Strings(services[:]...).VNodes(vnodes).Build()
}
},
)
}
}

func BenchmarkConsistentHashCreation(b *testing.B) {
for _, vnodes := range benchmarkVnodes {
b.Run(
fmt.Sprintf("vnodes-%d", vnodes),
func(b *testing.B) {
for range b.N {
ch := consistentHash.New()
ch.SetVnodeCount(vnodes)
for _, service := range services {
ch.Add(service)
}
}
},
)
}
}
58 changes: 31 additions & 27 deletions consistent/ring_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,31 @@
package consistent

import (
"math/rand"
"sort"
"testing"

"github.com/billhathaway/consistentHash"
"github.com/stretchr/testify/suite"
"github.com/xmidt-org/medley"
)

const (
// objectSeed is the random number seed we use to create objects to hash
objectSeed int64 = 7245298734452934458

// objectCount is the number of random objects we generate for hash inputs
objectCount int = 1000
)

type RingSuite struct {
suite.Suite

rand *rand.Rand
objects [objectCount][16]byte

originalServices []string
original *Ring[string]
}

func (suite *RingSuite) SetupSuite() {
suite.rand = rand.New(
rand.NewSource(objectSeed),
)

for i := 0; i < len(suite.objects); i++ {
suite.rand.Read(suite.objects[i][:])
}

suite.originalServices = []string{
"original1.service.net", "original2.service.net", "original3.service.net", "original4.service.net",
}
// for the unit tests, we don't need all the services
suite.originalServices = services[0:4]

suite.original = Strings(suite.originalServices...).Build()
suite.Require().NotNil(suite.original)
suite.Require().True(sort.IsSorted(suite.original.nodes))

distribution := make(map[string]int)
for _, object := range suite.objects {
for _, object := range hashObjects {
result, err := suite.original.Find(object[:])
suite.Require().NoError(err)
suite.Require().Contains(suite.originalServices, result)
Expand Down Expand Up @@ -79,7 +59,7 @@ func (suite *RingSuite) testUpdateEmpty() {
suite.True(didUpdate)
suite.Empty(updated.nodes)

for _, object := range suite.objects {
for _, object := range hashObjects {
result, err := updated.Find(object[:])
suite.Empty(result)
suite.ErrorIs(err, medley.ErrNoServices)
Expand All @@ -91,7 +71,7 @@ func (suite *RingSuite) testUpdatePartial() {
updated, didUpdate := suite.update(partial...)
suite.True(didUpdate)

for _, object := range suite.objects {
for _, object := range hashObjects {
result, err := updated.Find(object[:])
suite.Contains(partial, result)
suite.NoError(err)
Expand All @@ -103,7 +83,7 @@ func (suite *RingSuite) testUpdateAllNew() {
updated, didUpdate := suite.update(allNew...)
suite.True(didUpdate)

for _, object := range suite.objects {
for _, object := range hashObjects {
result, err := updated.Find(object[:])
suite.Contains(allNew, result)
suite.NoError(err)
Expand All @@ -123,6 +103,30 @@ func (suite *RingSuite) TestUpdate() {
suite.Run("NotNeeded", suite.testUpdateNotNeeded)
}

func (suite *RingSuite) TestBackwardCompatibility() {
ch := consistentHash.New()
ch.SetVnodeCount(DefaultVNodes)
for _, service := range suite.originalServices {
ch.Add(service)
}

var (
oldResult string
newResult string
err error
)

for _, object := range hashObjects {
oldResult, err = ch.Get(object[:])
suite.Require().NoError(err)

newResult, err = suite.original.Find(object[:])
suite.Require().NoError(err)

suite.Equal(oldResult, newResult)
}
}

func TestRing(t *testing.T) {
suite.Run(t, new(RingSuite))
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
)

require (
github.com/billhathaway/consistentHash v0.0.0-20140718022140-addea16d2229 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/billhathaway/consistentHash v0.0.0-20140718022140-addea16d2229 h1:w1t+UCLwxXgpUcXAlm3IkvWHGJDfhIyNrzJmCUkJq7s=
github.com/billhathaway/consistentHash v0.0.0-20140718022140-addea16d2229/go.mod h1:YTos5xiYv+RiIsYn3pqdwe5OULySucMqiPes1OgC5pM=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand Down

0 comments on commit 18065ec

Please sign in to comment.