Пример #1
0
        /// <summary>
        /// Once the algorithm has finished use the information it has stored to update the routing table.
        /// </summary>
        private void UpdateRoutingTable()
        {
            IKeyTable <IMLink> oldTable = ForwardingTable;

            foreach (DijkstraNode target in _confirmed)
            {
                if (target.ID != ID)
                {
                    //Work backwards along the route, starting at the target, until the first hop is found
                    DijkstraNode prev = target;
                    while (prev != null && !Equals(prev.GetPrev(ID)))
                    {
                        prev = prev.GetPrev(ID);
                    }

                    if (prev != null && Links.ContainsKey(prev.ID))
                    {
                        IMLink l = Links[prev.ID];
                        SetRoute(Algorithm, target.ID, l, target.GetDistanceFromRoot(ID));
                        oldTable.Remove(target.ID);
                    }
                }
            }
            //Trigger events for any nodes that can no longer be routed to
            foreach (IMNodeInternal n in KnownNodes)
            {
                if (oldTable.ContainsKey(n.ID))
                {
                    RemoveRoute(Algorithm, n.ID);
                }
            }
        }
Пример #2
0
        /// <inhertidoc />
        public void AddLink(IMLink link, Parameters parameters)
        {
            IMNode neighbour = link.OtherEnd(this);

            //Add the link referenced by both its own UUID and the ID of the neighbour it connects to
            lock (_links) {
                if (!_links.ContainsKey(neighbour.ID))
                {
                    _links.Add(neighbour.ID, link);
                }
                if (!_links.ContainsKey(link.ID))
                {
                    _links.Add(link.ID, link);
                }
            }
            lock (_neighbours)
                if (!_neighbours.ContainsKey(link.ID))
                {
                    _neighbours.Add(link.ID, neighbour);
                }

            link.OnWeightChanged += _weightDelegate;

            if (OnLinkAdded != null)
            {
                OnLinkAdded(ID, link, parameters);
                Logger.Debug(Name + " triggered OnLinkAdded for '" + link.Name + "'.");
            }
        }
Пример #3
0
        /// <inhertidoc />
        public void TriggerHighlight(string alg, IMNodeInternal target)
        {
            if (Equals(_globalHighlightTarget) || Equals(_globalHighlightRoot))
            {
                TriggerHighlightReset();
                return;
            }

            ClearOld();

            _globalTargetKey       = target.ID;
            _globalHighlightTarget = (IMNode)target;
            _globalHighlightRoot   = this;
            _globalHighlightColour = Colour;
            _globalHighlightState  = HighlghtState.HighlightingSingle;
            _highlightState        = HighlghtState.HighlightingSingle;

            //If there is a route
            if (ForwardingTable.ContainsKey(_globalTargetKey))
            {
                lock (HighlightLock) {
                    _highlightedLink        = ForwardingTable[_globalTargetKey];
                    _highlightedLink.Colour = _globalHighlightColour;
                    IMNode node = ForwardingTable[_globalTargetKey].OtherEnd(this);
                    node.Highlight(this);
                }
            }
            else
            {
                _highlightedLink = null;
            }
        }
Пример #4
0
        /// <summary>
        ///   What to do when a packet relevant to the highlight flooding algorithm is received
        ///
        ///   If the node has not already received one of the highlight flooding packets flood highlight packets along all links and send a new
        ///   highlight all packet back towards the source of the received packet
        /// </summary>
        /// <param name = "packet"></param>
        public void HighlightAll(IMNodeInternal hop)
        {
            if (HighlightingAll)
            {
                return;
            }

            lock (HighlightLock) {
                _highlightedLink = ForwardingTable.ContainsKey(_globalTargetKey) ? ForwardingTable[_globalTargetKey] : null;
                _highlightState  = HighlghtState.HighlightingAll;

                if (_highlightedLink != null)
                {
                    _highlightedLink.Colour = _globalHighlightColour;
                }

                foreach (IMLink l in _links)
                {
                    IMNode neighbour = l.OtherEnd(this);
                    if (!neighbour.Equals(hop))
                    {
                        neighbour.HighlightAll(this);
                    }
                }
            }
        }
Пример #5
0
        private void BroadcastUpdate(int TTL, string msg, bool visualise)
        {
            if (ShouldPrint(visualise))
            {
                Logger.Info(Name + " DV broadcasting update after '" + msg + "'.");
            }
            if (Model.IsPaused && IsCurrentAlgorithm && visualise)
            {
                Say("Broadcasting update after " + msg + ".");
            }
            foreach (IMNode n in Neighbours)
            {
                IMLink l = Links[n.ID];
                //Poisoned reverse, don't pass back routes which route via the destination node
                var v = new DistanceVector();
                lock (distanceVector) {
                    foreach (Distance d in distanceVector)
                    {
                        if (!_poison || !d.Link.Equals(l)) //No Poison reverse
                        {
                            v.Add(d.Target.ID, new Distance(d.Target, d.Hop, d.Link, d.Dist));
                        }
                        else //Poison reverse
                        {
                            v.Add(d.Target.ID, new Distance(d.Target, d.Hop, d.Link, -1f));
                        }
                    }
                }

                v.Add(ID, new Distance(Node, Node, l, 0f));
                _forwardMethod(ID, l.ID, new DVPacket(Node, n, v, visualise, TTL));
            }
        }
