Skip to content

Repository files navigation

medley

medley provides hashing logic aimed at distributed hashing.

Build Status codecov.io Go Report Card Quality Gate Status Apache V2 License GitHub Release GoDoc

Summary

Medley is a hashing package aimed at various types of distributed hashing. Currently, only consistent hashing is supported.

Table of Contents

Code of Conduct

This project and everyone participating in it are governed by the XMiDT Code Of Conduct. By participating, you agree to this Code.

Install

go get -u github.com/xmidt-org/medley@latest

Overview

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.

Key Features

Generic medley.Hash interface

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.

Consistent Hashing

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"))

Contributing

Refer to CONTRIBUTING.md.

About

Consistent hashing with a focus on large numbers of nodes

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages

Generated from xmidt-org/.go-template