Example #1
0
        /// <returns>null if no neighbors found for routing</returns>
        public ConnectionToNeighbor RouteInviteRequest(LocalDrpPeer localDrpPeer, RoutedRequest routedRequest)
        {
            var req    = routedRequest.InviteReq;
            var logger = routedRequest.Logger;
            ConnectionToNeighbor   r           = null;
            RegistrationIdDistance minDistance = null;
            var connectedNeighborsForRouting   = localDrpPeer.GetConnectedNeighborsForRouting(routedRequest).ToList();

            foreach (var connectedPeer in connectedNeighborsForRouting)
            {
                var distanceToConnectedPeer = req.ResponderRegistrationId.GetDistanceTo(_cryptoLibrary, connectedPeer.RemoteRegistrationId, NumberOfDimensions);
                logger.WriteToLog_routing_detail($"distanceToConnectedPeer={distanceToConnectedPeer} from {req} to {connectedPeer}");
                if (minDistance == null || minDistance.IsGreaterThan(distanceToConnectedPeer))
                {
                    minDistance = distanceToConnectedPeer;
                    r           = connectedPeer;
                }
            }
            if (r == null)
            {
                logger.WriteToLog_routing_detail($"no neighbors found for routing");
            }

            return(r);
        }
Example #2
0
        async Task TestDirection(Logger logger, double[] vectorFromThisToDestination, int iteration = 0)
        {
            // are all vectors along directionVector?
            bool neighbor_along_destinationVector_exists = false;

            foreach (var neighbor in ConnectedNeighborsCanBeUsedForNewRequests)
            {
                var thisRegIdVector               = RegistrationIdDistance.GetVectorValues(CryptoLibrary, this.Configuration.LocalPeerRegistrationId, vectorFromThisToDestination.Length);
                var neighborRegIdVector           = RegistrationIdDistance.GetVectorValues(CryptoLibrary, neighbor.RemoteRegistrationId, vectorFromThisToDestination.Length);
                var vectorFromLocalPeerToNeighbor = new double[thisRegIdVector.Length];
                for (int i = 0; i < vectorFromLocalPeerToNeighbor.Length; i++)
                {
                    vectorFromLocalPeerToNeighbor[i] = RegistrationIdDistance.GetDifferenceInLoopedRegistrationIdSpace(thisRegIdVector[i], neighborRegIdVector[i]);
                }

                double multProduct = 0;
                for (int dimensionI = 0; dimensionI < vectorFromThisToDestination.Length; dimensionI++)
                {
                    multProduct += vectorFromLocalPeerToNeighbor[dimensionI] * vectorFromThisToDestination[dimensionI];
                }
                if (multProduct > 0)
                {
                    neighbor_along_destinationVector_exists = true;
                    break;
                }
            }
            if (neighbor_along_destinationVector_exists == false)
            {
                if (iteration < 8)
                {
                    if (ConnectedNeighbors.Count < _configuration.AbsoluteMaxNumberOfNeighbors)
                    {
                        logger.WriteToLog_higherLevelDetail_EmitListOfPeers($"no neighbors to destination {MiscProcedures.VectorToString(vectorFromThisToDestination)}, sending REGISTER request... iteration={iteration}", this);

                        // try to fix the pain: connect to neighbors at empty direction
                        await ConnectToNewNeighborAsync(Engine.DateTimeNowUtc, true, vectorFromThisToDestination);

                        if (iteration >= 2)
                        {
                            await Engine.EngineThreadQueue.WaitAsync(TimeSpan.FromSeconds(10), "fixing empty direction 1237");
                        }

                        await TestDirection(logger, vectorFromThisToDestination, iteration + 1);
                    }
                    else
                    {
                        logger.WriteToLog_lightPain_EmitListOfPeers($"no neighbors to destination {MiscProcedures.VectorToString(vectorFromThisToDestination)} after {iteration} iterations. {ConnectedNeighbors.Count} connected neighbors already", this);
                    }
                }
                else
                { // pain is not fixed
                    logger.WriteToLog_lightPain_EmitListOfPeers($"no neighbors to destination {MiscProcedures.VectorToString(vectorFromThisToDestination)} after {iteration} iterations. {ConnectedNeighbors.Count} connected neighbors", this);
                }
            }
        }
