ring

package
v0.16.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 29, 2026 License: Apache-2.0 Imports: 3 Imported by: 0

Documentation

Overview

Package ring implements rendezvous (highest-random-weight, HRW) hashing — the L0 sharding primitive (DESIGN.md §11). Each key is placed on the nodes that score highest for it, where a node's score for a key is a hash of the key seeded by the node's identity. This gives:

  • Deterministic placement: every node computes the same owners for a key with no shared state beyond the membership list, so routing needs no coordinator on the hot path.
  • Minimal movement (~1/N) on membership change: adding a node only ever steals keys *to itself*, and removing a node only redistributes *its* keys — existing assignments between other nodes never reshuffle. This is the property that makes rebalancing move the minimal set of parts.

The ring is immutable; membership changes (Ring.With / Ring.Without) return a new ring.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Node

type Node struct {
	ID   string
	Zone string
}

Node is a cluster member. ID is its stable, unique identity (the only thing that affects a node's HRW score). Zone is an optional failure domain: Ring.Lookup spreads a key's replicas across distinct zones where possible, so a single zone failure cannot take out every replica. An empty Zone means "unspecified"; when every node's zone is empty (the default) placement is pure HRW, identical to a zone-unaware ring.

type Ring

type Ring struct {
	// contains filtered or unexported fields
}

Ring is an immutable set of nodes over which keys are placed by HRW hashing. The zero value is an empty ring; construct one with New. Safe for concurrent use (read-only).

func New

func New(nodes ...Node) *Ring

New returns a ring over nodes. Nodes with an empty or duplicate ID are dropped (ID is the identity), so membership is a well-formed set.

func (*Ring) Len

func (r *Ring) Len() int

Len returns the number of nodes.

func (*Ring) Lookup

func (r *Ring) Lookup(key []byte, rf int) []Node

Lookup returns up to rf nodes responsible for key — the first is the primary, the rest are replicas. It returns fewer than rf nodes only when the ring has fewer than rf members, and nil for an empty ring or rf ≤ 0. Selection is **zone-aware**: among nodes sorted by descending HRW score (ties broken by ID), it greedily picks the highest-scoring node from each not-yet-used zone first, so a key's replicas spread across as many distinct failure domains as possible; once distinct zones are exhausted (fewer zones than rf) it fills the remaining slots in score order. The primary is always the single highest-scoring node, and when every zone is empty the result is exactly the score-ordered top-rf (pure HRW). The result is fully deterministic.

func (*Ring) Nodes

func (r *Ring) Nodes() []Node

Nodes returns the membership, sorted by ID (a copy; callers may mutate it).

func (*Ring) Primary

func (r *Ring) Primary(key []byte) (Node, bool)

Primary returns the single owner of key (the highest-scoring node) and true, or a zero Node and false for an empty ring.

func (*Ring) With

func (r *Ring) With(n Node) *Ring

With returns a new ring with n added (a no-op clone if n.ID is empty or already present).

func (*Ring) Without

func (r *Ring) Without(id string) *Ring

Without returns a new ring with the node identified by id removed.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL