void AddInternal(IActorId id) { var hash = HashAlgorithm.ComputeHash(id.ToString()); lock (actors) { var index = actors.BinarySearch(KeyValuePair.New(hash, (IActorId)null), n => n.Key); if (index >= 0) return; actors.Insert(~index, KeyValuePair.New(hash, id)); } }
public DhtRing(IActorId self) { this.HashAlgorithm = new SHA1Managed(); this.SelfId = self; this.actors.Add(KeyValuePair.New(HashAlgorithm.ComputeHash(self.ToString()), self)); }
public IActorId Find(int ttl, IActorId originator = null) { lock (actors) { if (ttl < 0) return null; int selfIndex = SelfIndex; if (selfIndex < 0) return null; int distance = (int)Math.Pow(2, ttl); if (distance >= actors.Count) return null; int endPoint = selfIndex + distance; if (endPoint >= actors.Count) endPoint -= actors.Count; var destination = actors[endPoint]; if (destination.Equals(SelfId)) return null; if (originator == null) originator = SelfId; var hash = HashAlgorithm.ComputeHash(originator.ToString()); var originatorIndex = actors.BinarySearch(KeyValuePair.New(hash,(IActorId) null), n => n.Key); if (IsBetween(originatorIndex, selfIndex, endPoint)) { // if the originator is between us and the endpoint it means // if we send this message it will have wrapped completely around // the ring. if we do that nodes will receive the same message twice // so stop this message instead. return null; } return destination.Value; } }