Пример #6
0
        public void ResetHighlightAll()
        {
            _highlightState = HighlghtState.NotHighlighting;

            if (_highlightedLink != null)
            {
                _highlightedLink.Reset();
                _highlightedLink = null;
            }
        }
Пример #7
0
 protected override void LinkAdded(IMLink link, Parameters parameters, bool visualise)
 {
     findShortestPaths(TTL, "'" + link.Name + "' added", visualise);
     //If there was a packet which was received from the other end of the link that was added before
     //the link had been added process it.
     if (_unknownPacket != null && _unknownPacket.S.Equals(link.OtherEnd(ID)))
     {
         ProcessPacket(_unknownPacket);
         _unknownPacket = null;
     }
 }
Пример #8
0
        /// <Inheritdoc />
        public void Send(IMNodeExternal destination, Parameters parameters)
        {
            if (!ForwardingTable.ContainsKey(destination.ID))
            {
                Say("Unable to forward packet to " + destination.Name);
                return;
            }

            IMLink link = ForwardingTable[destination.ID];

            SendPacket(ID, link.ID, new MPacket(this, destination, this, parameters));
        }
Пример #9
0
 /// <summary>
 ///   Used to specify that the route to a target node is along the specified AddLink
 /// </summary>
 /// <param name = "target">The node to map a route to</param>
 /// <param name = "link">The AddLink along which to pass packets intended for target node</param>
 public void SetWIPRoute(UUID target, IMLink link)
 {
     lock (_wipRoute) {
         if (_wipRoute.ContainsKey(target))
         {
             _wipRoute[target] = link;
         }
         else
         {
             _wipRoute.Add(target, link);
         }
     }
 }
Пример #10
0
 protected void RemoveRoute(string alg, UUID target)
 {
     if (_table.ContainsKey(target))
     {
         IMLink oldLink = _table[target];
         float  oldDist = _distances[target];
         _table.Remove(target);
         _distances.Remove(target);
         if (OnRouteChange != null && IsCurrentAlgorithm)
         {
             OnRouteChange(alg, KnownNodes[target], oldLink, null, oldDist, -1f);
         }
     }
 }
Пример #11
0
 /// <summary>
 /// The main loop which is the body of the algorithm.
 /// Loops through every neighbour of the current node checking to see if they:
 /// A. Have been visited before
 /// B. Have been visited before but are now a shorter route
 /// </summary>
 /// <param name="current">The node currently being checked.</param>
 /// <param name="prev">The previous node that was checked.</param>
 /// <returns>The last node to be checked.</returns>
 private void MainLoop(DijkstraNode current, DijkstraNode prev)
 {
     while (_cont && current != null && !hitTarget(current))
     {
         //If necessary display text and wait
         if (_cont && _text && _visualise)
         {
             current.Say("4. Iterating through neighbours excluding neighbours in Confirmed");
             Pause();
         }
         //Get the current distance to the target
         float dist = current.GetDistanceFromRoot(ID);
         foreach (var n in current.Neighbours)
         {
             IMLink link = current.Links[n.ID];
             if (_visualise)
             {
                 _links.AddFirst(link);
             }
             var neighbour = this.GetAlgNode <DijkstraNode>(n.ID);
             if (_cont && !_confirmed.Contains(neighbour))
             {
                 if (_visualise && _text)
                 {
                     VisualiseCheckNeighbourText(neighbour, current, dist, link);
                 }
                 else if (_visualise)
                 {
                     VisualiseCheckNeighbour(neighbour, current, dist, link);
                 }
                 checkNeighbour(neighbour, current, dist, link);
             }
             if (!_cont)
             {
                 break;
             }
         }
         //Store the old previous node
         prev = current;
         if (_cont && _text && _visualise)
         {
             Say("Finished iterating through current's (" + current.Name +
                 "'s) neighbours, getting next current from tentative list");
             Pause();
         }
         //Get the next node to be checked (the one which has the shortest path to it)
         current = getNext(current);
     }
     FinishedReset(current, prev);
 }
