medley provides hashing logic aimed at distributed hashing.
Medley is a hashing package aimed at various types of distributed hashing. Currently, only consistent hashing is supported.
This project and everyone participating in it are governed by the XMiDT Code Of Conduct. By participating, you agree to this Code.
go get -u github.com/xmidt-org/medley@latest
Medley is a hashing library that provides some additional functionality on top of the golang stdlib package hash. Below are some key features of medley. See the godoc for more information.
Medley adds a Hash interface that is genericized. This normalizes hash.Hash32 and hash.Hash64 in the standard library.
// 32-bit hashing
h32 := medley.AsHash32(fnv.New32a())
h32.WriteString("here is a string")
fmt.Println(h.Value()) // instead of Sum32()
// 64-bit hashing ... notice how similar it is
h64 := medley.AsHash32(fnv.New64a())
h64.WriteString("here is a string")
fmt.Println(h.Value()) // instead of Sum64()The WriteString method computes the hash of a string without additional allocation.
The consistent package implements simple consistent hashing. A hash Ring is built using a Builder.
// First, create a ring using the desired configuration
builder := new(consistent.Builder[string, string]).
Algorithm(medley.FNV64a()). // the default is medley.Default64()
VNodes(10) // the default is consistent.DefaultVNodes
// Now, build rings based on sequences
hostNames := []string{"host-1.test.org", "host-2.test.org", "host-3.test.org"}
ring := builder.Build(
len(hostNames), // optional. used as a hint for preallocation. can be zero or negative for no preallocation.
medley.Stringify(slices.Values(hostNames)),
)
fmt.Println(ring.NearestString("myobject"))Custom values are also supported on a Ring. You simply have to tell medley how to obtain the hashable object from each custom value.
type server struct {
hostName string
port int
}
servers := []*server{
{hostName: "host-1.test.org", port: 1111},
{hostName: "host-2.test.org", port: 2222},
{hostName: "host-3.test.org", port: 2222},
}
var builder Builder[string, *server]
ring := builder.Build(
len(servers),
medley.Objectify(
func(s *server) string { return s.hostName }, // here's where we tell medley how to get a hashable object from a *service
slices.Values(servers),
)
)
fmt.Println(ring.NearestString("myobject"))Refer to CONTRIBUTING.md.