/// <summary>
 /// Creates the routing mechanism. Make sure to set the Max* fields.
 /// </summary>
 /// <param name="tcsResponses">The current task responses that are running.</param>
 /// <param name="tcsRoutingResponse">The response task from this routing request.</param>
 /// <param name="peerFilters"></param>
 public RoutingMechanism(VolatileReferenceArray<TaskCompletionSource<Message.Message>> tcsResponses,
     TcsRouting tcsRoutingResponse, ICollection<IPeerFilter> peerFilters)
 {
     TcsResponses = tcsResponses;
     TcsRoutingResponse = tcsRoutingResponse;
     _peerFilters = peerFilters;
 }
 public RoutingMechanism CreateRoutingMechanism(TcsRouting tcsRouting)
 {
     var tcsResponses = new TaskCompletionSource<Message.Message>[Parallel];
     var tcsResponseArray = new VolatileReferenceArray<TaskCompletionSource<Message.Message>>(tcsResponses);
     var routingMechanism = new RoutingMechanism(tcsResponseArray, tcsRouting, PeerFilters)
     {
         MaxDirectHits = MaxDirectHits,
         MaxFailures = MaxFailures,
         MaxNoNewInfo = MaxNoNewInfo,
         MaxSucess = MaxSuccess
     };
     return routingMechanism;
 }
Exemple #3
0
 public void SetTcsRouting(TcsRouting tcsRouting)
 {
     
 }
        /// <summary>
        /// Looks for a route to the given peer address.
        /// </summary>
        /// <param name="peerAddresses">Nodes that should be asked first for a route.</param>
        /// <param name="routingBuilder"></param>
        /// <param name="type"></param>
        /// <param name="cc"></param>
        /// <returns>A task object that is set to complete if the route has been found.</returns>
        private TcsRouting Routing(ICollection<PeerAddress> peerAddresses, RoutingBuilder routingBuilder,
            Message.Message.MessageType type, ChannelCreator cc)
        {
            try
            {
                if (peerAddresses == null)
                {
                    throw new ArgumentException("Some nodes/addresses need to be specified.");
                }
                bool randomSearch = routingBuilder.LocationKey == null;
                IComparer<PeerAddress> comparer;
                if (randomSearch)
                {
                    comparer = _peerBean.PeerMap.CreateComparer();
                }
                else
                {
                    comparer = PeerMap.CreateComparer(routingBuilder.LocationKey);
                }
                var queueToAsk = new SortedSet<PeerAddress>(comparer);
                var alreadyAsked = new SortedSet<PeerAddress>(comparer);

                // As presented by Kazuyuki Shudo at AIMS 2009, it is better to ask random
                // peers with the data than ask peers that are ordered by distance.
                // -> this balances load
                var directHits = new SortedDictionary<PeerAddress, DigestInfo>(comparer);
                var potentialHits = new SortedSet<PeerAddress>(comparer);

                // fill initially
                queueToAsk.AddAll(peerAddresses);
                alreadyAsked.Add(_peerBean.ServerPeerAddress);
                potentialHits.Add(_peerBean.ServerPeerAddress);

                // domain key can be null if we bootstrap
                if (type == Message.Message.MessageType.Request2
                    && routingBuilder.DomainKey != null
                    && !randomSearch
                    && _peerBean.DigestStorage != null)
                {
                    Number640 from;
                    Number640 to;
                    if (routingBuilder.From != null && routingBuilder.To != null)
                    {
                        from = routingBuilder.From;
                        to = routingBuilder.To;
                    }
                    else if (routingBuilder.ContentKey == null)
                    {
                        from = new Number640(routingBuilder.LocationKey, routingBuilder.DomainKey, Number160.Zero, Number160.Zero);
                        to = new Number640(routingBuilder.LocationKey, routingBuilder.DomainKey, Number160.MaxValue, Number160.MaxValue);
                    }
                    else
                    {
                        from = new Number640(routingBuilder.LocationKey, routingBuilder.DomainKey, routingBuilder.ContentKey, Number160.Zero);
                        to = new Number640(routingBuilder.LocationKey, routingBuilder.DomainKey, routingBuilder.ContentKey, Number160.MaxValue);
                    }

                    var digestBean = _peerBean.DigestStorage.Digest(from, to, -1, true);
                    if (digestBean.Size > 0)
                    {
                        directHits.Add(_peerBean.ServerPeerAddress, digestBean);
                    }
                }
                else if (type == Message.Message.MessageType.Request3
                         && !randomSearch
                         && _peerBean.DigestTracker != null)
                {
                    var digestInfo = _peerBean.DigestTracker.Digest(routingBuilder.LocationKey, routingBuilder.DomainKey,
                        routingBuilder.ContentKey);
                    // we always put ourselfs to the tracker list, so we need to check
                    // if we know also other peers on our trackers
                    if (digestInfo.Size > 0)
                    {
                        directHits.Add(_peerBean.ServerPeerAddress, digestInfo);
                    }
                }

                var tcsRouting = new TcsRouting();
                if (peerAddresses.Count == 0)
                {
                    tcsRouting.SetNeighbors(directHits, potentialHits, alreadyAsked, routingBuilder.IsBootstrap, false);
                }
                else
                {
                    // If a peer bootstraps to itself, then the size of peer addresses is 1
                    // and it contains itself. Check for that because we need to know if we
                    // are routing, bootstrapping and bootstrapping to ourselfs, to return
                    // the correct status for the task.
                    var isRoutingOnlyToSelf = peerAddresses.Count == 1 &&
                                               peerAddresses.First().Equals(_peerBean.ServerPeerAddress);

                    var routingMechanism = routingBuilder.CreateRoutingMechanism(tcsRouting);
                    routingMechanism.SetQueueToAsk(queueToAsk);
                    routingMechanism.SetPotentialHits(potentialHits);
                    routingMechanism.SetDirectHits(directHits);
                    routingMechanism.SetAlreadyAsked(alreadyAsked);

                    routingBuilder.SetIsRoutingOnlyToSelf(isRoutingOnlyToSelf);
                    RoutingRec(routingBuilder, routingMechanism, type, cc);
                }
                return tcsRouting;
            }
            catch (Exception ex)
            {
                Logger.Error("An exception occurred during routing.", ex);
                throw;
            }
        }