Skip to content

Commit

Permalink
weighted hash (#1563)
Browse files Browse the repository at this point in the history
* weighted hash

Signed-off-by: Michael Kalantar <[email protected]>

* fix lint problem

Signed-off-by: Michael Kalantar <[email protected]>

---------

Signed-off-by: Michael Kalantar <[email protected]>
  • Loading branch information
kalantar authored Jul 26, 2023
1 parent 55cfdf0 commit 6f9ff67
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 4 deletions.
16 changes: 12 additions & 4 deletions abn/service_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func lookupInternal(application string, user string) (controllers.RoutemapInterf
// Inspired by https://github.com/tysonmote/rendezvous/blob/master/rendezvous.go
func rendezvousGet(s controllers.RoutemapInterface, user string) int {
// current maximimum score as computed by the hash function
var maxScore uint64
var maxScore float64
// maxVersionNumber is the version index with the current maximum score
var maxVersionNumber int

Expand All @@ -73,12 +73,20 @@ func rendezvousGet(s controllers.RoutemapInterface, user string) int {
s.RLock()
defer s.RUnlock()

sumW := uint32(0)
for versionNumber := range s.GetVersions() {
sumW += s.Weights()[versionNumber]
}

for versionNumber, version := range s.GetVersions() {
if s.Weights()[versionNumber] == 0 {
w := s.Weights()[versionNumber]
if w == 0 {
continue
}
score := hash(fmt.Sprintf("%d", versionNumber), *version.GetSignature(), user)
log.Logger.Debugf("hash(%d,%s) --> %d -- %d", versionNumber, user, score, maxScore)
wFactor := float64(w) / float64(sumW)
h := hash(fmt.Sprintf("%d", versionNumber), *version.GetSignature(), user)
score := wFactor * float64(h)
log.Logger.Debugf("hash(%d,%s) --> %f -- %f", versionNumber, user, score, maxScore)
if score >= maxScore {
maxScore = score
maxVersionNumber = versionNumber
Expand Down
54 changes: 54 additions & 0 deletions abn/service_impl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"testing"

"github.com/dgraph-io/badger/v4"
"github.com/google/uuid"
util "github.com/iter8-tools/iter8/base"
"github.com/iter8-tools/iter8/storage/badgerdb"
"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -36,3 +38,55 @@ func TestLookupInternal(t *testing.T) {
assert.Equal(t, tr, versionNumbers[i])
}
}

func TestWeights(t *testing.T) {
var err error

// set up test metrics db for recording users
tempDirPath := t.TempDir()
MetricsClient, err = badgerdb.GetClient(badger.DefaultOptions(tempDirPath), badgerdb.AdditionalOptions{})
assert.NoError(t, err)

// setup: add desired routemaps to allRoutemaps
testRM := testRoutemaps{
allroutemaps: setupRoutemaps(t, *getWeightedTestRM("default", "test", []uint32{3, 1})),
}
allRoutemaps = &testRM

tries := 100
versionNumbers := make([]int, tries)
for i := 0; i < tries; i++ {
_, v, err := lookupInternal("default/test", uuid.NewString())
assert.NoError(t, err)
versionNumbers[i] = v
}

// expect 3/4 will be for version 0 (weight 3); ie, 75
// expect 1/4 will be for version 1 (weight 1); ie, 25
// compute number for version 1 by summing versionNumbers
// assert less than 30 (bigger than 25)
// there is a slight possibility of test failure

sum := 0
for i := 1; i < tries; i++ {
sum += versionNumbers[i]
}
assert.Less(t, sum, 30)
}

func getWeightedTestRM(namespace, name string, weights []uint32) *testroutemap {
copyWeights := make([]uint32, len(weights))
versions := make([]testversion, len(weights))
for i := range weights {
copyWeights[i] = weights[i]
versions[i] = testversion{signature: util.StringPointer(uuid.NewString())}
}

return &testroutemap{
namespace: namespace,
name: name,
versions: versions,
normalizedWeights: copyWeights,
}

}

0 comments on commit 6f9ff67

Please sign in to comment.