@@ -32,18 +32,21 @@ var DefaultHash Hash = xxhash.Sum64String
3232// DefaultTokensPerNode is the default number of virtual nodes per node.
3333const DefaultTokensPerNode = 100
3434
35- // New creates a new hash ring.
36- func New (fn Hash , tokensPerNode int , initialNodes ... string ) * Ring {
37- if fn == nil {
38- fn = DefaultHash
35+ // New creates a new hash ring with the given configuration and adds the given nodes.
36+ // The given Hash (or DefaultHash if nil) is used to hash nodes and keys (strings).
37+ // Each node is assigned tokensPerNode tokens (or DefaultTokensPerNode if <= 0) – aka. virtual nodes – for a more
38+ // uniform key distribution.
39+ func New (hash Hash , tokensPerNode int , initialNodes ... string ) * Ring {
40+ if hash == nil {
41+ hash = DefaultHash
3942 }
4043 if tokensPerNode <= 0 {
4144 tokensPerNode = DefaultTokensPerNode
4245 }
4346
4447 numTokens := len (initialNodes ) * tokensPerNode
4548 r := & Ring {
46- hash : fn ,
49+ hash : hash ,
4750 tokensPerNode : tokensPerNode ,
4851
4952 tokens : make ([]uint64 , 0 , numTokens ),
@@ -53,8 +56,9 @@ func New(fn Hash, tokensPerNode int, initialNodes ...string) *Ring {
5356 return r
5457}
5558
56- // Ring implements consistent hashing, aka ring hash (not thread-safe).
57- // It hashes nodes and keys onto a ring of tokens. Keys are mapped to the next node on the ring.
59+ // Ring implements consistent hashing, aka. ring hash (not thread-safe).
60+ // It hashes nodes and keys (strings) onto a ring of tokens. Keys are mapped to the next token (node) on the ring.
61+ // Nodes cannot be removed. Instantiate a new Ring instead.
5862type Ring struct {
5963 hash Hash
6064 tokensPerNode int
@@ -63,10 +67,12 @@ type Ring struct {
6367 tokenToNode map [uint64 ]string
6468}
6569
70+ // IsEmpty returns true if there are no nodes in this Ring.
6671func (r * Ring ) IsEmpty () bool {
6772 return len (r .tokens ) == 0
6873}
6974
75+ // AddNodes adds hash tokens for the given nodes to this Ring.
7076func (r * Ring ) AddNodes (nodes ... string ) {
7177 for _ , node := range nodes {
7278 for i := 0 ; i < r .tokensPerNode ; i ++ {
@@ -80,6 +86,7 @@ func (r *Ring) AddNodes(nodes ...string) {
8086 slices .Sort (r .tokens )
8187}
8288
89+ // Hash hashes the given key onto the ring of tokens and returns the node that belongs to the next token on the ring.
8390func (r * Ring ) Hash (key string ) string {
8491 if r .IsEmpty () {
8592 return ""
0 commit comments