/// <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); }
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); } } }
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); }
///<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); }
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"); } } }
public bool IsGreaterThan(RegistrationIdDistance another) { return(this._distance_sumSqr > another._distance_sumSqr); }
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}"); } }