Пример #12
0
        /// <summary>
        /// Visualise the process of choosing the next node. Will output text about what is going on if necessary.
        /// </summary>
        /// <param name="next">The next node to be current.</param>
        /// <param name="prev">The node that was previously current.</param>
        private void VisualiseChooseNext(DijkstraNode next, DijkstraNode prev)
        {
            if (_cont && !next.Equals(this))
            {
                if (_cont && _text)
                {
                    Say("8. There are nodes in the tentative list. Finding the node in tentative with the smallest cost");
                    Pause();
                }
                Pause(3f);
                if (_cont && _text)
                {
                    Say("9. new current = " + next.Name + " with cost " + next.GetDistanceFromRoot(ID));
                    Pause();
                    Say("10. Adding link between ct (" + prev.Name + ") and new current (" + next.Name + ") to the shortest path");
                    Pause();
                }
            }

            prev.Reset();

            IMLink confirmedLink = next.GetWIPRoute(ID);

            if (_cont && confirmedLink != null)
            {
                Pause(6f);
                confirmedLink.Colour = Color.Red;
            }

            if (_cont && _text)
            {
                Say((next.Equals(this) ? "2a" : "11a") + ". Adding " +
                    (next.Equals(this) ? "root" : "new current") + " (" + next.Name + ") to Confirmed");
                Pause();
                Say((next.Equals(this) ? "2b" : "11b") + ". Setting current to " +
                    (next.Equals(this) ? "root" : "new current") + " (" + next.Name + ")");
            }

            next.Reset();
            next.Selected = currentGlow;
            next.Colour   = Color.White;

            if (_cont && _text && !next.Equals(this))
            {
                Pause();
                Say("11c. Going to step 4");
                Pause();
            }
        }
Пример #13
0
 /// <summary>
 /// Broadcasts update packets. Iterates through neighbour and as long as the source of the update was not the neighbour sends a flood packet to that neighbour.
 /// </summary>
 /// <param name="receivedAlong"></param>
 /// <param name="msg"></param>
 /// <param name="evt"></param>
 /// <param name="visualisePackets"></param>
 private void BroadcastUpdate(UUID receivedAlong, string msg, int evt, bool visualisePackets)
 {
     if (Model.IsPaused && IsCurrentAlgorithm && visualisePackets)
     {
         Say("Broadcasting update after " + msg + ".");
     }
     foreach (IMNode neighbour in Neighbours)
     {
         IMLink link = Links[neighbour.ID];
         if (link != null && (!neighbour.ID.Equals(receivedAlong) || !link.IsBidirectional))
         {
             _forwardMethod(ID, link.ID, new LinkStatePacket(Node, Node, neighbour, evt, visualisePackets));
         }
     }
 }
Пример #14
0
        public Distance(IMNodeInternal target, IMNodeInternal hop, IMLink link, float distance)
        {
            if (target == null)
                throw new Exception("Target node must be set when initialising distance to target");
            if (hop == null)
                throw new Exception("First hop must be set when initialising distance to target");
            if (link == null)
                throw new Exception("First hop link must be set when initialising distance to target");
            //if (distance <= 0)
            //    throw new AlgorithmException("Distance must be positive when initialising distance to target");

            this.target = target;
            this.hop = hop;
            this.link = link;
            this.distance = distance;
        }
Пример #15
0
        internal void update(IMNodeInternal hop, IMLink link, float dist)
        {
            if (hop == null)
            {
                throw new Exception("First hop must be set when updating distance to target");
            }
            if (link == null)
            {
                throw new Exception("First hop link must be set when updating distance to target");
            }
            //if (distance <= 0)
            //    throw new AlgorithmException("Distance must be positive when updating distance to target");

            this.hop  = hop;
            this.link = link;
            update(dist);
        }
Пример #16
0
 private void UpdateRoutes(IMNodeInternal target, IMNodeInternal hop, IMLink link, float dist)
 {
     if (target.ID.Equals(ID))
     {
         return;
     }
     SetRoute(DV.DV_NAME, target.ID, link, dist);
     lock (distanceVector)
         if (!distanceVector.ContainsKey(target.ID))
         {
             distanceVector.Add(target.ID, new Distance(target, hop, link, dist));
         }
         else
         {
             distanceVector[target.ID].update(hop, link, dist);
         }
 }
Пример #17
0
        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;
        }
Пример #18
0
        /// <summary>
        ///   What to do when notified that it should highlight
        ///
        ///   Will highlight the link and forward the packet on if necessary
        /// </summary>
        /// <param name = "packet">The packet received</param>
        public void Highlight(IMNodeInternal hop)
        {
            _highlightedLink = ForwardingTable.ContainsKey(_globalTargetKey) ? ForwardingTable[_globalTargetKey] : null;

            if (HighlightingSingle ||
                (_highlightedLink != null && _highlightedLink.OtherEnd(this).Equals(hop)))
            {
                return;
            }

            lock (HighlightLock) {
                _highlightState = HighlghtState.HighlightingSingle;

                if (_highlightedLink != null)
                {
                    _highlightedLink.Colour = _globalHighlightColour;
                    _highlightedLink.OtherEnd(this).Highlight(this);
                }
            }
        }
Пример #19
0
        public void ResetHighlight(IMNodeInternal hop)
        {
            if (Equals(_globalHighlightTarget) ||
                !Highlighting ||
                (_highlightedLink != null && _highlightedLink.OtherEnd(this).Equals(hop)))
            {
                return;
            }

            lock (HighlightLock) {
                _highlightState = HighlghtState.NotHighlighting;

                if (_highlightedLink != null)
                {
                    _highlightedLink.Reset();
                    _highlightedLink.OtherEnd(this).ResetHighlight(this);
                    _highlightedLink = null;
                }
            }
        }
Пример #20
0
        public Distance(IMNodeInternal target, IMNodeInternal hop, IMLink link, float distance)
        {
            if (target == null)
            {
                throw new Exception("Target node must be set when initialising distance to target");
            }
            if (hop == null)
            {
                throw new Exception("First hop must be set when initialising distance to target");
            }
            if (link == null)
            {
                throw new Exception("First hop link must be set when initialising distance to target");
            }
            //if (distance <= 0)
            //    throw new AlgorithmException("Distance must be positive when initialising distance to target");

            this.target   = target;
            this.hop      = hop;
            this.link     = link;
            this.distance = distance;
        }
Пример #21
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);
         }
     }
 }
Пример #22
0
        /// <inhertidoc />
        public void RemoveLink(UUID l, Parameters parameters)
        {
            if (!Neighbours.ContainsKey(l))
            {
                throw new Exception("The link to be remove is not a known link.");
            }

            IMNodeInternal neighbour = _neighbours[l];
            IMLink         link      = _links[neighbour.ID];

            link.OnWeightChanged -= _weightDelegate;

            lock (_links) {
                _links.Remove(neighbour.ID);
                _links.Remove(l);
            } lock (_neighbours)
                _neighbours.Remove(link.ID);

            if (OnLinkRemoved != null && !parameters.Get <bool>("Clearing"))
            {
                OnLinkRemoved(ID, link, parameters);
                Logger.Debug(Name + " triggered OnLinkRemoved for '" + link.Name + "'.");
            }
        }
Пример #23
0
        public void ResetHighlight(IMNodeInternal hop)
        {
            if (Equals(_globalHighlightTarget) ||
                !Highlighting ||
                (_highlightedLink != null && _highlightedLink.OtherEnd(this).Equals(hop)))
                return;

            lock (HighlightLock) {
                _highlightState = HighlghtState.NotHighlighting;

                if (_highlightedLink != null) {
                    _highlightedLink.Reset();
                    _highlightedLink.OtherEnd(this).ResetHighlight(this);
                    _highlightedLink = null;
                }
            }
        }
Пример #24
0
 public Distance(Distance distance, IMNodeInternal hop, IMLink link, float hopWeight)
     : this(distance.Target, hop, link, distance.Dist + hopWeight)
 {
 }
Пример #25
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);
        }
Пример #26
0
        /// <summary>
        /// Visualises the process of checking a neighbour node.
        /// </summary>
        /// <param name="neighbour">The neighbour to check.</param>
        /// <param name="current">The current node.</param>
        /// <param name="dist">The distance from the root to the current node.</param>
        /// <param name="link">The link between current and neighbour.</param>
        private void VisualiseCheckNeighbour(DijkstraNode neighbour, DijkstraNode current, float dist, IMLink link)
        {
            if (!_visualise)
                return;

            if (_cont) {
                Pause(4f);
                link.Colour = Color.Blue;
                Pause(6);
            }

            try {
                if (_cont && !_tentative.Contains(neighbour)) {
                    neighbour.Selected = tentativeGlow;
                    Pause(6);
                }
            } catch (KeyNotFoundException e) {
                //If the AddLink being checked is no Keyer in the list of links the algorithm needs to stop
                _cont = false;
                if (_visualise)
                    VisualisedNode = null;
                Logger.Debug("Trying to work with a neighbour (" + neighbour.Name + ") which is not actually connected to " +
                         current.Name + " (root = " + Name + ")");
            }

            if (_cont)
                link.Colour = Color.White;
        }
Пример #27
0
 protected override void WeightChanged(IMLink link, bool visualise)
 {
     OnChange("Link to '" + link.Name + "' changed weight to " + link.Weight, link.ID, Node.Parameters, visualise);
 }
Пример #28
0
        internal void SetDistanceFromRoot(UUID root, float value, DijkstraNode prevNode, IMLink link)
        {
            //if (prevNode != null/* && !Links.ContainsKey(prevNode.ID)*/)
            //    return;

            lock (_distances) {
                if (_distances.ContainsKey(root)) {
                    _distances[root] = value;
                    _prev[root] = prevNode;
                } else {
                    _distances.Add(root, value);
                    _prev.Add(root, prevNode);
                }
            }
            if (prevNode != null)
                SetWIPRoute(root, link);
        }
Пример #29
0
        /// <summary>
        ///   What to do when notified that it should highlight
        /// 
        ///   Will highlight the link and forward the packet on if necessary
        /// </summary>
        /// <param name = "packet">The packet received</param>
        public void Highlight(IMNodeInternal hop)
        {
            _highlightedLink = ForwardingTable.ContainsKey(_globalTargetKey) ? ForwardingTable[_globalTargetKey] : null;

            if (HighlightingSingle ||
                (_highlightedLink != null && _highlightedLink.OtherEnd(this).Equals(hop)))
                return;

            lock (HighlightLock) {
                _highlightState = HighlghtState.HighlightingSingle;

                if (_highlightedLink != null) {
                    _highlightedLink.Colour = _globalHighlightColour;
                    _highlightedLink.OtherEnd(this).Highlight(this);
                }
            }
        }
Пример #30
0
 private void UpdateRoutes(IMNodeInternal target, IMNodeInternal hop, IMLink link, float dist)
 {
     if (target.ID.Equals(ID))
         return;
     SetRoute(DV.DV_NAME, target.ID, link, dist);
     lock (distanceVector)
         if (!distanceVector.ContainsKey(target.ID))
             distanceVector.Add(target.ID, new Distance(target, hop, link, dist));
         else
             distanceVector[target.ID].update(hop, link, dist);
 }
Пример #31
0
        internal void SetDistanceFromRoot(UUID root, float value, DijkstraNode prevNode, IMLink link)
        {
            //if (prevNode != null/* && !Links.ContainsKey(prevNode.ID)*/)
            //    return;

            lock (_distances) {
                if (_distances.ContainsKey(root))
                {
                    _distances[root] = value;
                    _prev[root]      = prevNode;
                }
                else
                {
                    _distances.Add(root, value);
                    _prev.Add(root, prevNode);
                }
            }
            if (prevNode != null)
            {
                SetWIPRoute(root, link);
            }
        }
Пример #32
0
 protected override void WeightChanged(IMLink link, bool visualise)
 {
     OnChange("Link to '" + link.Name + "' changed weight to " + link.Weight, link.ID, Node.Parameters, visualise);
 }
Пример #33
0
 protected override void LinkRemoved(IMLink link, Parameters parameters, bool visualise)
 {
     OnChange("Link to '" + link.OtherEnd(Node).Name + "' removed", link.ID, parameters, visualise);
 }
Пример #34
0
 /// <summary>
 ///   Used to specify that the route to a target node is along the specified AddLink
 /// </summary>
 /// <param name = "target">The node to map a route to</param>
 /// <param name = "link">The AddLink along which to pass packets intended for target node</param>
 public void SetWIPRoute(UUID target, IMLink link)
 {
     lock (_wipRoute) {
         if (_wipRoute.ContainsKey(target))
             _wipRoute[target] = link;
         else
             _wipRoute.Add(target, link);
     }
 }
Пример #35
0
        /// <inhertidoc />
        public void TriggerHighlight(string alg, IMNodeInternal target)
        {
            if (Equals(_globalHighlightTarget) || Equals(_globalHighlightRoot)) {
                TriggerHighlightReset();
                return;
            }

            ClearOld();

            _globalTargetKey = target.ID;
            _globalHighlightTarget = (IMNode)target;
            _globalHighlightRoot = this;
            _globalHighlightColour = Colour;
            _globalHighlightState = HighlghtState.HighlightingSingle;
            _highlightState = HighlghtState.HighlightingSingle;

            //If there is a route
            if (ForwardingTable.ContainsKey(_globalTargetKey)) {
                lock (HighlightLock) {
                    _highlightedLink = ForwardingTable[_globalTargetKey];
                    _highlightedLink.Colour = _globalHighlightColour;
                    IMNode node = ForwardingTable[_globalTargetKey].OtherEnd(this);
                    node.Highlight(this);
                }
            } else
                _highlightedLink = null;
        }
Пример #36
0
 protected override void LinkRemoved(IMLink link, Parameters parameters, bool visualise)
 {
     OnChange("Link to '" + link.OtherEnd(Node).Name + "' removed", link.ID, parameters, visualise);
 }
Пример #37
0
        internal void update(IMNodeInternal hop, IMLink link, float dist)
        {
            if (hop == null)
                throw new Exception("First hop must be set when updating distance to target");
            if (link == null)
                throw new Exception("First hop link must be set when updating distance to target");
            //if (distance <= 0)
            //    throw new AlgorithmException("Distance must be positive when updating distance to target");

            this.hop = hop;
            this.link = link;
            update(dist);
        }
Пример #38
0
        /// <summary>
        /// Check a neighbour of the current node to see if it needs to be added to the tentative list
        /// or the shortest route to it needs to be updated.
        /// </summary>
        /// <param name="neighbour">The neighbour to check.</param>
        /// <param name="current">The current node.</param>
        /// <param name="dist">The distance from the root to the current node.</param>
        /// <param name="link">The link between current and neighbour.</param>
        private void checkNeighbour(DijkstraNode neighbour, DijkstraNode current, float dist, IMLink link)
        {
            float newDistance = dist + link.Weight;

            try {
                //If the new route from root to neighbour is shorter than the old route or there was no old route
                //set the current node as the first step towards the root from neighbour
                if (_cont && !_tentative.Contains(neighbour)) {
                    _tentative.AddFirst(neighbour);
                    neighbour.SetDistanceFromRoot(ID, newDistance, current, link);
                } else if (_cont && newDistance <= neighbour.GetDistanceFromRoot(ID))
                    neighbour.SetDistanceFromRoot(ID, newDistance, current, link);
            } catch (KeyNotFoundException e) {
                //If the AddLink being checked is no Keyer in the list of links the algorithm needs to stop
                _cont = false;
                if (_visualise)
                    VisualisedNode = null;
                Logger.Debug("Trying to work with a neighbour (" + neighbour.Name + ") which is not actually connected to " +
                         current.Name + " (root = " + Name + ")");
            }

            //Incase another thread has modified the distance
            if (_cont && newDistance < neighbour.GetDistanceFromRoot(ID))
                neighbour.SetDistanceFromRoot(ID, newDistance, neighbour, link);
        }
Пример #39
0
 protected override void WeightChanged(IMLink link, bool visualise)
 {
     findShortestPaths(TTL, "'" + link.Name + "' weight changed to " + link.Weight, visualise);
 }
Пример #40
0
        /// <summary>
        /// Visualises the process of checking a neighbour node and prints out text explaining what is happening.
        /// </summary>
        /// <param name="neighbour">The neighbour to check.</param>
        /// <param name="current">The current node.</param>
        /// <param name="dist">The distance from the root to the current node.</param>
        /// <param name="link">The link between current and neighbour.</param>
        private void VisualiseCheckNeighbourText(DijkstraNode neighbour, DijkstraNode current, float dist, IMLink link)
        {
            if (!_visualise && !_text)
                return;

            float newDistance = dist + link.Weight;

            if (_cont) {
                //if (_cont && _text)
                //    current.Say("Examining neighbour " + neighbour.Name);
                Pause(4f);
                link.Colour = Color.Blue;
                if (_cont && _text) {
                    Pause();
                    current.Say("5. Test cost to " + neighbour.Name + " = " + dist + " + " + link.Weight + " = " +
                                  newDistance);
                    Pause();
                }
                Pause(4f);
            }

            try {
                if (_cont && !_tentative.Contains(neighbour)) {
                    if (_cont && _text)
                        current.Say(neighbour.Name + " is not in tentative list");

                    _tentative.AddFirst(neighbour);
                    neighbour.SetDistanceFromRoot(ID, newDistance, current, link);

                    if (_cont) {
                        Pause(4f);
                        neighbour.Selected = tentativeGlow;
                        if (_cont && _text) {
                            current.Say("6a. Adding " + neighbour.Name + " to the tentative list");
                            Pause();
                            current.Say("6b. " + neighbour.Name + ".cost = test cost (" + newDistance + ")");
                        }
                    }
                }
                    //If the new route from root to neighbour is shorter than the old route or there was no old route
                    //set the current node as the first step towards the root from neighbour
                else if (_cont && newDistance <= neighbour.GetDistanceFromRoot(ID)) {
                    neighbour.SetDistanceFromRoot(ID, newDistance, current, link);

                    if (_cont && _text) {
                        current.Say(neighbour.Name + ".cost (" + neighbour.GetDistanceFromRoot(ID) + ") > test cost (" +
                                      newDistance + ")");
                        Pause();
                        current.Say("7. " + neighbour.Name + ".cost = test cost (" + newDistance + ")");
                        Pause();
                    }
                }
            } catch (KeyNotFoundException e) {
                //If the AddLink being checked is no Keyer in the list of links the algorithm needs to stop
                _cont = false;
                if (_visualise)
                    VisualisedNode = null;
                Logger.Debug("Trying to work with a neighbour (" + neighbour.Name + ") which is not actually connected to " +
                         current.Name + " (root = " + Name + ")");
            }

            if (_cont && newDistance < neighbour.GetDistanceFromRoot(ID))
                neighbour.SetDistanceFromRoot(ID, newDistance, neighbour, link);

            if (_cont) {
                Pause(4f);
                link.Colour = Color.White;
                Pause(6f);
            }
        }
Пример #41
0
 protected override void LinkRemoved(IMLink link, Parameters parameters, bool visualise)
 {
     lock (neighbourVectors)
         neighbourVectors.Remove(link.OtherEnd(ID));
     findShortestPaths(TTL, "'" + link.Name + "' removed", visualise);
 }
Пример #42
0
 public Distance(Distance distance, IMNodeInternal hop, IMLink link, float hopWeight)
     : this(distance.Target, hop, link, distance.Dist + hopWeight)
 {
 }
Пример #43
0
 protected override void LinkAdded(IMLink link, Parameters parameters, bool visualise)
 {
     findShortestPaths(TTL, "'" + link.Name + "' added", visualise);
     //If there was a packet which was received from the other end of the link that was added before
     //the link had been added process it.
     if (_unknownPacket != null && _unknownPacket.S.Equals(link.OtherEnd(ID))) {
         ProcessPacket(_unknownPacket);
         _unknownPacket = null;
     }
 }