Example #3
0
        public static double[] GetDifferenceVector(RegistrationId from, RegistrationId to, ICryptoLibrary cryptoLibrary, int numberOfDimensions)
        {
            var fromRegIdVector        = RegistrationIdDistance.GetVectorValues(cryptoLibrary, from, numberOfDimensions);
            var destinationRegIdVector = RegistrationIdDistance.GetVectorValues(cryptoLibrary, to, numberOfDimensions);
            var diff = new double[fromRegIdVector.Length];

            for (int i = 0; i < diff.Length; i++)
            {
                diff[i] = RegistrationIdDistance.GetDifferenceInLoopedRegistrationIdSpace(fromRegIdVector[i], destinationRegIdVector[i]);
            }
            return(diff);
        }
Example #4
0
        ///<param name="considerValueOfUniqueSectors">false when registering via EP</param>
        /// <returns>component of mutual value</returns>
        public float GetValue(float[] neighborVector, bool neighborIsAlreadyConnected, bool considerValueOfUniqueSectors)
        {
            float distanceFromLocalPeerToNeighbor = 0;
            var   vectorFromLocalPeerToNeighbor   = new float[NumberOfDimensions];

            for (int i = 0; i < neighborVector.Length; i++)
            {
                var vectorFromLocalPeerToNeighbor_i = RegistrationIdDistance.GetDifferenceInLoopedRegistrationIdSpace(_localPeerVector[i], neighborVector[i]);
                vectorFromLocalPeerToNeighbor[i] = vectorFromLocalPeerToNeighbor_i;
                distanceFromLocalPeerToNeighbor += vectorFromLocalPeerToNeighbor_i * vectorFromLocalPeerToNeighbor_i;
            }
            distanceFromLocalPeerToNeighbor = (float)Math.Sqrt(distanceFromLocalPeerToNeighbor);
            float r = -distanceFromLocalPeerToNeighbor;

            if (considerValueOfUniqueSectors)
            {
                var sectorIndex            = _vsic.GetSectorIndex(vectorFromLocalPeerToNeighbor);
                var neighborsCountInSector = _currentNeighborsCountPerSectors[sectorIndex];
                if (neighborIsAlreadyConnected)
                {
                    if (neighborsCountInSector == 1)
                    {
                        r += EmptySectorOccupationValue;                              // this neighbor is the only one in the sector
                    }
                    //   else if (neighborsCountInSector == 2) r += 1.0f; // TODO questionable heuristics really 1 or another value?
                }
                else
                {
                    if (neighborsCountInSector == 0)
                    {
                        r += EmptySectorOccupationValue;
                    }
                    //  else if (neighborsCountInSector == 1) r += 1.0f; // TODO questionable heuristics really 1 or another value?
                }
            }
            return(r);
        }
