ExRingRing (ex_ring_ring v0.1.0)
Copy MarkdownExRingRing - Consistent Hash Ring implementation in Elixir.
This module provides the main public API for creating and manipulating consistent hash rings.
Example
# Create nodes
nodes = ExRingRing.list_to_nodes([:a, :b, :c, :d, :e])
# Create a ring
ring = ExRingRing.make(nodes)
# Find a node for an item
{:ok, node} = ExRingRing.find_node(ring, "item_1")
# Collect multiple nodes for replication
nodes = ExRingRing.collect_nodes(ring, "item_1", 3)
# Add a node
new_ring = ExRingRing.add_node(ring, ExRingRing.Domain.Entities.Node.make(:f))
# Remove a node
new_ring = ExRingRing.remove_node(ring, :c)
Summary
Functions
Adds a single node to the ring.
Adds nodes to the ring.
Collects N nodes for the given item in order of priority.
Finds the node responsible for the given item.
Gets the number of nodes in the ring.
Gets all nodes in the ring as a list.
Checks if the given term is a valid ring.
Converts a list of keys/tuples to a list of nodes.
Creates a new consistent hash ring.
Creates a new consistent hash ring from a list of keys.
Removes a single node from the ring.
Removes nodes from the ring by their keys.
Functions
@spec add_node( ExRingRing.Domain.Entities.Ring.t(), ExRingRing.Domain.Entities.Node.t() ) :: ExRingRing.Domain.Entities.Ring.t()
Adds a single node to the ring.
@spec add_nodes(ExRingRing.Domain.Entities.Ring.t(), [ ExRingRing.Domain.Entities.Node.t() ]) :: ExRingRing.Domain.Entities.Ring.t()
Adds nodes to the ring.
Existing nodes with the same key will be overwritten.
@spec collect_nodes(ExRingRing.Domain.Entities.Ring.t(), term(), non_neg_integer()) :: [ ExRingRing.Domain.Entities.Node.t() ]
Collects N nodes for the given item in order of priority.
Useful for replication - the first node is primary, subsequent nodes are replicas.
@spec find_node(ExRingRing.Domain.Entities.Ring.t(), term()) :: {:ok, ExRingRing.Domain.Entities.Node.t()} | :error
Finds the node responsible for the given item.
Returns {:ok, node} or :error if the ring is empty.
@spec get_node_count(ExRingRing.Domain.Entities.Ring.t()) :: non_neg_integer()
Gets the number of nodes in the ring.
@spec get_nodes(ExRingRing.Domain.Entities.Ring.t()) :: [ ExRingRing.Domain.Entities.Node.t() ]
Gets all nodes in the ring as a list.
Checks if the given term is a valid ring.
@spec list_to_nodes([term()]) :: [ExRingRing.Domain.Entities.Node.t()]
Converts a list of keys/tuples to a list of nodes.
Accepts:
- Keys:
[:a, :b, :c] - Key-data pairs:
[{:a, "data_a"}, {:b, "data_b"}] - Key-data-options tuples:
[{:a, "data_a", [weight: 2]}, {:b, "data_b"}]
Examples
iex> ExRingRing.list_to_nodes([:a, :b, :c]) |> length()
3
iex> ExRingRing.list_to_nodes([{:a, "server_a"}, {:b, "server_b", [weight: 2]}]) |> length()
2
@spec make( [ExRingRing.Domain.Entities.Node.t() | term()], keyword() ) :: ExRingRing.Domain.Entities.Ring.t()
Creates a new consistent hash ring.
Options
:virtual_node_count- Number of virtual nodes per physical node (default: 256):max_hash_byte_size- Maximum bytes of hash to use (default: 4):hash_algorithm- Hash algorithm::md5,:sha,:sha256,:crc32,:phash2(default::md5):implementation- Ring implementation::static(fast reads) or:dynamic(fast writes) (default::static)
Examples
iex> nodes = ExRingRing.list_to_nodes([:a, :b, :c])
iex> ring = ExRingRing.make(nodes)
iex> ExRingRing.is_ring(ring)
true
iex> ring = ExRingRing.make_from_keys([:a, :b, :c], virtual_node_count: 128)
iex> ExRingRing.is_ring(ring)
true
@spec make_from_keys( [term()], keyword() ) :: ExRingRing.Domain.Entities.Ring.t()
Creates a new consistent hash ring from a list of keys.
Examples
iex> ring = ExRingRing.make_from_keys([:a, :b, :c])
iex> ExRingRing.is_ring(ring)
true
@spec remove_node(ExRingRing.Domain.Entities.Ring.t(), term()) :: ExRingRing.Domain.Entities.Ring.t()
Removes a single node from the ring.
@spec remove_nodes(ExRingRing.Domain.Entities.Ring.t(), [term()]) :: ExRingRing.Domain.Entities.Ring.t()
Removes nodes from the ring by their keys.