Пример #44
0
        /// <inhertidoc />
        public void AddLink(IMLink link, Parameters parameters)
        {
            IMNode neighbour = link.OtherEnd(this);

            //Add the link referenced by both its own UUID and the ID of the neighbour it connects to
            lock (_links) {
                if (!_links.ContainsKey(neighbour.ID))
                    _links.Add(neighbour.ID, link);
                if (!_links.ContainsKey(link.ID))
                    _links.Add(link.ID, link);
            }
            lock (_neighbours)
                if (!_neighbours.ContainsKey(link.ID))
                    _neighbours.Add(link.ID, neighbour);

            link.OnWeightChanged += _weightDelegate;

            if (OnLinkAdded != null) {
                OnLinkAdded(ID, link, parameters);
                Logger.Debug(Name + " triggered OnLinkAdded for '" + link.Name + "'.");
            }
        }
Пример #45
0
        private void PrintDistanceVector(string msg)
        {
            string spacer   = "|";
            String infinity = "-1";
            int    colWidth = NAME_WIDTH + spacer.Length + 1;

            //Column header
            msg  = "\n" + Name + " (DV): " + msg;
            msg += "\n";
            for (int i = 0; i < NAME_WIDTH; i++)
            {
                msg += "#";
            }
            msg += spacer + " ";
            msg += getCol(Name, colWidth);
            lock (distanceVector)
                foreach (Distance d in distanceVector)
                {
                    msg += getCol(d.Target.Name, colWidth);
                }

            //Divider
            msg += "\n";
            for (int i = 0; i < colWidth * (distanceVector.Count + 2); i++)
            {
                msg += "_";
            }

            //Row for this node
            msg += "\n" + getCol(Name, NAME_WIDTH) + spacer + " ";
            msg += getCol("0", colWidth);
            lock (distanceVector)
                foreach (Distance d in distanceVector)
                {
                    msg += getCol(d.Dist + "", colWidth);
                }

            //Row for neighbour vectors
            foreach (IMNodeInternal neighbour in Neighbours)
            {
                IMLink l = Links[neighbour.ID];
                UUID   y = neighbour.ID;
                if (!neighbourVectors.ContainsKey(y))
                {
                    continue;
                }
                msg += "\n" + getCol(neighbour.Name, NAME_WIDTH) + spacer + " ";
                msg += getNeighbourCol(ID, y, colWidth, infinity);

                lock (distanceVector)
                    foreach (Distance d in distanceVector)
                    {
                        var x = d.Target;
                        if (neighbourVectors[y].ContainsKey(x.ID))
                        {
                            msg += getNeighbourCol(x.ID, y, colWidth, infinity);
                        }
                        else
                        {
                            msg += getCol("", NAME_WIDTH) + spacer + " ";
                        }
                    }
            }

            //Logger.Debug(msg + "\n");
            Console.WriteLine(msg);
        }
Пример #46
0
        /// <summary>
        ///   What to do when a packet relevant to the highlight flooding algorithm is received
        /// 
        ///   If the node has not already received one of the highlight flooding packets flood highlight packets along all links and send a new
        ///   highlight all packet back towards the source of the received packet
        /// </summary>
        /// <param name = "packet"></param>
        public void HighlightAll(IMNodeInternal hop)
        {
            if (HighlightingAll) return;

            lock (HighlightLock) {
                _highlightedLink = ForwardingTable.ContainsKey(_globalTargetKey) ? ForwardingTable[_globalTargetKey] : null;
                _highlightState = HighlghtState.HighlightingAll;

                if (_highlightedLink != null)
                    _highlightedLink.Colour = _globalHighlightColour;

                foreach (IMLink l in _links) {
                    IMNode neighbour = l.OtherEnd(this);
                    if (!neighbour.Equals(hop))
                        neighbour.HighlightAll(this);
                }
            }
        }
Пример #47
0
        /// <summary>
        /// Check a neighbour of the current node to see if it needs to be added to the tentative list
        /// or the shortest route to it needs to be updated.
        /// </summary>
        /// <param name="neighbour">The neighbour to check.</param>
        /// <param name="current">The current node.</param>
        /// <param name="dist">The distance from the root to the current node.</param>
        /// <param name="link">The link between current and neighbour.</param>
        private void checkNeighbour(DijkstraNode neighbour, DijkstraNode current, float dist, IMLink link)
        {
            float newDistance = dist + link.Weight;

            try {
                //If the new route from root to neighbour is shorter than the old route or there was no old route
                //set the current node as the first step towards the root from neighbour
                if (_cont && !_tentative.Contains(neighbour))
                {
                    _tentative.AddFirst(neighbour);
                    neighbour.SetDistanceFromRoot(ID, newDistance, current, link);
                }
                else if (_cont && newDistance <= neighbour.GetDistanceFromRoot(ID))
                {
                    neighbour.SetDistanceFromRoot(ID, newDistance, current, link);
                }
            } catch (KeyNotFoundException e) {
                //If the AddLink being checked is no Keyer in the list of links the algorithm needs to stop
                _cont = false;
                if (_visualise)
                {
                    VisualisedNode = null;
                }
                Logger.Debug("Trying to work with a neighbour (" + neighbour.Name + ") which is not actually connected to " +
                             current.Name + " (root = " + Name + ")");
            }

            //Incase another thread has modified the distance
            if (_cont && newDistance < neighbour.GetDistanceFromRoot(ID))
            {
                neighbour.SetDistanceFromRoot(ID, newDistance, neighbour, link);
            }
        }
