using System; using System.Linq; namespace JwKdsV.Core.LoadBalance { /// /// Consistent Hash Select /// /// public class ConsistentHashRouting : Routing { private Tuple> _cacheConsistentHashTuple; private readonly int _vnodes; public ConsistentHashRouting() : this(0) { } public ConsistentHashRouting(int virtualNodesFactor) { _vnodes = virtualNodesFactor < 1 ? LoadBalanceConstants.DefaultVirtualNodesFactor : virtualNodesFactor; } protected override T selectInternal(object message, T[] instances) { if (message == null) return default(T); string messageHash = message.GetHashCode().ToString(); var consistentHashCircle = getInstanceConsistentHashCircle(instances); return consistentHashCircle.NodeFor(messageHash); } /// /// Create instance Consistent Hash Circle, if instance no change will direct read the cache /// /// /// private ConsistentHash getInstanceConsistentHashCircle(T[] instances) { if (_cacheConsistentHashTuple == null || !_cacheConsistentHashTuple.Item1.SequenceEqual(instances)) { _cacheConsistentHashTuple = new Tuple>(instances, ConsistentHash.Create(instances, _vnodes)); } return _cacheConsistentHashTuple.Item2; } } }