Celerity.Ring 2.4.0

There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Celerity.Ring --version 2.4.0
                    
NuGet\Install-Package Celerity.Ring -Version 2.4.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Celerity.Ring" Version="2.4.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Celerity.Ring" Version="2.4.0" />
                    
Directory.Packages.props
<PackageReference Include="Celerity.Ring" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Celerity.Ring --version 2.4.0
                    
#r "nuget: Celerity.Ring, 2.4.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Celerity.Ring@2.4.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Celerity.Ring&version=2.4.0
                    
Install as a Cake Addin
#tool nuget:?package=Celerity.Ring&version=2.4.0
                    
Install as a Cake Tool

Celerity.Ring

Deterministic consistent-hashing and rendezvous (HRW) rings for sharding and request routing — generic over your key type and a zero-cost, JIT-inlined Celerity hasher.

dotnet add package Celerity.Ring

The BCL has no consistent-hashing type, so the status quo is "hand-roll a SortedDictionary<uint, TNode> + a hash, or take a stale NuGet." Celerity.Ring fills that gap and adds the property a sharded fleet actually needs: byte-identical key→node assignment across processes, runtimes, and CPU architectures (x64 / arm64 / Blazor WASM). A ring built from string.GetHashCode() reshards silently between processes because that hash is randomized per run; Celerity.Ring routes through a specified deterministic hash (StringXxHash3Hasher) and pure integer mixing — no randomized hash, no float/log, no endianness-dependent step.

Consistent-hash ring

using Celerity.Ring;

var ring = new StringConsistentHashRing<string>();   // string keys, deterministic StringXxHash3Hasher
ring.Add("cache-a", "10.0.0.1");
ring.Add("cache-b", "10.0.0.2");
ring.Add("cache-c", "10.0.0.3", weight: 2);          // twice the virtual nodes -> ~2x the keys

string owner = ring.GetNode("user:42");              // single node for this key
var replicas = ring.GetReplicas("user:42", 3);       // primary + 2 distinct successors

ring.Remove("cache-b");                              // only cache-b's ~1/N keys remap

Each node is placed at VirtualNodesPerNode (default 160) positions on a [0, 2^32) ring, so load is even and a departing node hands its keys to many successors instead of one. Adding/removing a node remaps only about 1/NodeCount of keys — versus the near-total reshuffle of hash % nodeCount.

Rendezvous (HRW) hash

No ring array, nothing to rebuild on membership change — ideal for small, churning clusters:

var pool = new StringRendezvousHash<string>();
pool.Add("node-1", "10.0.0.1");
pool.Add("node-2", "10.0.0.2");

string owner = pool.GetNode("tenant:7");             // highest-scoring node for this key
var ranked = pool.GetReplicas("tenant:7", 2);        // ranked preference list

Scoring is pure-integer max (weights are realized as integer sub-labels), so HRW stays deterministic across platforms with no floating-point log. A lookup is O(NodeCount) scaled by total weight.

Generic over your key type

Both types are generic over TKey and a struct IHashProvider<TKey> the JIT inlines on the routing hot path:

using Celerity.Hashing;

var byId  = new ConsistentHashRing<Endpoint, long, Int64WangNaiveHasher>();
var byGuid = new RendezvousHash<Endpoint, Guid, GuidHasher>();

For cross-process agreement, use a specified deterministic hasher (StringXxHash3Hasher, GuidHasher, an integer hasher) — not DefaultHasher<string>, which delegates to the per-run-randomized BCL string hash.

Concurrency

Reads (GetNode / TryGetNode / GetReplicas) are lock-free: each mutation publishes an immutable snapshot with a single volatile write, so a reader always sees a consistent topology. Mutations (Add / Remove) must be serialized by the caller.

Why managed (and not a native binding)

GetNode(key) is one chatty call over one small managed key on the request hot path. Binding a native ring (libketama) means marshaling the key on every lookup, it can only hash byte buffers (not your inlined generic hasher), and it needs a per-RID native binary that Blazor WASM / Native AOT / IL2CPP can't load. Determinism across a heterogeneous fleet is a correctness requirement a randomized GetHashCode and a per-arch .so cannot meet. A pure-managed ring runs identically on every RID with no native dependency.

Part of the Celerity family.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.4.1-beta.4 26 7/26/2026
2.4.0 38 7/26/2026
2.3.1-beta.15 45 7/25/2026
2.3.1-beta.8 39 7/23/2026
2.3.1-beta.2 36 7/22/2026
2.3.0 82 7/19/2026
2.2.1-beta.24 55 7/18/2026
2.2.1-beta.18 51 7/14/2026
2.2.1-beta.15 46 7/12/2026