Пример #48
0
        public void ResetHighlightAll()
        {
            _highlightState = HighlghtState.NotHighlighting;

            if (_highlightedLink != null) {
                _highlightedLink.Reset();
                _highlightedLink = null;
            }
        }
Пример #49
0
        /// <summary>
        /// Visualises the process of checking a neighbour node.
        /// </summary>
        /// <param name="neighbour">The neighbour to check.</param>
        /// <param name="current">The current node.</param>
        /// <param name="dist">The distance from the root to the current node.</param>
        /// <param name="link">The link between current and neighbour.</param>
        private void VisualiseCheckNeighbour(DijkstraNode neighbour, DijkstraNode current, float dist, IMLink link)
        {
            if (!_visualise)
            {
                return;
            }

            if (_cont)
            {
                Pause(4f);
                link.Colour = Color.Blue;
                Pause(6);
            }

            try {
                if (_cont && !_tentative.Contains(neighbour))
                {
                    neighbour.Selected = tentativeGlow;
                    Pause(6);
                }
            } catch (KeyNotFoundException e) {
                //If the AddLink being checked is no Keyer in the list of links the algorithm needs to stop
                _cont = false;
                if (_visualise)
                {
                    VisualisedNode = null;
                }
                Logger.Debug("Trying to work with a neighbour (" + neighbour.Name + ") which is not actually connected to " +
                             current.Name + " (root = " + Name + ")");
            }

            if (_cont)
            {
                link.Colour = Color.White;
            }
        }
Пример #50
0
        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;
        }
Пример #51
0
        /// <summary>
        /// Visualises the process of checking a neighbour node and prints out text explaining what is happening.
        /// </summary>
        /// <param name="neighbour">The neighbour to check.</param>
        /// <param name="current">The current node.</param>
        /// <param name="dist">The distance from the root to the current node.</param>
        /// <param name="link">The link between current and neighbour.</param>
        private void VisualiseCheckNeighbourText(DijkstraNode neighbour, DijkstraNode current, float dist, IMLink link)
        {
            if (!_visualise && !_text)
            {
                return;
            }

            float newDistance = dist + link.Weight;

            if (_cont)
            {
                //if (_cont && _text)
                //    current.Say("Examining neighbour " + neighbour.Name);
                Pause(4f);
                link.Colour = Color.Blue;
                if (_cont && _text)
                {
                    Pause();
                    current.Say("5. Test cost to " + neighbour.Name + " = " + dist + " + " + link.Weight + " = " +
                                newDistance);
                    Pause();
                }
                Pause(4f);
            }

            try {
                if (_cont && !_tentative.Contains(neighbour))
                {
                    if (_cont && _text)
                    {
                        current.Say(neighbour.Name + " is not in tentative list");
                    }

                    _tentative.AddFirst(neighbour);
                    neighbour.SetDistanceFromRoot(ID, newDistance, current, link);

                    if (_cont)
                    {
                        Pause(4f);
                        neighbour.Selected = tentativeGlow;
                        if (_cont && _text)
                        {
                            current.Say("6a. Adding " + neighbour.Name + " to the tentative list");
                            Pause();
                            current.Say("6b. " + neighbour.Name + ".cost = test cost (" + newDistance + ")");
                        }
                    }
                }
                //If the new route from root to neighbour is shorter than the old route or there was no old route
                //set the current node as the first step towards the root from neighbour
                else if (_cont && newDistance <= neighbour.GetDistanceFromRoot(ID))
                {
                    neighbour.SetDistanceFromRoot(ID, newDistance, current, link);

                    if (_cont && _text)
                    {
                        current.Say(neighbour.Name + ".cost (" + neighbour.GetDistanceFromRoot(ID) + ") > test cost (" +
                                    newDistance + ")");
                        Pause();
                        current.Say("7. " + neighbour.Name + ".cost = test cost (" + newDistance + ")");
                        Pause();
                    }
                }
            } catch (KeyNotFoundException e) {
                //If the AddLink being checked is no Keyer in the list of links the algorithm needs to stop
                _cont = false;
                if (_visualise)
                {
                    VisualisedNode = null;
                }
                Logger.Debug("Trying to work with a neighbour (" + neighbour.Name + ") which is not actually connected to " +
                             current.Name + " (root = " + Name + ")");
            }

            if (_cont && newDistance < neighbour.GetDistanceFromRoot(ID))
            {
                neighbour.SetDistanceFromRoot(ID, newDistance, neighbour, link);
            }

            if (_cont)
            {
                Pause(4f);
                link.Colour = Color.White;
                Pause(6f);
            }
        }