github.com/spaolacci/murmur3@v1.1.0/murmur_test.go (about) 1 package murmur3 2 3 import ( 4 "fmt" 5 "strconv" 6 "testing" 7 ) 8 9 var data = []struct { 10 seed uint32 11 h32 uint32 12 h64_1 uint64 13 h64_2 uint64 14 s string 15 }{ 16 {0x00, 0x00000000, 0x0000000000000000, 0x0000000000000000, ""}, 17 {0x00, 0x248bfa47, 0xcbd8a7b341bd9b02, 0x5b1e906a48ae1d19, "hello"}, 18 {0x00, 0x149bbb7f, 0x342fac623a5ebc8e, 0x4cdcbc079642414d, "hello, world"}, 19 {0x00, 0xe31e8a70, 0xb89e5988b737affc, 0x664fc2950231b2cb, "19 Jan 2038 at 3:14:07 AM"}, 20 {0x00, 0xd5c48bfc, 0xcd99481f9ee902c9, 0x695da1a38987b6e7, "The quick brown fox jumps over the lazy dog."}, 21 22 {0x01, 0x514e28b7, 0x4610abe56eff5cb5, 0x51622daa78f83583, ""}, 23 {0x01, 0xbb4abcad, 0xa78ddff5adae8d10, 0x128900ef20900135, "hello"}, 24 {0x01, 0x6f5cb2e9, 0x8b95f808840725c6, 0x1597ed5422bd493b, "hello, world"}, 25 {0x01, 0xf50e1f30, 0x2a929de9c8f97b2f, 0x56a41d99af43a2db, "19 Jan 2038 at 3:14:07 AM"}, 26 {0x01, 0x846f6a36, 0xfb3325171f9744da, 0xaaf8b92a5f722952, "The quick brown fox jumps over the lazy dog."}, 27 28 {0x2a, 0x087fcd5c, 0xf02aa77dfa1b8523, 0xd1016610da11cbb9, ""}, 29 {0x2a, 0xe2dbd2e1, 0xc4b8b3c960af6f08, 0x2334b875b0efbc7a, "hello"}, 30 {0x2a, 0x7ec7c6c2, 0xb91864d797caa956, 0xd5d139a55afe6150, "hello, world"}, 31 {0x2a, 0x58f745f6, 0xfd8f19ebdc8c6b6a, 0xd30fdc310fa08ff9, "19 Jan 2038 at 3:14:07 AM"}, 32 {0x2a, 0xc02d1434, 0x74f33c659cda5af7, 0x4ec7a891caf316f0, "The quick brown fox jumps over the lazy dog."}, 33 } 34 35 func TestRefStrings(t *testing.T) { 36 for _, elem := range data { 37 38 h32 := New32WithSeed(elem.seed) 39 h32.Write([]byte(elem.s)) 40 if v := h32.Sum32(); v != elem.h32 { 41 t.Errorf("[Hash32] key: '%s', seed: '%d': 0x%x (want 0x%x)", elem.s, elem.seed, v, elem.h32) 42 } 43 44 h32.Reset() 45 h32.Write([]byte(elem.s)) 46 target := fmt.Sprintf("%08x", elem.h32) 47 if p := fmt.Sprintf("%x", h32.Sum(nil)); p != target { 48 t.Errorf("[Hash32] key: '%s', seed: '%d': %s (want %s)", elem.s, elem.seed, p, target) 49 } 50 51 if v := Sum32WithSeed([]byte(elem.s), elem.seed); v != elem.h32 { 52 t.Errorf("[Hash32] key '%s', seed: '%d': 0x%x (want 0x%x)", elem.s, elem.seed, v, elem.h32) 53 } 54 55 h64 := New64WithSeed(elem.seed) 56 h64.Write([]byte(elem.s)) 57 if v := h64.Sum64(); v != elem.h64_1 { 58 t.Errorf("'[Hash64] key: '%s', seed: '%d': 0x%x (want 0x%x)", elem.s, elem.seed, v, elem.h64_1) 59 } 60 61 h64.Reset() 62 h64.Write([]byte(elem.s)) 63 target = fmt.Sprintf("%016x", elem.h64_1) 64 if p := fmt.Sprintf("%x", h64.Sum(nil)); p != target { 65 t.Errorf("[Hash64] key: '%s', seed: '%d': %s (want %s)", elem.s, elem.seed, p, target) 66 } 67 68 if v := Sum64WithSeed([]byte(elem.s), elem.seed); v != elem.h64_1 { 69 t.Errorf("[Hash64] key: '%s', seed: '%d': 0x%x (want 0x%x)", elem.s, elem.seed, v, elem.h64_1) 70 } 71 72 h128 := New128WithSeed(elem.seed) 73 74 h128.Write([]byte(elem.s)) 75 if v1, v2 := h128.Sum128(); v1 != elem.h64_1 || v2 != elem.h64_2 { 76 t.Errorf("[Hash128] key: '%s', seed: '%d': 0x%x-0x%x (want 0x%x-0x%x)", elem.s, elem.seed, v1, v2, elem.h64_1, elem.h64_2) 77 } 78 79 h128.Reset() 80 h128.Write([]byte(elem.s)) 81 target = fmt.Sprintf("%016x%016x", elem.h64_1, elem.h64_2) 82 if p := fmt.Sprintf("%x", h128.Sum(nil)); p != target { 83 t.Errorf("[Hash128] key: '%s', seed: '%d': %s (want %s)", elem.s, elem.seed, p, target) 84 } 85 86 if v1, v2 := Sum128WithSeed([]byte(elem.s), elem.seed); v1 != elem.h64_1 || v2 != elem.h64_2 { 87 t.Errorf("[Hash128] key: '%s', seed: '%d': 0x%x-0x%x (want 0x%x-0x%x)", elem.s, elem.seed, v1, v2, elem.h64_1, elem.h64_2) 88 } 89 } 90 } 91 92 func TestIncremental(t *testing.T) { 93 for _, elem := range data { 94 h32 := New32WithSeed(elem.seed) 95 h128 := New128WithSeed(elem.seed) 96 var i, j int 97 for k := len(elem.s); i < k; i = j { 98 j = 2*i + 3 99 if j > k { 100 j = k 101 } 102 s := elem.s[i:j] 103 print(s + "|") 104 h32.Write([]byte(s)) 105 h128.Write([]byte(s)) 106 } 107 println() 108 if v := h32.Sum32(); v != elem.h32 { 109 t.Errorf("[Hash32] key: '%s', seed: '%d': 0x%x (want 0x%x)", elem.s, elem.seed, v, elem.h32) 110 } 111 if v1, v2 := h128.Sum128(); v1 != elem.h64_1 || v2 != elem.h64_2 { 112 t.Errorf("[Hash128] key: '%s', seed: '%d': 0x%x-0x%x (want 0x%x-0x%x)", elem.s, elem.seed, v1, v2, elem.h64_1, elem.h64_2) 113 } 114 } 115 } 116 117 func Benchmark32(b *testing.B) { 118 buf := make([]byte, 8192) 119 for length := 1; length <= cap(buf); length *= 2 { 120 b.Run(strconv.Itoa(length), func(b *testing.B) { 121 buf = buf[:length] 122 b.SetBytes(int64(length)) 123 b.ResetTimer() 124 for i := 0; i < b.N; i++ { 125 Sum32(buf) 126 } 127 }) 128 } 129 } 130 131 func BenchmarkPartial32(b *testing.B) { 132 buf := make([]byte, 128) 133 for length := 8; length <= cap(buf); length *= 2 { 134 b.Run(strconv.Itoa(length), func(b *testing.B) { 135 buf = buf[:length] 136 b.SetBytes(int64(length)) 137 138 start := (32 / 8) / 2 139 chunks := 7 140 k := length / chunks 141 tail := (length - start) % k 142 143 b.ResetTimer() 144 for i := 0; i < b.N; i++ { 145 hasher := New32() 146 hasher.Write(buf[0:start]) 147 148 for j := start; j+k <= length; j += k { 149 hasher.Write(buf[j : j+k]) 150 } 151 152 hasher.Write(buf[length-tail:]) 153 hasher.Sum32() 154 } 155 }) 156 } 157 } 158 159 func Benchmark64(b *testing.B) { 160 buf := make([]byte, 8192) 161 for length := 1; length <= cap(buf); length *= 2 { 162 b.Run(strconv.Itoa(length), func(b *testing.B) { 163 buf = buf[:length] 164 b.SetBytes(int64(length)) 165 b.ResetTimer() 166 for i := 0; i < b.N; i++ { 167 Sum64(buf) 168 } 169 }) 170 } 171 } 172 173 func Benchmark128(b *testing.B) { 174 buf := make([]byte, 8192) 175 for length := 1; length <= cap(buf); length *= 2 { 176 b.Run(strconv.Itoa(length), func(b *testing.B) { 177 buf = buf[:length] 178 b.SetBytes(int64(length)) 179 b.ResetTimer() 180 for i := 0; i < b.N; i++ { 181 Sum128(buf) 182 } 183 }) 184 } 185 }