forked from TrueCloudLab/hrw
🐿 Extend SortSliceByValue with more types
This commit is contained in:
parent
7462e26df6
commit
e06640668d
2 changed files with 122 additions and 13 deletions
57
hrw.go
57
hrw.go
|
@ -86,22 +86,73 @@ func SortSliceByValue(slice interface{}, hash uint64) {
|
||||||
case int:
|
case int:
|
||||||
var key = make([]byte, 16)
|
var key = make([]byte, 16)
|
||||||
slice := slice.([]int)
|
slice := slice.([]int)
|
||||||
|
|
||||||
for i := 0; i < length; i++ {
|
for i := 0; i < length; i++ {
|
||||||
binary.BigEndian.PutUint64(key, uint64(slice[i]))
|
binary.BigEndian.PutUint64(key, uint64(slice[i]))
|
||||||
rule = append(rule, weight(Hash(key), hash))
|
rule = append(rule, weight(Hash(key), hash))
|
||||||
}
|
}
|
||||||
|
case uint:
|
||||||
|
var key = make([]byte, 16)
|
||||||
|
slice := slice.([]uint)
|
||||||
|
for i := 0; i < length; i++ {
|
||||||
|
binary.BigEndian.PutUint64(key, uint64(slice[i]))
|
||||||
|
rule = append(rule, weight(Hash(key), hash))
|
||||||
|
}
|
||||||
|
case int8:
|
||||||
|
slice := slice.([]int8)
|
||||||
|
for i := 0; i < length; i++ {
|
||||||
|
key := byte(slice[i])
|
||||||
|
rule = append(rule, weight(Hash([]byte{key}), hash))
|
||||||
|
}
|
||||||
|
case uint8:
|
||||||
|
slice := slice.([]uint8)
|
||||||
|
for i := 0; i < length; i++ {
|
||||||
|
key := slice[i]
|
||||||
|
rule = append(rule, weight(Hash([]byte{key}), hash))
|
||||||
|
}
|
||||||
|
case int16:
|
||||||
|
var key = make([]byte, 8)
|
||||||
|
slice := slice.([]int16)
|
||||||
|
for i := 0; i < length; i++ {
|
||||||
|
binary.BigEndian.PutUint16(key, uint16(slice[i]))
|
||||||
|
rule = append(rule, weight(Hash(key), hash))
|
||||||
|
}
|
||||||
|
case uint16:
|
||||||
|
var key = make([]byte, 8)
|
||||||
|
slice := slice.([]uint16)
|
||||||
|
for i := 0; i < length; i++ {
|
||||||
|
binary.BigEndian.PutUint16(key, slice[i])
|
||||||
|
rule = append(rule, weight(Hash(key), hash))
|
||||||
|
}
|
||||||
case int32:
|
case int32:
|
||||||
var key = make([]byte, 16)
|
var key = make([]byte, 16)
|
||||||
slice := slice.([]int32)
|
slice := slice.([]int32)
|
||||||
|
|
||||||
for i := 0; i < length; i++ {
|
for i := 0; i < length; i++ {
|
||||||
binary.BigEndian.PutUint32(key, uint32(slice[i]))
|
binary.BigEndian.PutUint32(key, uint32(slice[i]))
|
||||||
rule = append(rule, weight(Hash(key), hash))
|
rule = append(rule, weight(Hash(key), hash))
|
||||||
}
|
}
|
||||||
|
case uint32:
|
||||||
|
var key = make([]byte, 16)
|
||||||
|
slice := slice.([]uint32)
|
||||||
|
for i := 0; i < length; i++ {
|
||||||
|
binary.BigEndian.PutUint32(key, slice[i])
|
||||||
|
rule = append(rule, weight(Hash(key), hash))
|
||||||
|
}
|
||||||
|
case int64:
|
||||||
|
var key = make([]byte, 32)
|
||||||
|
slice := slice.([]int64)
|
||||||
|
for i := 0; i < length; i++ {
|
||||||
|
binary.BigEndian.PutUint64(key, uint64(slice[i]))
|
||||||
|
rule = append(rule, weight(Hash(key), hash))
|
||||||
|
}
|
||||||
|
case uint64:
|
||||||
|
var key = make([]byte, 32)
|
||||||
|
slice := slice.([]uint64)
|
||||||
|
for i := 0; i < length; i++ {
|
||||||
|
binary.BigEndian.PutUint64(key, slice[i])
|
||||||
|
rule = append(rule, weight(Hash(key), hash))
|
||||||
|
}
|
||||||
case string:
|
case string:
|
||||||
slice := slice.([]string)
|
slice := slice.([]string)
|
||||||
|
|
||||||
for i := 0; i < length; i++ {
|
for i := 0; i < length; i++ {
|
||||||
rule = append(rule, weight(hash,
|
rule = append(rule, weight(hash,
|
||||||
Hash([]byte(slice[i]))))
|
Hash([]byte(slice[i]))))
|
||||||
|
|
78
hrw_test.go
78
hrw_test.go
|
@ -9,7 +9,14 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
type hashString string
|
type (
|
||||||
|
hashString string
|
||||||
|
unknown byte
|
||||||
|
slices struct {
|
||||||
|
actual interface{}
|
||||||
|
expect interface{}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
var testKey = []byte("0xff51afd7ed558ccd")
|
var testKey = []byte("0xff51afd7ed558ccd")
|
||||||
|
|
||||||
|
@ -44,6 +51,7 @@ func Example() {
|
||||||
// trying GET six.example.com/examples/object-key
|
// trying GET six.example.com/examples/object-key
|
||||||
// trying GET five.example.com/examples/object-key
|
// trying GET five.example.com/examples/object-key
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h hashString) Hash() uint64 {
|
func (h hashString) Hash() uint64 {
|
||||||
return Hash([]byte(h))
|
return Hash([]byte(h))
|
||||||
}
|
}
|
||||||
|
@ -118,8 +126,8 @@ func TestSortSliceByValueFail(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("must 'fail' for unknown type", func(t *testing.T) {
|
t.Run("must 'fail' for unknown type", func(t *testing.T) {
|
||||||
actual := []byte{1, 2, 3, 4, 5}
|
actual := []unknown{1, 2, 3, 4, 5}
|
||||||
expect := []byte{1, 2, 3, 4, 5}
|
expect := []unknown{1, 2, 3, 4, 5}
|
||||||
hash := Hash(testKey)
|
hash := Hash(testKey)
|
||||||
SortSliceByValue(actual, hash)
|
SortSliceByValue(actual, hash)
|
||||||
if !reflect.DeepEqual(actual, expect) {
|
if !reflect.DeepEqual(actual, expect) {
|
||||||
|
@ -139,12 +147,64 @@ func TestSortSliceByValueHasher(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSortSliceByValueIntSlice(t *testing.T) {
|
func TestSortSliceByValueIntSlice(t *testing.T) {
|
||||||
actual := []int{0, 1, 2, 3, 4, 5}
|
cases := []slices{
|
||||||
expect := []int{2, 3, 1, 4, 0, 5}
|
{
|
||||||
|
actual: []int{0, 1, 2, 3, 4, 5},
|
||||||
|
expect: []int{2, 3, 1, 4, 0, 5},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
actual: []uint{0, 1, 2, 3, 4, 5},
|
||||||
|
expect: []uint{2, 3, 1, 4, 0, 5},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
actual: []int8{0, 1, 2, 3, 4, 5},
|
||||||
|
expect: []int8{2, 0, 5, 1, 4, 3},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
actual: []uint8{0, 1, 2, 3, 4, 5},
|
||||||
|
expect: []uint8{2, 0, 5, 1, 4, 3},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
actual: []int16{0, 1, 2, 3, 4, 5},
|
||||||
|
expect: []int16{5, 4, 0, 3, 2, 1},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
actual: []uint16{0, 1, 2, 3, 4, 5},
|
||||||
|
expect: []uint16{5, 4, 0, 3, 2, 1},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
actual: []int32{0, 1, 2, 3, 4, 5},
|
||||||
|
expect: []int32{1, 3, 5, 4, 2, 0},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
actual: []uint32{0, 1, 2, 3, 4, 5},
|
||||||
|
expect: []uint32{1, 3, 5, 4, 2, 0},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
actual: []int64{0, 1, 2, 3, 4, 5},
|
||||||
|
expect: []int64{1, 5, 3, 4, 2, 0},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
actual: []uint64{0, 1, 2, 3, 4, 5},
|
||||||
|
expect: []uint64{1, 5, 3, 4, 2, 0},
|
||||||
|
},
|
||||||
|
}
|
||||||
hash := Hash(testKey)
|
hash := Hash(testKey)
|
||||||
SortSliceByValue(actual, hash)
|
|
||||||
if !reflect.DeepEqual(actual, expect) {
|
for _, tc := range cases {
|
||||||
t.Errorf("Was %#v, but expected %#v", actual, expect)
|
SortSliceByValue(tc.actual, hash)
|
||||||
|
if !reflect.DeepEqual(tc.actual, tc.expect) {
|
||||||
|
t.Errorf("Was %#v, but expected %#v", tc.actual, tc.expect)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,7 +386,6 @@ func TestUniformDistribution(t *testing.T) {
|
||||||
"Chi2 condition for .9 is not met (expected %.2f <= %.2f)",
|
"Chi2 condition for .9 is not met (expected %.2f <= %.2f)",
|
||||||
chi2, chiTable[size-1])
|
chi2, chiTable[size-1])
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("sortByInt32Value", func(t *testing.T) {
|
t.Run("sortByInt32Value", func(t *testing.T) {
|
||||||
|
@ -367,7 +426,6 @@ func TestUniformDistribution(t *testing.T) {
|
||||||
"Chi2 condition for .9 is not met (expected %.2f <= %.2f)",
|
"Chi2 condition for .9 is not met (expected %.2f <= %.2f)",
|
||||||
chi2, chiTable[size-1])
|
chi2, chiTable[size-1])
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("hash collision", func(t *testing.T) {
|
t.Run("hash collision", func(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue