After this commit, dev auth would start working with the `REMARK_URL` hostname instead of the previously hardcoded 127.0.0.1. Breaks development setup where `REMARK_URL` was set to a non-standard value and dev auth was running on 127.0.0.1 and working, as, after that change, it would stop working.
80 lines
1.4 KiB
Go
80 lines
1.4 KiB
Go
package rendezvous
|
|
|
|
type Rendezvous struct {
|
|
nodes map[string]int
|
|
nstr []string
|
|
nhash []uint64
|
|
hash Hasher
|
|
}
|
|
|
|
type Hasher func(s string) uint64
|
|
|
|
func New(nodes []string, hash Hasher) *Rendezvous {
|
|
r := &Rendezvous{
|
|
nodes: make(map[string]int, len(nodes)),
|
|
nstr: make([]string, len(nodes)),
|
|
nhash: make([]uint64, len(nodes)),
|
|
hash: hash,
|
|
}
|
|
|
|
for i, n := range nodes {
|
|
r.nodes[n] = i
|
|
r.nstr[i] = n
|
|
r.nhash[i] = hash(n)
|
|
}
|
|
|
|
return r
|
|
}
|
|
|
|
func (r *Rendezvous) Lookup(k string) string {
|
|
// short-circuit if we're empty
|
|
if len(r.nodes) == 0 {
|
|
return ""
|
|
}
|
|
|
|
khash := r.hash(k)
|
|
|
|
var midx int
|
|
var mhash = xorshiftMult64(khash ^ r.nhash[0])
|
|
|
|
for i, nhash := range r.nhash[1:] {
|
|
if h := xorshiftMult64(khash ^ nhash); h > mhash {
|
|
midx = i + 1
|
|
mhash = h
|
|
}
|
|
}
|
|
|
|
return r.nstr[midx]
|
|
}
|
|
|
|
func (r *Rendezvous) Add(node string) {
|
|
r.nodes[node] = len(r.nstr)
|
|
r.nstr = append(r.nstr, node)
|
|
r.nhash = append(r.nhash, r.hash(node))
|
|
}
|
|
|
|
func (r *Rendezvous) Remove(node string) {
|
|
// find index of node to remove
|
|
nidx := r.nodes[node]
|
|
|
|
// remove from the slices
|
|
l := len(r.nstr)
|
|
r.nstr[nidx] = r.nstr[l]
|
|
r.nstr = r.nstr[:l]
|
|
|
|
r.nhash[nidx] = r.nhash[l]
|
|
r.nhash = r.nhash[:l]
|
|
|
|
// update the map
|
|
delete(r.nodes, node)
|
|
moved := r.nstr[nidx]
|
|
r.nodes[moved] = nidx
|
|
}
|
|
|
|
func xorshiftMult64(x uint64) uint64 {
|
|
x ^= x >> 12 // a
|
|
x ^= x << 25 // b
|
|
x ^= x >> 27 // c
|
|
return x * 2685821657736338717
|
|
}
|