From 098fd24704d71d996f1d3a880b4c3a659bc2cd4e Mon Sep 17 00:00:00 2001 From: Alex Vanin Date: Fri, 1 Feb 2019 12:57:05 +0300 Subject: [PATCH] Support for int32 slices (#4) --- hrw.go | 6 ++++++ hrw_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/hrw.go b/hrw.go index 05744ef..8ee43e4 100644 --- a/hrw.go +++ b/hrw.go @@ -89,6 +89,12 @@ func SortSliceByValue(slice interface{}, hash uint64) { binary.BigEndian.PutUint64(key, uint64(slice[i])) rule = append(rule, weight(Hash(key), hash)) } + case []int32: + var key = make([]byte, 16) + for i := 0; i < length; i++ { + binary.BigEndian.PutUint32(key, uint32(slice[i])) + rule = append(rule, weight(Hash(key), hash)) + } case []string: for i := 0; i < length; i++ { rule = append(rule, weight(hash, diff --git a/hrw_test.go b/hrw_test.go index 2a8e00d..32aabcc 100644 --- a/hrw_test.go +++ b/hrw_test.go @@ -329,6 +329,47 @@ func TestUniformDistribution(t *testing.T) { }) + t.Run("sortByInt32Value", func(t *testing.T) { + var ( + i uint64 + a, b [size]int32 + counts = make(map[int32]int, size) + key = make([]byte, 16) + ) + + for i = 0; i < size; i++ { + a[i] = int32(i) + } + + for i = 0; i < keys; i++ { + copy(b[:], a[:]) + binary.BigEndian.PutUint64(key, i) + hash := Hash(key) + SortSliceByValue(b[:], hash) + counts[b[0]]++ + } + + var chi2 float64 + mean := float64(keys) / float64(size) + delta := mean * percent + for node, count := range counts { + d := mean - float64(count) + chi2 += math.Pow(float64(count)-mean, 2) / mean + if d > delta || (0-d) > delta { + t.Errorf( + "Node %d received %d keys, expected %.0f (+/- %.2f)", + node, count, mean, delta, + ) + } + } + if chi2 > chiTable[size-1] { + t.Errorf( + "Chi2 condition for .9 is not met (expected %.2f <= %.2f)", + chi2, chiTable[size-1]) + } + + }) + t.Run("hash collision", func(t *testing.T) { var ( i uint64