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  }