private void RouteChangeListener(string alg, IMNodeInternal target, IMLink oldRoute, IMLink newRoute, float oldDist, float dist) { Logger.Debug(Name + " changing route to " + target.Name + ". " + (oldRoute == null ? "No old route" : "Old route: " + oldRoute.Name) + ". " + (newRoute == null ? "No new route" : "New route: " + newRoute.Name)); if (OnForwardingTableChange != null && (oldRoute == null || newRoute == null || !oldRoute.Equals(newRoute) || oldDist != dist)) { OnForwardingTableChange(ID, ForwardingTableList); } //If not highlighting or not highlighting the route that was changed quit if ((oldRoute != null && newRoute != null && oldRoute.Equals(newRoute)) || !GlobalHighlighting || !target.Equals(_globalHighlightTarget) || (GlobalHighlightingSingle && !HighlightingSingle && !Equals(_globalHighlightRoot))) { return; } if (oldRoute != null) { oldRoute.Reset(); if (HighlightingSingle) { oldRoute.OtherEnd(this).ResetHighlight(this); } } if (newRoute != null) { newRoute.Colour = _globalHighlightColour; if (GlobalHighlightingSingle) { _highlightState = HighlghtState.HighlightingSingle; newRoute.OtherEnd(this).Highlight(this); } } else { _highlightState = HighlghtState.NotHighlighting; } _highlightedLink = newRoute; }
protected void SetRoute(string alg, UUID target, IMLink link, float dist) { if (_table.ContainsKey(target)) { IMLink oldLink = _table[target]; float oldDist = _distances[target]; _table[target] = link; _distances[target] = dist; if (OnRouteChange != null && IsCurrentAlgorithm && (!link.Equals(oldLink) || dist != oldDist)) { OnRouteChange(alg, KnownNodes[target], oldLink, link, oldDist, dist); } } else { _table.Add(target, link); _distances.Add(target, dist); if (OnRouteChange != null && IsCurrentAlgorithm) { OnRouteChange(alg, KnownNodes[target], null, link, -1f, dist); } } }
private void RouteChangeListener(string alg, IMNodeInternal target, IMLink oldRoute, IMLink newRoute, float oldDist, float dist) { Logger.Debug(Name + " changing route to " + target.Name + ". " + (oldRoute == null ? "No old route" : "Old route: " + oldRoute.Name) + ". " + (newRoute == null ? "No new route" : "New route: " + newRoute.Name)); if (OnForwardingTableChange != null && (oldRoute == null || newRoute == null || !oldRoute.Equals(newRoute) || oldDist != dist)) OnForwardingTableChange(ID, ForwardingTableList); //If not highlighting or not highlighting the route that was changed quit if ((oldRoute != null && newRoute != null && oldRoute.Equals(newRoute)) || !GlobalHighlighting || !target.Equals(_globalHighlightTarget) || (GlobalHighlightingSingle && !HighlightingSingle && !Equals(_globalHighlightRoot))) return; if (oldRoute != null) { oldRoute.Reset(); if (HighlightingSingle) oldRoute.OtherEnd(this).ResetHighlight(this); } if (newRoute != null) { newRoute.Colour = _globalHighlightColour; if (GlobalHighlightingSingle) { _highlightState = HighlghtState.HighlightingSingle; newRoute.OtherEnd(this).Highlight(this); } } else _highlightState = HighlghtState.NotHighlighting; _highlightedLink = newRoute; }
/// <summary> /// Finds the shortest route to a target. /// /// To start with can be in one of two states: /// A: No route known /// B: There is a route known /// /// Can finish in one of four states /// 1. There was no route originally and one has been found /// 2. There is a new, shorter route along a different link /// 3. The target can no longer be reached but used to be reachable /// 4. The original route is still shortest but is now a different length /// 5. The original route is no longer available but a new route was found /// 6. The original route is still shortest and has not changed /// 7. The target was not reachable before and is still not reachable /// /// 1 = Update distance vector, broadcast update, trigger routing table changed event /// 2 = Update distance vector, broadcast update, trigger routing table changed event /// 3 = Update distance vector, broadcast update, trigger routing table changed event /// 4 = Update distance vector, broadcast update, trigger routing table changed event /// 5 = Update distance vector, broadcast update, trigger routing table changed event /// 6 = No events triggered /// 7 = No events triggered /// </summary> /// <param name="targetNode"></param> /// <returns></returns> private bool findShortestPath(IMNodeInternal targetNode, List <string> changes) { UUID target = targetNode.ID; //oldDist == null indicates initial state A, otherwise initial state B. Distance oldDist; lock (distanceVector) oldDist = distanceVector.ContainsKey(target) ? distanceVector[target].copy() : null; IKeyTable <DistanceVector> tmpNeighbours = neighbourVectors.Copy(); IMLink link = null; float dist = float.MaxValue; if (oldDist != null && oldDist.Link.OtherEnd(ID).Equals(target) && Links.ContainsKey(target)) { //If there was an old route and target is a neighbour and the link was the link between them use the weight of that link as the starting weight link = Links[target]; dist = link.Weight; } else if (oldDist != null && tmpNeighbours.ContainsKey(oldDist.Hop.ID) && tmpNeighbours[oldDist.Hop.ID].ContainsKey(target) && tmpNeighbours[oldDist.Hop.ID][target].Dist > 0f) { //If there was an old route and it involved routing via a neighbour and that neighbour can still route then take the starting weight as the distance to the neighbour + the distance from the neighbour to the target link = Links[oldDist.Hop.ID]; dist = tmpNeighbours[oldDist.Hop.ID][target].Dist + link.Weight; } //Check every neighbour to see if the weight of the link to that neighbour + the distance the neighbour can achieve to the target is shorter . foreach (var neighbour in Neighbours) { var neighbourLink = Links[neighbour.ID]; var neighbourVector = tmpNeighbours.ContainsKey(neighbour.ID) && tmpNeighbours[neighbour.ID].ContainsKey(target) ? tmpNeighbours[neighbour.ID][target] : null; var neighbourDist = neighbourVector != null ? neighbourLink.Weight + neighbourVector.Dist : float.MaxValue; //Neighbour vector distance of 0 or less indicates poison reverse or a link to itself //Also checks to see if the link at the other end is the neighbour and whether the weight of the link is less than the current distance if ((neighbourVector != null && neighbourVector.Dist > 0 && neighbourDist < dist) || neighbour.Equals(targetNode) && neighbourLink.Weight < dist) { link = neighbourLink; dist = neighbour.Equals(targetNode) ? link.Weight : neighbourDist; } } if (link == null && oldDist == null) { //Case 5 + 6 return(false); } if (link != null && oldDist == null) { //1. There was no route originally and one has been found UpdateRoutes(targetNode, link.OtherEnd(Node), link, dist); changes.Add("Distance Vector added route to " + targetNode.Name + " via " + link.OtherEnd(Node).Name + " with distance " + Math.Round(dist, 2) + "."); } else if (link == null && oldDist != null) { //3. The target can no longer be reached but used to be reachable lock (distanceVector) { distanceVector.Remove(target); RemoveRoute(DV.DV_NAME, target); changes.Add("Distance Vector removed route to " + targetNode.Name + ". " + oldDist.Hop.Name + " is no longer a valid first hop and no other route was found."); } } else if (oldDist != null && !link.Equals(oldDist.Link)) { //2. There is a new, shorter route along a different link UpdateRoutes(targetNode, link.OtherEnd(Node), link, dist); changes.Add("Distance Vector changed route to " + targetNode.Name + " from " + oldDist.Hop.Name + " to " + link.OtherEnd(Node).Name + " with distance " + Math.Round(dist, 2) + "."); } else if (oldDist != null && link.Equals(oldDist.Link) && dist != oldDist.Dist) { //4. The original route is still shortest but is now a different length UpdateRoutes(targetNode, link.OtherEnd(Node), link, dist); changes.Add("Distance Vector changed weight of route to " + targetNode.Name + " from " + Math.Round(oldDist.Dist, 2) + " to " + Math.Round(dist, 2) + "."); } else { return(false); } return(true); }