Example #5
0
        public P2pConnectionValueCalculator(float[] localPeerVector, IEnumerable <float[]> currentNeighborsVectors, Action <string> wtl)
        {
            _localPeerVector = localPeerVector;
            if (!_vsics.TryGetValue(NumberOfDimensions, out _vsic))
            {
                _vsic = new VectorSectorIndexCalculator(NumberOfDimensions);
                _vsics.Add(NumberOfDimensions, _vsic);
            }
            _currentNeighborsCountPerSectors = new int[_vsic.IndexesCount];

            int neighborIndex = 0;
            var vectorsFromLocalPeerToNeighbors = new List <float[]>();

            foreach (var neighborVector in currentNeighborsVectors)
            {
                var   vectorFromLocalPeerToNeighbor        = new float[NumberOfDimensions];
                float vectorFromLocalPeerToNeighbor_length = 0;
                for (int i = 0; i < NumberOfDimensions; i++)
                {
                    var vectorFromLocalPeerToNeighbor_i = RegistrationIdDistance.GetDifferenceInLoopedRegistrationIdSpace(_localPeerVector[i], neighborVector[i]);
                    vectorFromLocalPeerToNeighbor[i]      = vectorFromLocalPeerToNeighbor_i;
                    vectorFromLocalPeerToNeighbor_length += vectorFromLocalPeerToNeighbor_i * vectorFromLocalPeerToNeighbor_i;
                }
                vectorFromLocalPeerToNeighbor_length = (float)Math.Sqrt(vectorFromLocalPeerToNeighbor_length);
                var sectorIndex = _vsic.GetSectorIndex(vectorFromLocalPeerToNeighbor);
                _currentNeighborsCountPerSectors[sectorIndex]++;


                for (int i = 0; i < NumberOfDimensions; i++)
                {
                    vectorFromLocalPeerToNeighbor[i] /= vectorFromLocalPeerToNeighbor_length;
                }
                wtl?.Invoke($"neighbor#{neighborIndex} localToNeighbor=[{String.Join(";", vectorFromLocalPeerToNeighbor.Select(x => x.ToString()))}] sectorIndex={sectorIndex}");

                vectorsFromLocalPeerToNeighbors.Add(vectorFromLocalPeerToNeighbor);

                neighborIndex++;
            }

            _emptyDirectionVector = null;

            //_emptyDirectionVector = FindEmptyDirection(NumberOfDimensions, _vsic, vectorsFromLocalPeerToNeighbors);
            //if (_emptyDirectionVector != null)
            //{
            //    _thereIsNeighborAlongEmptyDirectionVector = false;
            //    neighborIndex = 0;
            //    foreach (var vectorFromLocalPeerToNeighbor in vectorsFromLocalPeerToNeighbors)
            //    {
            //        float mulResult = 0;
            //        for (int i = 0; i < NumberOfDimensions; i++)
            //            mulResult += vectorFromLocalPeerToNeighbor[i] * _emptyDirectionVector[i];
            //        wtl?.Invoke($"neighbor#{neighborIndex}=[{String.Join(";", vectorFromLocalPeerToNeighbor.Select(x => x.ToString()))}]:mulResult={mulResult};");
            //        if (mulResult > 0)
            //        {
            //            _thereIsNeighborAlongEmptyDirectionVector = true;
            //            break;
            //        }
            //        neighborIndex++;
            //    }
            //}

            if (wtl != null)
            {
                for (int sectorIndex = 0; sectorIndex < _vsic.IndexesCount; sectorIndex++)
                {
                    wtl.Invoke($"sector{sectorIndex} simplexVector=[{String.Join(";", _vsic.GetSimplexVector(sectorIndex).Select(x => x.ToString()))}]");
                }
                if (_emptyDirectionVector != null)
                {
                    wtl.Invoke($"emptyDirectionVector=[{String.Join(";", _emptyDirectionVector.Select(x => x.ToString()))}]");
                }
                else
                {
                    wtl.Invoke($"emptyDirectionVector=null");
                }
            }
        }
Example #6
0
 public bool IsGreaterThan(RegistrationIdDistance another)
 {
     return(this._distance_sumSqr > another._distance_sumSqr);
 }
