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  }