Deterministic pagination in random albums sort (#1841)
* Deterministic pagination in random albums sort * Reseed on first random page * Add unit tests * Use rand in Subsonic API * Use different seeds per user on SEEDEDRAND() SQLite3 function * Small refactor * Fix id mismatch * Add seeded random to media_file (subsonic endpoint `getRandomSongs`) * Refactor * Remove unneeded import --------- Co-authored-by: Deluan <deluan@navidrome.org>
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
package hasher
|
||||
|
||||
import "hash/maphash"
|
||||
|
||||
var instance = NewHasher()
|
||||
|
||||
func Reseed(id string) {
|
||||
instance.Reseed(id)
|
||||
}
|
||||
|
||||
func HashFunc() func(id, str string) uint64 {
|
||||
return instance.HashFunc()
|
||||
}
|
||||
|
||||
type hasher struct {
|
||||
seeds map[string]maphash.Seed
|
||||
}
|
||||
|
||||
func NewHasher() *hasher {
|
||||
h := new(hasher)
|
||||
h.seeds = make(map[string]maphash.Seed)
|
||||
return h
|
||||
}
|
||||
|
||||
// Reseed generates a new seed for the given id
|
||||
func (h *hasher) Reseed(id string) {
|
||||
h.seeds[id] = maphash.MakeSeed()
|
||||
}
|
||||
|
||||
// HashFunc returns a function that hashes a string using the seed for the given id
|
||||
func (h *hasher) HashFunc() func(id, str string) uint64 {
|
||||
return func(id, str string) uint64 {
|
||||
var hash maphash.Hash
|
||||
var seed maphash.Seed
|
||||
var ok bool
|
||||
if seed, ok = h.seeds[id]; !ok {
|
||||
seed = maphash.MakeSeed()
|
||||
h.seeds[id] = seed
|
||||
}
|
||||
hash.SetSeed(seed)
|
||||
_, _ = hash.WriteString(str)
|
||||
return hash.Sum64()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user