github.com/segmentio/parquet-go@v0.0.0-20230712180008-5d42db8f0d47/bloom/xxhash/sum64uint_test.go (about) 1 package xxhash_test 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 "testing" 7 "testing/quick" 8 "time" 9 10 "github.com/segmentio/parquet-go/bloom/xxhash" 11 ) 12 13 func TestSumUint8(t *testing.T) { 14 b := [1]byte{0: 42} 15 h := xxhash.Sum64Uint8(42) 16 x := xxhash.Sum64(b[:]) 17 if h != x { 18 t.Errorf("got %064b; want %064b", h, x) 19 } 20 } 21 22 func TestSumUint16(t *testing.T) { 23 b := [2]byte{0: 42} 24 h := xxhash.Sum64Uint16(42) 25 x := xxhash.Sum64(b[:]) 26 if h != x { 27 t.Errorf("got %064b; want %064b", h, x) 28 } 29 } 30 31 func TestSumUint32(t *testing.T) { 32 b := [4]byte{0: 42} 33 h := xxhash.Sum64Uint32(42) 34 x := xxhash.Sum64(b[:]) 35 if h != x { 36 t.Errorf("got %064b; want %064b", h, x) 37 } 38 } 39 40 func TestSumUint64(t *testing.T) { 41 b := [8]byte{0: 42} 42 h := xxhash.Sum64Uint64(42) 43 x := xxhash.Sum64(b[:]) 44 if h != x { 45 t.Errorf("got %064b; want %064b", h, x) 46 } 47 } 48 49 func TestSumUint128(t *testing.T) { 50 b := [16]byte{0: 42} 51 h := xxhash.Sum64Uint128(b) 52 x := xxhash.Sum64(b[:]) 53 if h != x { 54 t.Errorf("got %064b; want %064b", h, x) 55 } 56 } 57 58 func TestMultiSum64Uint8(t *testing.T) { 59 f := func(v []uint8) bool { 60 h := make([]uint64, len(v)) 61 n := xxhash.MultiSum64Uint8(h, v) 62 if n != len(v) { 63 t.Errorf("return value mismatch: got %d; want %d", n, len(v)) 64 return false 65 } 66 for i := range h { 67 x := xxhash.Sum64(v[i : i+1]) 68 if h[i] != x { 69 t.Errorf("sum at index %d mismatch: got %064b; want %064b", i, h[i], x) 70 return false 71 } 72 } 73 return true 74 } 75 if err := quick.Check(f, nil); err != nil { 76 t.Error(err) 77 } 78 } 79 80 func TestMultiSum64Uint16(t *testing.T) { 81 f := func(v []uint16) bool { 82 h := make([]uint64, len(v)) 83 n := xxhash.MultiSum64Uint16(h, v) 84 if n != len(v) { 85 t.Errorf("return value mismatch: got %d; want %d", n, len(v)) 86 return false 87 } 88 for i := range h { 89 b := [2]byte{} 90 binary.LittleEndian.PutUint16(b[:], v[i]) 91 x := xxhash.Sum64(b[:]) 92 if h[i] != x { 93 t.Errorf("sum at index %d mismatch: got %064b; want %064b", i, h[i], x) 94 return false 95 } 96 } 97 return true 98 } 99 if err := quick.Check(f, nil); err != nil { 100 t.Error(err) 101 } 102 } 103 104 func TestMultiSum64Uint32(t *testing.T) { 105 f := func(v []uint32) bool { 106 h := make([]uint64, len(v)) 107 n := xxhash.MultiSum64Uint32(h, v) 108 if n != len(v) { 109 t.Errorf("return value mismatch: got %d; want %d", n, len(v)) 110 return false 111 } 112 for i := range h { 113 b := [4]byte{} 114 binary.LittleEndian.PutUint32(b[:], v[i]) 115 x := xxhash.Sum64(b[:]) 116 if h[i] != x { 117 t.Errorf("sum at index %d mismatch: got %064b; want %064b", i, h[i], x) 118 return false 119 } 120 } 121 return true 122 } 123 if err := quick.Check(f, nil); err != nil { 124 t.Error(err) 125 } 126 } 127 128 func TestMultiSum64Uint64(t *testing.T) { 129 f := func(v []uint64) bool { 130 h := make([]uint64, len(v)) 131 n := xxhash.MultiSum64Uint64(h, v) 132 if n != len(v) { 133 t.Errorf("return value mismatch: got %d; want %d", n, len(v)) 134 return false 135 } 136 for i := range h { 137 b := [8]byte{} 138 binary.LittleEndian.PutUint64(b[:], v[i]) 139 x := xxhash.Sum64(b[:]) 140 if h[i] != x { 141 t.Errorf("sum at index %d mismatch: got %064b; want %064b", i, h[i], x) 142 return false 143 } 144 } 145 return true 146 } 147 if err := quick.Check(f, nil); err != nil { 148 t.Error(err) 149 } 150 } 151 152 func TestMultiSum64Uint128(t *testing.T) { 153 f := func(v [][16]byte) bool { 154 h := make([]uint64, len(v)) 155 n := xxhash.MultiSum64Uint128(h, v) 156 if n != len(v) { 157 t.Errorf("return value mismatch: got %d; want %d", n, len(v)) 158 return false 159 } 160 for i := range h { 161 x := xxhash.Sum64(v[i][:]) 162 if h[i] != x { 163 t.Errorf("sum at index %d mismatch: got %064b; want %064b", i, h[i], x) 164 return false 165 } 166 } 167 return true 168 } 169 if err := quick.Check(f, nil); err != nil { 170 t.Error(err) 171 } 172 } 173 174 func reportThroughput(b *testing.B, loops, count int, start time.Time) { 175 throughput := float64(loops*count) / time.Since(start).Seconds() 176 // Measure the throughput of writes to the output buffer; 177 // it makes the results comparable across benchmarks that 178 // have inputs of different sizes. 179 b.SetBytes(8 * int64(count)) 180 b.ReportMetric(0, "ns/op") 181 b.ReportMetric(throughput, "hash/s") 182 } 183 184 const benchmarkBufferSize = 4096 185 186 func BenchmarkMultiSum64Uint8(b *testing.B) { 187 in := make([]uint8, benchmarkBufferSize) 188 for i := range in { 189 in[i] = uint8(i) 190 } 191 b.Run(fmt.Sprintf("%dKB", benchmarkBufferSize/1024), func(b *testing.B) { 192 out := make([]uint64, len(in)) 193 start := time.Now() 194 for i := 0; i < b.N; i++ { 195 _ = xxhash.MultiSum64Uint8(out, in) 196 } 197 reportThroughput(b, b.N, len(out), start) 198 }) 199 } 200 201 func BenchmarkMultiSum64Uint16(b *testing.B) { 202 in := make([]uint16, benchmarkBufferSize/2) 203 for i := range in { 204 in[i] = uint16(i) 205 } 206 b.Run(fmt.Sprintf("%dKB", benchmarkBufferSize/1024), func(b *testing.B) { 207 out := make([]uint64, len(in)) 208 start := time.Now() 209 for i := 0; i < b.N; i++ { 210 _ = xxhash.MultiSum64Uint16(out, in) 211 } 212 reportThroughput(b, b.N, len(out), start) 213 }) 214 } 215 216 func BenchmarkMultiSum64Uint32(b *testing.B) { 217 in := make([]uint32, benchmarkBufferSize/4) 218 for i := range in { 219 in[i] = uint32(i) 220 } 221 b.Run(fmt.Sprintf("%dKB", benchmarkBufferSize/1024), func(b *testing.B) { 222 out := make([]uint64, len(in)) 223 start := time.Now() 224 for i := 0; i < b.N; i++ { 225 _ = xxhash.MultiSum64Uint32(out, in) 226 } 227 reportThroughput(b, b.N, len(out), start) 228 }) 229 } 230 231 func BenchmarkMultiSum64Uint64(b *testing.B) { 232 in := make([]uint64, benchmarkBufferSize/8) 233 for i := range in { 234 in[i] = uint64(i) 235 } 236 b.Run(fmt.Sprintf("%dKB", benchmarkBufferSize/1024), func(b *testing.B) { 237 out := make([]uint64, len(in)) 238 start := time.Now() 239 for i := 0; i < b.N; i++ { 240 _ = xxhash.MultiSum64Uint64(out, in) 241 } 242 reportThroughput(b, b.N, len(out), start) 243 }) 244 } 245 246 func BenchmarkMultiSum64Uint128(b *testing.B) { 247 in := make([][16]byte, benchmarkBufferSize/16) 248 for i := range in { 249 binary.LittleEndian.PutUint64(in[i][:8], uint64(i)) 250 binary.LittleEndian.PutUint64(in[i][8:], uint64(i)) 251 } 252 b.Run(fmt.Sprintf("%dKB", benchmarkBufferSize/1024), func(b *testing.B) { 253 out := make([]uint64, len(in)) 254 start := time.Now() 255 for i := 0; i < b.N; i++ { 256 _ = xxhash.MultiSum64Uint128(out, in) 257 } 258 reportThroughput(b, b.N, len(out), start) 259 }) 260 }