Example #7
0
        void RouteRegistrationRequest_LocalDrpPeerIteration(LocalDrpPeer localDrpPeer, RoutedRequest routedRequest,
                                                            ref double?maxP2pConnectionValue,
                                                            ref ConnectionToNeighbor proxyToDestinationPeer, ref LocalDrpPeer acceptAt)
        {
            var req = routedRequest.RegisterReq;
            var connectedNeighborsForRouting = localDrpPeer.GetConnectedNeighborsForRouting(routedRequest).ToList();
            var logger = routedRequest.Logger;

            var distancesToNeighbors         = new List <RegistrationIdDistance>();
            var requestedDirectionMulResults = new List <double>();
            int connectedNeighborsCountThatMatchReqFilters = 0;

            foreach (var neighbor in connectedNeighborsForRouting)
            {
                if (req.MinimalDistanceToNeighbor != 0)
                {
                    var distanceToNeighbor = req.RequesterRegistrationId.GetDistanceTo(_cryptoLibrary, neighbor.RemoteRegistrationId, NumberOfDimensions);
                    distancesToNeighbors.Add(distanceToNeighbor);
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"distanceToNeighbor={distanceToNeighbor} from REGISTER REQ {req.RequesterRegistrationId} to {neighbor} (req.min={req.MinimalDistanceToNeighbor})");
                    }
                    if (distanceToNeighbor.IsLessThan(req.MinimalDistanceToNeighbor))
                    {
                        // skip: this is too close than requested
                        if (logger.WriteToLog_detail_enabled)
                        {
                            logger.WriteToLog_detail($"skipping connection to {neighbor}: distance={distanceToNeighbor} is less than requested={req.MinimalDistanceToNeighbor}");
                        }
                        continue;
                    }
                }
                if (req.DirectionVectorNullable != null)
                {
                    var    requestedDirectionVector = req.DirectionVectorNullableD;
                    var    vectorFromThisToNeighbor = RegistrationId.GetDifferenceVector(req.RequesterRegistrationId, neighbor.RemoteRegistrationId, CryptoLibrary, Configuration.SandboxModeOnly_NumberOfDimensions);
                    double mulResult = 0;
                    for (int i = 0; i < requestedDirectionVector.Length; i++)
                    {
                        mulResult += requestedDirectionVector[i] * requestedDirectionVector[i];
                    }
                    requestedDirectionMulResults.Add(mulResult);
                    if (mulResult < 0)
                    {
                        if (logger.WriteToLog_detail_enabled)
                        {
                            logger.WriteToLog_detail($"skipping connection to {neighbor}: direction from requester to neighbor does not match requested vector");
                        }
                        continue;
                    }
                }
                connectedNeighborsCountThatMatchReqFilters++;

                var p2pConnectionValue_withNeighbor = P2pConnectionValueCalculator.GetMutualP2pConnectionValue(CryptoLibrary, req.RequesterRegistrationId, req.RequesterNeighborsBusySectorIds,
                                                                                                               neighbor.RemoteRegistrationId, neighbor.RemoteNeighborsBusySectorIds ?? 0, NumberOfDimensions, false, false, false);

                if (logger.WriteToLog_deepDetail_enabled)
                {
                    logger.WriteToLog_deepDetail($"p2pConnectionValue_withNeighbor={p2pConnectionValue_withNeighbor} from REGISTER REQ {req.RequesterRegistrationId} to {neighbor}");
                }

                if (maxP2pConnectionValue == null || maxP2pConnectionValue < p2pConnectionValue_withNeighbor)
                {
                    maxP2pConnectionValue  = p2pConnectionValue_withNeighbor;
                    proxyToDestinationPeer = neighbor;
                    acceptAt = null;
                }
            }

            if (connectedNeighborsCountThatMatchReqFilters == 0 && connectedNeighborsForRouting.Count != 0)
            {
                if (req.MinimalDistanceToNeighbor != 0)
                {
                    // special case: we are inside the "minDistance" hypersphere: move away from the requester, proxy to most distant neighbor
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"special case: move away from the requester, proxy to most distant neighbor");
                    }
                    RegistrationIdDistance maxDistance = null;
                    for (int i = 0; i < connectedNeighborsForRouting.Count; i++)
                    {
                        var neighbor           = connectedNeighborsForRouting[i];
                        var distanceToNeighbor = distancesToNeighbors[i];
                        if (logger.WriteToLog_detail_enabled)
                        {
                            logger.WriteToLog_detail($"distanceToConnectedPeer={distanceToNeighbor} from REGISTER REQ {req.RequesterRegistrationId} to {neighbor} (req.min={req.MinimalDistanceToNeighbor})");
                        }
                        if (maxDistance == null || distanceToNeighbor.IsGreaterThan(maxDistance))
                        {
                            maxDistance            = distanceToNeighbor;
                            proxyToDestinationPeer = neighbor;
                            acceptAt = null;
                        }
                    }
                }
                if (req.DirectionVectorNullable != null)
                {
                    if (logger.WriteToLog_detail_enabled)
                    {
                        logger.WriteToLog_detail($"special case: move towards the specified direction");
                    }
                    double?maxMulResult = null;
                    for (int i = 0; i < connectedNeighborsForRouting.Count; i++)
                    {
                        var neighbor  = connectedNeighborsForRouting[i];
                        var mulResult = requestedDirectionMulResults[i];
                        if (logger.WriteToLog_detail_enabled)
                        {
                            logger.WriteToLog_detail($"mulResult={mulResult} for {neighbor}");
                        }
                        if (maxMulResult == null || mulResult > maxMulResult)
                        {
                            maxMulResult           = mulResult;
                            proxyToDestinationPeer = neighbor;
                            acceptAt = null;
                        }
                    }
                }
            }

            // dont connect to local peer if already connected
            if (localDrpPeer.Configuration.LocalPeerRegistrationId.Equals(req.RequesterRegistrationId) == true)
            {
                if (logger.WriteToLog_detail_enabled)
                {
                    logger.WriteToLog_detail($"not accepting request at local peer: it has same regID {req.RequesterRegistrationId}");
                }
            }
            else if (localDrpPeer.ConnectedNeighbors.Any(x => x.RemoteRegistrationId.Equals(req.RequesterRegistrationId)) == true)
            {
                if (logger.WriteToLog_detail_enabled)
                {
                    logger.WriteToLog_detail($"not accepting request at local peer: already connected to {req.RequesterRegistrationId}");
                }
            }
            else if (localDrpPeer.ConnectedNeighbors.Count > localDrpPeer.Configuration.AbsoluteMaxNumberOfNeighbors)
            {
                if (logger.WriteToLog_detail_enabled)
                {
                    logger.WriteToLog_detail($"not accepting request at local peer: already too many neighbors ({localDrpPeer.ConnectedNeighbors.Count})");
                }
            }
            else
            {
                var p2pConnectionValue_withLocalPeer = P2pConnectionValueCalculator.GetMutualP2pConnectionValue(CryptoLibrary, req.RequesterRegistrationId, req.RequesterNeighborsBusySectorIds,
                                                                                                                localDrpPeer.Configuration.LocalPeerRegistrationId, localDrpPeer.ConnectedNeighborsBusySectorIds, NumberOfDimensions, false, false, false);
                if (logger.WriteToLog_detail_enabled)
                {
                    logger.WriteToLog_detail($"p2pConnectionValue_withLocalPeer={p2pConnectionValue_withLocalPeer} from REGISTER REQ {req.RequesterRegistrationId} to {localDrpPeer.Configuration.LocalPeerRegistrationId}");
                }
                if (maxP2pConnectionValue == null || p2pConnectionValue_withLocalPeer > maxP2pConnectionValue)
                {
                    maxP2pConnectionValue  = p2pConnectionValue_withLocalPeer;
                    proxyToDestinationPeer = null;
                    acceptAt = localDrpPeer;
                }
            }

            if (logger.WriteToLog_detail_enabled)
            {
                logger.WriteToLog_detail($"<< RouteRegistrationRequest_LocalDrpPeerIteration() proxyTo={proxyToDestinationPeer}, acceptAt={acceptAt}");
            }
        }