Example #1
0
        private IEnumerable <NodeIdentifier <TKey> > NodeLookUp(TKey key,
                                                                IEnumerable <NodeIdentifier <TKey> > knownClosestNodes)
        {
            // convert the closest nodes to a list to prevent multiple enumerations
            List <NodeIdentifier <TKey> > closestNodes = knownClosestNodes.ToList();

            List <NodeIdentifier <TKey> > orderedNodes = closestNodes.ToObservable()
                                                         .CachedSelectMany(nodeId =>
            {
                IKadNode <TKey, TValue> client = CreateClientFromNodeId(nodeId);
                FindNodeResult <TKey> nodes    = client.FindNode(key, NodeIdentifier);
                return(Observable.Return(nodes));
            }, maxConcurrent: Settings.Cita)
                                                         .SelectMany(findNodeResult => findNodeResult.Nodes)
                                                         .Merge(closestNodes.ToObservable())
                                                         .Distinct()
                                                         .Do(RegisterNewNode)
                                                         .Timeout(Settings.ClientTimeOut)
                                                         .OnErrorResumeNext(Observable.Empty <NodeIdentifier <TKey> >())
                                                         .ToEnumerable()
                                                         .OrderBy(nodeId => nodeId.NodeId,
                                                                  new LamdaComparer <TKey>((n1, n2) => RoutingTable.DistanceComparer(n1, n2, key)))
                                                         .Take(Settings.K)
                                                         .ToList();

            return(orderedNodes.SequenceEqual(closestNodes)
                       ? orderedNodes
                       : NodeLookUp(key, orderedNodes));
        }