quintodrome/utils/hasher/hasher.go

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

75 lines
1.4 KiB
Go
Raw Normal View History

package hasher
2024-05-19 08:35:30 -08:00
import (
"hash/maphash"
"strconv"
2024-07-22 10:27:02 -08:00
"sync"
2024-05-19 17:55:19 -08:00
"github.com/navidrome/navidrome/utils/random"
2024-05-19 08:35:30 -08:00
)
var instance = NewHasher()
func Reseed(id string) {
instance.Reseed(id)
}
2024-05-19 08:35:30 -08:00
func SetSeed(id string, seed string) {
instance.SetSeed(id, seed)
}
func CurrentSeed(id string) string {
instance.mutex.RLock()
defer instance.mutex.RUnlock()
return instance.seeds[id]
}
func HashFunc() func(id, str string) uint64 {
return instance.HashFunc()
}
2024-05-19 08:35:30 -08:00
type Hasher struct {
seeds map[string]string
2024-07-22 10:27:02 -08:00
mutex sync.RWMutex
2024-05-19 08:35:30 -08:00
hashSeed maphash.Seed
}
2024-05-19 08:35:30 -08:00
func NewHasher() *Hasher {
h := new(Hasher)
h.seeds = make(map[string]string)
h.hashSeed = maphash.MakeSeed()
return h
}
2024-05-19 08:35:30 -08:00
// SetSeed sets a seed for the given id
func (h *Hasher) SetSeed(id string, seed string) {
2024-07-22 10:27:02 -08:00
h.mutex.Lock()
defer h.mutex.Unlock()
2024-05-19 08:35:30 -08:00
h.seeds[id] = seed
}
// Reseed generates a new random seed for the given id
func (h *Hasher) Reseed(id string) {
_ = h.reseed(id)
}
func (h *Hasher) reseed(id string) string {
2024-05-19 17:55:19 -08:00
seed := strconv.FormatUint(random.Uint64(), 36)
2024-07-22 10:27:02 -08:00
h.SetSeed(id, seed)
2024-05-19 08:35:30 -08:00
return seed
}
// HashFunc returns a function that hashes a string using the seed for the given id
2024-05-19 08:35:30 -08:00
func (h *Hasher) HashFunc() func(id, str string) uint64 {
return func(id, str string) uint64 {
2024-07-22 10:27:02 -08:00
h.mutex.RLock()
seed, ok := h.seeds[id]
h.mutex.RUnlock()
if !ok {
2024-05-19 08:35:30 -08:00
seed = h.reseed(id)
}
2024-05-19 08:35:30 -08:00
return maphash.Bytes(h.hashSeed, []byte(seed+str))
}
}