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;
        }
Beispiel #2
0
 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;
        }
Beispiel #4
0
        /// <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);
        }