github.com/tobgu/qframe@v0.4.0/internal/hash/memhash_test.go (about) 1 package hash_test 2 3 import ( 4 "fmt" 5 "math/rand" 6 "testing" 7 8 "github.com/tobgu/qframe/internal/hash" 9 ) 10 11 const noSeed int64 = 0 12 const seed1 int64 = 1 13 const seed2 int64 = 2 14 const seed3 int64 = 3 15 16 func genInts(seed int64, size int) []int { 17 result := make([]int, size) 18 r := rand.New(rand.NewSource(seed)) 19 if seed == noSeed { 20 // Sorted slice 21 for ix := range result { 22 result[ix] = ix 23 } 24 } else { 25 // Random slice 26 for ix := range result { 27 result[ix] = r.Intn(size) 28 } 29 } 30 31 return result 32 } 33 34 func genIntsWithCardinality(seed int64, size, cardinality int) []int { 35 result := genInts(seed, size) 36 for i, x := range result { 37 result[i] = x % cardinality 38 } 39 40 return result 41 } 42 43 func genStringsWithCardinality(seed int64, size, cardinality, strLen int) []string { 44 baseStr := "abcdefghijklmnopqrstuvxyz"[:strLen] 45 result := make([]string, size) 46 for i, x := range genIntsWithCardinality(seed, size, cardinality) { 47 result[i] = fmt.Sprintf("%s%d", baseStr, x) 48 } 49 return result 50 } 51 52 func Test_StringDistribution(t *testing.T) { 53 size := 100000 54 strs1 := genStringsWithCardinality(seed1, 100000, 1000, 10) 55 strs2 := genStringsWithCardinality(seed2, 100000, 10, 10) 56 strs3 := genStringsWithCardinality(seed3, 100000, 2, 10) 57 58 hashCounter := make(map[uint32]int) 59 stringCounter := make(map[string]int) 60 for i := 0; i < size; i++ { 61 val := hash.HashBytes([]byte(strs1[i]), 0) 62 val = hash.HashBytes([]byte(strs2[i]), val) 63 val = hash.HashBytes([]byte(strs3[i]), val) 64 h := uint32(val) 65 hashCounter[h] += 1 66 stringCounter[strs1[i]+strs2[i]+strs3[i]] += 1 67 } 68 69 // For this input the hash is perfect so we expect the same number 70 // of different hashes as actual values. 71 if len(hashCounter) < len(stringCounter) { 72 t.Errorf("Unexpected hash count: %d, %d", len(hashCounter), len(stringCounter)) 73 } 74 } 75 76 func Test_SmallIntDistribution(t *testing.T) { 77 result := make(map[uint64]uint64) 78 for i := 1; i < 177; i++ { 79 val := hash.HashBytes([]byte{0, 0, 0, 0, 0, 0, 0, byte(i)}, 0) 80 result[val] = result[val] + 1 81 } 82 83 if len(result) != 176 { 84 t.Errorf("%d: %v", len(result), result) 85 } 86 }