blob: 6003bffba395db07814287e775efcae9d7ba81d1 [file]
package xxhash
import (
"bytes"
"encoding/binary"
"fmt"
"hash"
"hash/crc32"
"strings"
"testing"
"github.com/OneOfOne/xxhash"
"github.com/spaolacci/murmur3"
)
func TestSum(t *testing.T) {
for i, tt := range []struct {
input string
want uint64
}{
{"", 0xef46db3751d8e999},
{"a", 0xd24ec4f1a98c6e5b},
{"as", 0x1c330fb2d66be179},
{"asd", 0x631c37ce72a97393},
{"asdf", 0x415872f599cea71e},
{
// Exactly 63 characters, which exercises all code paths.
"Call me Ishmael. Some years ago--never mind how long precisely-",
0x02a2e85470d6fd96,
},
} {
for chunkSize := 1; chunkSize <= len(tt.input); chunkSize++ {
x := New()
for j := 0; j < len(tt.input); j += chunkSize {
end := j + chunkSize
if end > len(tt.input) {
end = len(tt.input)
}
chunk := []byte(tt.input[j:end])
n, err := x.Write(chunk)
if err != nil || n != len(chunk) {
t.Fatalf("[i=%d,chunkSize=%d] Write: got (%d, %v); want (%d, nil)",
i, chunkSize, n, err, len(chunk))
}
}
if got := x.Sum64(); got != tt.want {
t.Fatalf("[i=%d,chunkSize=%d] got 0x%x; want 0x%x",
i, chunkSize, got, tt.want)
}
var b [8]byte
binary.BigEndian.PutUint64(b[:], tt.want)
if got := x.Sum(nil); !bytes.Equal(got, b[:]) {
t.Fatalf("[i=%d,chunkSize=%d] Sum: got %v; want %v",
i, chunkSize, got, b[:])
}
}
if got := Sum64([]byte(tt.input)); got != tt.want {
t.Fatalf("[i=%d] Sum64: got 0x%x; want 0x%x", i, got, tt.want)
}
}
}
func TestReset(t *testing.T) {
parts := []string{"The quic", "k br", "o", "wn fox jumps", " ov", "er the lazy ", "dog."}
x := New()
for _, part := range parts {
x.Write([]byte(part))
}
h0 := x.Sum64()
x.Reset()
x.Write([]byte(strings.Join(parts, "")))
h1 := x.Sum64()
if h0 != h1 {
t.Errorf("0x%x != 0x%x", h0, h1)
}
}
var (
sink uint64
sinkb []byte
)
func sumFunc(h hash.Hash) func(b []byte) uint64 {
return func(b []byte) uint64 {
h.Reset()
h.Write(b)
sinkb = h.Sum(nil)
return 0 // value doesn't matter
}
}
func BenchmarkHashes(b *testing.B) {
for _, ht := range []struct {
name string
f func(b []byte) uint64
}{
{"xxhash", Sum64},
{"OneOfOne", xxhash.Checksum64},
{"murmur3", murmur3.Sum64},
{"CRC-32", sumFunc(crc32.NewIEEE())},
} {
for _, nt := range []struct {
name string
n int
}{
{"5b", 5},
{"20b", 20},
{"100b", 100},
{"4KB", 4e3},
{"10MB", 10e6},
} {
s := make([]byte, nt.n)
for i := range s {
s[i] = byte(i)
}
b.Run(
fmt.Sprintf("%s,n=%s", ht.name, nt.name),
func(b *testing.B) { bench(b, ht.f, s) },
)
}
}
}
func bench(b *testing.B, f func(b []byte) uint64, s []byte) {
b.SetBytes(int64(len(s)))
for i := 0; i < b.N; i++ {
sink = f(s)
}
}