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;
}
}
}