43 lines
1.2 KiB
Go
43 lines
1.2 KiB
Go
//
|
||
// hash.go
|
||
// Copyright (C) 2023 tiglog <me@tiglog.com>
|
||
//
|
||
// Distributed under terms of the MIT license.
|
||
//
|
||
|
||
package gcache
|
||
|
||
// IHash is responsible for generating unsigned, 64-bit hash of provided string. IHash should minimize collisions
|
||
// (generating same hash for different strings) and while performance is also important fast functions are preferable (i.e.
|
||
// you can use FarmHash family).
|
||
type IHash interface {
|
||
Sum64(string) uint64
|
||
}
|
||
|
||
// newDefaultHash returns a new 64-bit FNV-1a IHash which makes no memory allocations.
|
||
// Its Sum64 method will lay the value out in big-endian byte order.
|
||
// See https://en.wikipedia.org/wiki/Fowler–Noll–Vo_hash_function
|
||
func newDefaultHash() IHash {
|
||
return fnv64a{}
|
||
}
|
||
|
||
type fnv64a struct{}
|
||
|
||
const (
|
||
// offset64 FNVa offset basis. See https://en.wikipedia.org/wiki/Fowler–Noll–Vo_hash_function#FNV-1a_hash
|
||
offset64 = 14695981039346656037
|
||
// prime64 FNVa prime value. See https://en.wikipedia.org/wiki/Fowler–Noll–Vo_hash_function#FNV-1a_hash
|
||
prime64 = 1099511628211
|
||
)
|
||
|
||
// Sum64 gets the string and returns its uint64 hash value.
|
||
func (f fnv64a) Sum64(key string) uint64 {
|
||
var hash uint64 = offset64
|
||
for i := 0; i < len(key); i++ {
|
||
hash ^= uint64(key[i])
|
||
hash *= prime64
|
||
}
|
||
|
||
return hash
|
||
}
|