/// <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; } }
internal DVNode(IMNodeInternal node, ForwardDelegate forwardMethod, IAsynchQueue queue, IKeyTableFactory tableFactory, int TTL, IConfigSource config) : base(node, tableFactory, config) { _queue = queue; _forwardMethod = forwardMethod; this.TTL = TTL; distanceVector = new DistanceVector(); neighbourVectors = tableFactory.MakeKeyTable <DistanceVector>(); highlightParameters = new Parameters(new object[] { "HColour", node.Colour }); IConfig dvConfig = config.Configs["DV"]; if (dvConfig == null) { dvConfig = config.Configs["DistanceVector"]; } if (dvConfig == null) { dvConfig = config.Configs["Algorithm"]; } if (dvConfig == null) { dvConfig = config.Configs[0]; } _poison = dvConfig.GetBoolean("PoisonReverse", true); _everPrint = dvConfig.GetBoolean("EverPrint", false); _alwaysPrint = dvConfig.GetBoolean("AlwaysPrint", false); highlightPrintText = dvConfig.GetBoolean("HighlightPrint", false); }
/// <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); } } } }
public LinkStateNode(IMNodeInternal node, IKeyTableFactory tableFactory, IAsynchQueue dijkstraQ, IAsynchQueue packetQ, ForwardDelegate forwardMethod, IConfigSource config) : base(node, tableFactory, dijkstraQ, config) { _eventQ = packetQ; _forwardMethod = forwardMethod; _processedEvents = new HashSet <int>(); OnRouteChange += (alg, target, oldRoute, newRoute, oldDistance, distance) => { _changed = true; if (!Model.IsPaused) { return; } if (oldRoute != null && newRoute != null) { Say("Link State changed route to " + target.Name + " from " + oldRoute.OtherEnd(Node).Name + " to " + newRoute.OtherEnd(Node).Name + "."); } else if (oldRoute == null) { Say("Link State added route to " + target.Name + " via " + newRoute.OtherEnd(Node).Name + " with distance " + distance + "."); } else if (newRoute == null) { Say("Link State removed route to " + target.Name + ". " + oldRoute.OtherEnd(Node).Name + " is no longer a valid first hop and no other route was found."); } else { Say("Link State changed weight of route to " + target.Name + " from " + oldDistance + " to " + distance + "."); } }; }
internal DVNode(IMNodeInternal node, ForwardDelegate forwardMethod, IAsynchQueue queue, IKeyTableFactory tableFactory, int TTL, IConfigSource config) : base(node, tableFactory, config) { _queue = queue; _forwardMethod = forwardMethod; this.TTL = TTL; distanceVector = new DistanceVector(); neighbourVectors = tableFactory.MakeKeyTable<DistanceVector>(); highlightParameters = new Parameters(new object[] { "HColour", node.Colour }); IConfig dvConfig = config.Configs["DV"]; if (dvConfig == null) dvConfig = config.Configs["DistanceVector"]; if (dvConfig == null) dvConfig = config.Configs["Algorithm"]; if (dvConfig == null) dvConfig = config.Configs[0]; _poison = dvConfig.GetBoolean("PoisonReverse", true); _everPrint = dvConfig.GetBoolean("EverPrint", false); _alwaysPrint = dvConfig.GetBoolean("AlwaysPrint", false); highlightPrintText = dvConfig.GetBoolean("HighlightPrint", false); }
/// <summary> /// Initialise a Dijkstra's Packet /// </summary> /// <param name = "hop">The node this packet just came from as opposed to its original source</param> /// <param name = "from">The node the packet was sent from</param> /// <param name = "to">The node the packet is destined for</param> /// <param name = "evt">The AddLink along which the packet is currently travelling</param> /// <param name = "view">The view layer which is used to visualise the packet moving</param> /// <param name = "visualise">Whether the packet should be visualised</param> internal LinkStatePacket(IMNodeInternal hop, INode from, INode to, int evt, bool visualise) : base(from, to, hop, new Parameters(), LinkState.LINK_STATE_NAME, visualise) { _event = evt; Name = "Link IsOn " + Name; Selected = 1d; Parameters.Set <bool>("Visualise", visualise); }
public DVPacket(IMNodeInternal from, INode to, DistanceVector distanceVector, bool visualise = false, int TTL = 51) : base(from, to, from, new Parameters("Visualise", visualise), DV.DV_NAME, visualise) { _distanceVector = distanceVector; _highlighting = false; _ttl = TTL - 1; Name = "Distance Vector " + Name; Selected = 1d; }
public MPacket(INode source, INode destination, IMNodeInternal hop, Parameters parameters, string algorithm = null, bool visualise = true) : base("Packet from " + source.Name + " to " + destination.Name, source.Colour, 0d, parameters) { S = source.ID; D = destination.ID; Source = source; Destination = destination; Hop = hop; Type = algorithm == null ? PTypes.data : PTypes.Algorithm; Visualise = Type == PTypes.data || visualise; Algorithm = algorithm; }
private void VisualiseAlgorithm(IMNodeInternal target, Parameters parameters) { Logger.Debug("Distance vector visualising routing for " + Node.Name + "."); if (target == null) { Node.TriggerHighlightAll(DV.DV_NAME); } else { Node.TriggerHighlight(DV.DV_NAME, target); } }
/// <summary> /// Initialise the various variables, flags and collections that are used to run the algorithm. /// </summary> /// <param name="target">The target being routed to. Null means route to every target.</param> /// /// private void Init(IMNodeInternal target) { _target = _target != null && target == null ? _target : target; _confirmed.Clear(); _tentative.Clear(); _links.Clear(); _tentative.AddFirst(this); foreach (DijkstraNode n in this.GetAllNodes <DijkstraNode>()) { n.SetDistanceFromRoot(ID, float.MaxValue, null, null); } _cont = true; }
protected AbstractAlgorithmNode(IMNodeInternal node, IKeyTableFactory tableFactory, IConfigSource config) { AlgCollectionExtension._tableFactory = tableFactory; Logger = LogManager.GetLogger(GetType()); _node = node; _table = tableFactory.MakeKeyTable <IMLink>(); _distances = tableFactory.MakeKeyTable <float>(); this.RegisterAlgNode(); Node.OnWeightChange += (link, weight) => WeightChanged(Links[link], IsCurrentAlgorithm && Links[link].Parameters.Get <bool>("Visualise")); Node.OnLinkAdded += (n, link, parameters) => LinkAdded(link, parameters, IsCurrentAlgorithm && parameters.Get <bool>("Visualise")); Node.OnLinkRemoved += (n, link, parameters) => LinkRemoved(link, parameters, IsCurrentAlgorithm && parameters.Get <bool>("Visualise")); }
public DijkstraNode(IMNodeInternal node, IKeyTableFactory tableFactory, IAsynchQueue queue, IConfigSource config) : base(node, tableFactory, config) { _queue = queue; _distances = tableFactory.MakeKeyTable <float>(); _wipRoute = tableFactory.MakeKeyTable <IMLink>(); _prev = tableFactory.MakeKeyTable <DijkstraNode>(); _confirmed = new LinkedList <DijkstraNode>(); _tentative = new LinkedList <DijkstraNode>(); _links = new LinkedList <IMLink>(); SetDistanceFromRoot(ID, 0f, null, null); }
internal void RunAlgorithm(string description, IMNodeInternal to, bool visualise) { _visualise = visualise; ResetAlgorithm(); if (_visualise && IsCurrentAlgorithm) { _visualiseThread = new Thread(() => RunAlgorithm(to)); _visualiseThread.Name = description; _visualiseThread.Start(); } else { _queue.QWork(GetType().Name + " " + description, () => RunAlgorithm(to)); } }
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; }
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); }
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); } }
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> /// 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); } } }
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; } } }
public override void VisualiseAlgorithm(UUID to, Parameters parameters) { if (Equals(VisualisedNode)) { ResetAlgorithm(); _visualise = false; VisualisedNode = null; return; } else if (VisualisedNode != null) { VisualisedNode.Stop(); } IMNodeInternal target = KnownNodes.ContainsKey(to) ? KnownNodes[to] : null; _text = Dijkstra.AlwaysPrint || (Dijkstra.EverPrint && parameters != null && parameters.Get <bool>("Text")); VisualisedNode = this; RunAlgorithm("Visualise Dijkstra's Algorithm", target, true); }
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; }
/// <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 + "'."); } }
private void RunAlgorithm(IMNodeInternal to) { lock (_runLock) { Init(to); if (_visualise) { Logger.Debug("Dijkstra visualising routing from " + Name); } if (_cont && _text && _visualise) { Say("Starting Algorithm"); Say("1. Initialising Confirmed and Tentative lists"); } DijkstraNode current = getNext(this); DijkstraNode prev = current; if (_cont && _text && _visualise) { Pause(); Say("3. Cost for root (" + Node.Name + ") = 0"); Pause(); } MainLoop(current, prev); //If the algorithm didn't finish prematurely if (_cont) { UpdateRoutingTable(); } algorithmFinished(); } }
/// <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); } } }
public Distance(Distance distance, IMNodeInternal hop, IMLink link, float hopWeight) : this(distance.Target, hop, link, distance.Dist + hopWeight) { }
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); }
public IAlgorithmNode MakeNode(IMNodeInternal node, ForwardDelegate forwardMethod) { return(new LinkStateNode(node, _tableFactory, _dijkstraQ, _eventQ, forwardMethod, _config)); }
public IAlgorithmNode MakeNode(IMNodeInternal node, ForwardDelegate forwardMethod) { return new DVNode(node, forwardMethod, _queue, _tableFactory, TTL, _config); }
public DijkstraNode(IMNodeInternal node, IKeyTableFactory tableFactory, IAsynchQueue queue, IConfigSource config) : base(node, tableFactory, config) { _queue = queue; _distances = tableFactory.MakeKeyTable<float>(); _wipRoute = tableFactory.MakeKeyTable<IMLink>(); _prev = tableFactory.MakeKeyTable<DijkstraNode>(); _confirmed = new LinkedList<DijkstraNode>(); _tentative = new LinkedList<DijkstraNode>(); _links = new LinkedList<IMLink>(); SetDistanceFromRoot(ID, 0f, null, null); }
/// <summary> /// Initialise the various variables, flags and collections that are used to run the algorithm. /// </summary> /// <param name="target">The target being routed to. Null means route to every target.</param> /// /// private void Init(IMNodeInternal target) { _target = _target != null && target == null ? _target : target; _confirmed.Clear(); _tentative.Clear(); _links.Clear(); _tentative.AddFirst(this); foreach (DijkstraNode n in this.GetAllNodes<DijkstraNode>()) n.SetDistanceFromRoot(ID, float.MaxValue, null, null); _cont = true; }
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); }
/// <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; }
public IAlgorithmNode MakeNode(IMNodeInternal node, ForwardDelegate forwardMethod) { return(new DVNode(node, forwardMethod, _queue, _tableFactory, TTL, _config)); }
private void VisualiseAlgorithm(IMNodeInternal target, Parameters parameters) { Logger.Debug("Distance vector visualising routing for " + Node.Name + "."); if (target == null) Node.TriggerHighlightAll(DV.DV_NAME); else Node.TriggerHighlight(DV.DV_NAME, target); }
/// <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); }
/// <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); } } }
private void RunAlgorithm(IMNodeInternal to) { lock (_runLock) { Init(to); if (_visualise) Logger.Debug("Dijkstra visualising routing from " + Name); if (_cont && _text && _visualise) { Say("Starting Algorithm"); Say("1. Initialising Confirmed and Tentative lists"); } DijkstraNode current = getNext(this); DijkstraNode prev = current; if (_cont && _text && _visualise) { Pause(); Say("3. Cost for root (" + Node.Name + ") = 0"); Pause(); } MainLoop(current, prev); //If the algorithm didn't finish prematurely if (_cont) UpdateRoutingTable(); algorithmFinished(); } }
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; } } }
/// <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; }
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; }
public IAlgorithmNode MakeNode(IMNodeInternal node, ForwardDelegate forwardMethod) { return new LinkStateNode(node, _tableFactory, _dijkstraQ, _eventQ, forwardMethod, _config); }