Added more tests

This commit is contained in:
Eduard Urbach 2023-07-23 11:40:22 +02:00
parent f9f9410b1f
commit 0a39a88c74
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
3 changed files with 42 additions and 27 deletions

View File

@ -8,10 +8,14 @@ import (
)
func BenchmarkSize(b *testing.B) {
b.Run("7", bench(7))
b.Run("8", bench(8))
b.Run("16", bench(16))
b.Run("17", bench(17))
b.Run("32", bench(32))
b.Run("33", bench(33))
b.Run("64", bench(64))
b.Run("65", bench(65))
b.Run("128", bench(128))
b.Run("256", bench(256))
b.Run("512", bench(512))

View File

@ -13,7 +13,7 @@ func add(x uint64, in []byte) uint64 {
var i int
// Cache lines on modern processors are 64 bytes long.
// A single uint64 consumes 64 bits (8 bytes).
// A single uint64 consumes 8 bytes.
// That means we should read 8 uint64 at a time.
for ; i < len(in)-63; i += 64 {
words := (*[8]uint64)(unsafe.Pointer(&in[i]))
@ -46,5 +46,5 @@ func add(x uint64, in []byte) uint64 {
}
func mix(x uint64, b uint64) uint64 {
return (x + b) * 0x50003
return (x + b) * 0xD0003
}

View File

@ -7,42 +7,53 @@ import (
"git.akyoto.dev/go/hash"
)
// Hashes generated in tests will be saved to check for collisions.
var hashes = map[uint64][]byte{}
func TestTinyCollisions(t *testing.T) {
for size := 1; size < 8; size++ {
tmp := make([]byte, size)
index := 0
// addHash adds a new hash and checks for collisions.
func addHash(t *testing.T, sum uint64, data []byte) {
saved, found := hashes[sum]
for i := 0; i < 256; i++ {
tmp[index] += 1
h := hash.Bytes(tmp)
previous, found := hashes[h]
if found && !bytes.Equal(saved, data) {
t.Fatalf("collision between %v and %v:\nhash %064b", saved, data, sum)
}
if found && !bytes.Equal(tmp, previous) {
t.Fatalf("collision between %v and %v:\nhash %064b", previous, tmp, h)
}
save := make([]byte, len(data))
copy(save, data)
hashes[sum] = save
}
save := make([]byte, size)
copy(save, tmp)
hashes[h] = save
index = (index + 1) % size
// TestTiny hashes every single permutation that is 1-32 bytes long.
func TestTiny(t *testing.T) {
for size := 1; size <= 32; size++ {
data := make([]byte, size)
for i := 0; i <= 255*size; i++ {
sum := hash.Bytes(data)
addHash(t, sum, data)
data[i%size] += 1
}
}
}
func TestZeroedCollisions(t *testing.T) {
// TestZeroed hashes completely zeroed buffers that are 1-8192 bytes long.
func TestZeroed(t *testing.T) {
zero := make([]byte, 8192)
for size := 1; size <= len(zero); size++ {
tmp := zero[:size]
h := hash.Bytes(tmp)
previous, found := hashes[h]
if found && !bytes.Equal(tmp, previous) {
t.Fatalf("collision between %v and %v:\nhash %064b", previous, tmp, h)
}
hashes[h] = tmp
data := zero[:size]
sum := hash.Bytes(data)
addHash(t, sum, data)
}
}
// TestSameByte hashes every byte repetition that is 1-512 bytes long.
func TestSameByte(t *testing.T) {
for b := 1; b < 256; b++ {
for size := 1; size <= 512; size++ {
data := bytes.Repeat([]byte{byte(b)}, size)
sum := hash.Bytes(data)
addHash(t, sum, data)
}
}
}