Пример #1
0
 private static void printDiamond(UInt32 pointASN, UInt32 stub, List <UInt32> competitors, SecureSimulator.NetworkGraph g, StreamWriter output)
 {
     SecureSimulator.AsNode pointASNode = g.GetNode(pointASN);
     SecureSimulator.AsNode stubASNode  = g.GetNode(stub);
     foreach (UInt32 c in competitors)
     {
         SecureSimulator.AsNode cASNode = g.GetNode(c);
         output.WriteLine("{0} {1} {2} {3} {4}", pointASN,
                          relationshipToString(cASNode.GetRelationshipTypeOfNeighbor(pointASNode)),
                          c,
                          relationshipToString(stubASNode.GetRelationshipTypeOfNeighbor(cASNode)),
                          stub);
     }
 }
Пример #2
0
        /// <summary>
        /// Extension method on the NetworkGraph class that performs a [modified] BFS on the
        /// specified graph from the specified source ndoe.  The allowedRelationships specifies
        /// which edges may be traversed during the BFS.
        /// This algorithm breaks ties by picking the node with the lower node number.
        /// This algorithm allows you to execute multiple BFS iterations on a single graph, with the
        /// constraint that any previous BFS trees created in a prior BFS run will not be modified (only
        /// added to).
        /// If limitedDiscovery is true, the BFS will only find new nodes that are 1 edge away from any existing
        /// BFS tree.
        /// If includeSibling is true, then ties are broken by first taking non-siblings over siblings.
        ///
        /// Modified by PGill Oct. 2010 to take in references to the Best, BucketTable and ChosenPaths sets. The function
        /// was also modified to populate these for our new sims.
        /// </summary>
        public static void ExecuteBfs(NetworkGraph graph, List <UInt32> srcNodeNums, bool limitedDiscovery, bool includeSibling,
                                      RelationshipType allowedRelationships, ref List <UInt32>[] Best, ref List <UInt32>[] BestNew, ref List <UInt32>[][] BucketTable, ref List <UInt32>[] ChosenPath,
                                      ref UInt32[] ChosenParent, ref byte[] L, ref byte[] BestRelation)
        {
            Destination utility = new Destination();
            // Initialize some stuff...
            Queue <AsNode> nodeQueue = new Queue <AsNode>(graph.NodeCount);

            graph.BfsTreeNodeCount = 0;

            // "Visit" the source nodes
            foreach (UInt32 srcNodeNum in srcNodeNums)
            {
                AsNode currentNode = graph.GetNode(srcNodeNum);
                currentNode.InProcessBfsStatus = NodeInProcessBfsStatus.SeenInCurrentRun;
                currentNode.BfsDepth           = 0;
                nodeQueue.Enqueue(currentNode);
                graph.BfsTreeNodeCount++;

                //init the destination's path to itself
                ChosenPath[srcNodeNum] = new List <UInt32>();
                ChosenPath[srcNodeNum].Add(srcNodeNum);
                Best[srcNodeNum] = new List <UInt32>();
                Best[srcNodeNum].Add(srcNodeNum);


                //if (allowedRelationships.HasFlag(RelationshipType.CustomerOf))
                if ((allowedRelationships & RelationshipType.CustomerOf) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship)
                {
                    BucketTable[0][Destination._CUSTOMERCOLUMN] = new List <UInt32>();
                    BucketTable[0][Destination._CUSTOMERCOLUMN].Add(srcNodeNum);
                }
            }

            // While there's still nodes to be examined...
            while (nodeQueue.Count > 0)
            {
                // Dequeue a node to examine.  Iterate through all of its neighbors of the specified type (plus
                // existing BFS children) and visit them.
                AsNode currentNode = nodeQueue.Dequeue();
                foreach (AsNode oppositeNode in currentNode.GetNeighborsByType(allowedRelationships | RelationshipType.BfsParentOf).Distinct())
                {
                    bool addedtoBest = false;
                    // If this is the first time we've see this node, mark it and possibly enqueue it for later examination
                    if (oppositeNode.InProcessBfsStatus == NodeInProcessBfsStatus.UnseenInCurrentRun)
                    {
                        // Case 1: oppositeNode is a newly discovered node, also unseen in any previous BFS runs
                        if (oppositeNode.PriorBfsStatus == NodePriorBfsStatus.NotDiscoveredInPriorBfs)
                        {
                            oppositeNode.InProcessBfsStatus = NodeInProcessBfsStatus.SeenInCurrentRun;
                            oppositeNode.BfsDepth           = currentNode.BfsDepth + 1;
                            oppositeNode.BfsParentNode      = currentNode;

                            currentNode.AddBfsChild(oppositeNode);

                            graph.BfsTreeDepth = Math.Max(graph.BfsTreeDepth, oppositeNode.BfsDepth);
                            graph.BfsTreeNodeCount++;

                            if (!oppositeNode.isStub() || !OnlyNonStubs)
                            {
                                L[oppositeNode.NodeNum] = (byte)oppositeNode.BfsDepth;
                                /*** add this node to the buckettable and update its chosen path, parent and BFS depth***/

                                //if (allowedRelationships.HasFlag(RelationshipType.CustomerOf)) -- this is .NET 4, downgraded to make comptabilte with .NET 3.5
                                if ((allowedRelationships & RelationshipType.CustomerOf) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship)
                                {
                                    //init this spot in the bucket table (if needed)
                                    if (BucketTable[oppositeNode.BfsDepth][Destination._CUSTOMERCOLUMN] == null)
                                    {
                                        BucketTable[oppositeNode.BfsDepth][Destination._CUSTOMERCOLUMN] = new List <UInt32>();
                                    }

                                    BestRelation[oppositeNode.NodeNum] = Destination._CUSTOMERCOLUMN;
                                    BucketTable[oppositeNode.BfsDepth][Destination._CUSTOMERCOLUMN].Add(oppositeNode.NodeNum);
                                    utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._CUSTOMERCOLUMN, ref ChosenPath);
                                }
                                //else if (allowedRelationships.HasFlag(RelationshipType.ProviderTo)) -- this is .NET 4, downgraded to make comptabilte with .NET 3.5
                                else if ((allowedRelationships & RelationshipType.ProviderTo) == RelationshipType.ProviderTo)
                                {
                                    //init this spot in the bucket table (if needed)
                                    if (BucketTable[oppositeNode.BfsDepth][Destination._PROVIDERCOLUMN] == null)
                                    {
                                        BucketTable[oppositeNode.BfsDepth][Destination._PROVIDERCOLUMN] = new List <UInt32>();
                                    }

                                    BestRelation[oppositeNode.NodeNum] = Destination._PROVIDERCOLUMN;
                                    BucketTable[oppositeNode.BfsDepth][Destination._PROVIDERCOLUMN].Add(oppositeNode.NodeNum);
                                    utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PROVIDERCOLUMN, ref ChosenPath);
                                }

                                //else if (allowedRelationships.HasFlag(RelationshipType.PeerOf)) -- this is .NET 4, downgraded to make comptabilte with .NET 3.5
                                else if ((allowedRelationships & RelationshipType.PeerOf) == RelationshipType.PeerOf)
                                {
                                    //init this spot in the bucket table (if needed)
                                    if (BucketTable[oppositeNode.BfsDepth][Destination._PEERCOLUMN] == null)
                                    {
                                        BucketTable[oppositeNode.BfsDepth][Destination._PEERCOLUMN] = new List <UInt32>();
                                    }

                                    BestRelation[oppositeNode.NodeNum] = Destination._PEERCOLUMN;
                                    BucketTable[oppositeNode.BfsDepth][Destination._PEERCOLUMN].Add(oppositeNode.NodeNum);
                                    utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PEERCOLUMN, ref ChosenPath);
                                }

                                /*** update this node's Best set ***/
                                if (Best[oppositeNode.NodeNum] == null)
                                {
                                    Best[oppositeNode.NodeNum] = new List <UInt32>();
                                }
                                Best[oppositeNode.NodeNum].Add(currentNode.NodeNum);
                                ChosenParent[oppositeNode.NodeNum] = currentNode.NodeNum;

                                if (BestNew[oppositeNode.NodeNum] == null)
                                {
                                    BestNew[oppositeNode.NodeNum] = new List <UInt32>();
                                }

                                UInt32 encoded  = 0;
                                UInt32 NodeNumx = currentNode.NodeNum;

                                if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.ProviderTo)
                                {
                                    encoded = (UInt32)((NodeNumx << 3) + Destination._PROVIDERCOLUMN);
                                }
                                else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship)
                                {
                                    encoded = (UInt32)((NodeNumx << 3) + Destination._CUSTOMERCOLUMN);
                                }
                                else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.PeerOf)
                                {
                                    encoded = (UInt32)((NodeNumx << 3) + Destination._PEERCOLUMN);
                                }
                                BestNew[oppositeNode.NodeNum].Add(encoded);
                            }

                            // If we want to continue discovering past this newly found node, enqueue it
                            if (!limitedDiscovery)
                            {
                                nodeQueue.Enqueue(oppositeNode);
                            }
                        }
                        // Case 2: oppositeNode was found in a prior BFS run, and the path to oppositeNode went through currentNode
                        else if (oppositeNode.BfsParentNode == currentNode)
                        {
                            // Don't need to do any marking of the opposite node because it's already in the BFS tree.
                            // Just enqueue it so we can continue our BFS from that node at some later time.
                            oppositeNode.InProcessBfsStatus = NodeInProcessBfsStatus.SeenInCurrentRun;
                            nodeQueue.Enqueue(oppositeNode);
                            graph.BfsTreeDepth = Math.Max(graph.BfsTreeDepth, oppositeNode.BfsDepth);
                            graph.BfsTreeNodeCount++;

                            // Sanity check... the depth should be the same, right?
                            if (oppositeNode.BfsDepth != currentNode.BfsDepth + 1)
                            {
                                throw new Exception("Unexpected BFS depth during BFS re-run");
                            }
                        }
                        // Case 3: oppositeNode was found in a prior BFS run, and the path to oppositeNode did NOT go through currentNode
                        // No action necessary.  We can't process oppositeNode now because we aren't allow to follow this edge.
                        // Eventually we will hit the already-existing edge that's part of a prior BFS run, and we'll enter Case 2 above.
                    }
                    // We've seen this node before...
                    else
                    {
                        // Did we find an alternate route to the opposite node?
                        // We cannot change the route if this node was found in a prior BFS run.
                        // This is where tie-breaking happens...
                        if ((oppositeNode.InProcessBfsStatus == NodeInProcessBfsStatus.SeenInCurrentRun) &&
                            (oppositeNode.BfsDepth == (currentNode.BfsDepth + 1)) &&
                            (oppositeNode.PriorBfsStatus != NodePriorBfsStatus.DiscoveredInPriorBfs))
                        {
                            // This is an alternate route... break the tie
                            //note that current node is a potential parent of opposite node here.
                            //equivalent to current node being one of the nodes in the tiebreak set

                            //Console.WriteLine("Ties Breaker");

                            //UPDATED CONDITION TO DEAL WITH HASH FLAG
                            if ((Hash && NewRouteWinsTieBreak(currentNode, oppositeNode, includeSibling)) || (!Hash && NewRouteWinsTieBreakOriginal(currentNode, oppositeNode, includeSibling)))
                            {
                                // Tie-break algorithm says we have a new, better route to this node.
                                // We need to switch the route through the current node instead.
                                oppositeNode.BfsParentNode.RemoveBfsChild(oppositeNode);
                                oppositeNode.BfsParentNode = currentNode;
                                currentNode.AddBfsChild(oppositeNode);

                                if (!oppositeNode.isStub() || !OnlyNonStubs)
                                {
                                    /*** update chosen parent***/
                                    ChosenParent[oppositeNode.NodeNum] = currentNode.NodeNum;

                                    /***  update its chosen path ***/

                                    //if (allowedRelationships.HasFlag(RelationshipType.CustomerOf))
                                    if ((allowedRelationships & RelationshipType.CustomerOf) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship)
                                    {
                                        utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._CUSTOMERCOLUMN, ref ChosenPath);
                                    }
                                    //else if (allowedRelationships.HasFlag(RelationshipType.ProviderTo))
                                    else if ((allowedRelationships & RelationshipType.ProviderTo) == RelationshipType.ProviderTo)
                                    {
                                        utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PROVIDERCOLUMN, ref ChosenPath);
                                    }
                                    //else if (allowedRelationships.HasFlag(RelationshipType.PeerOf))
                                    else if ((allowedRelationships & RelationshipType.PeerOf) == RelationshipType.PeerOf)
                                    {
                                        utility.updatePath(oppositeNode.NodeNum, ChosenPath[currentNode.NodeNum], Destination._PEERCOLUMN, ref ChosenPath);
                                    }
                                }
                            }
                            /*** NEED TO UPDATE BEST SET WHETHER OR NOT THIS WINS THE TIE BREAK!! **/
                            if (!oppositeNode.isStub() || !OnlyNonStubs)
                            {
                                Best[oppositeNode.NodeNum].Add(currentNode.NodeNum);
                                addedtoBest = true;
                            }
                        }
                    }
                    if ((Best[oppositeNode.NodeNum] != null))// && addedtoBest)// &&
                    //(oppositeNode.PriorBfsStatus != NodePriorBfsStatus.DiscoveredInPriorBfs))
                    {
                        if (BestNew[oppositeNode.NodeNum] == null)
                        {
                            BestNew[oppositeNode.NodeNum] = new List <UInt32>();
                        }

                        UInt32 encoded  = 0;
                        UInt32 NodeNumx = currentNode.NodeNum;

                        if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.ProviderTo)
                        {
                            encoded = (UInt32)((NodeNumx << 3) + Destination._PROVIDERCOLUMN);
                        }
                        else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.CustomerOf || allowedRelationships == RelationshipType.NullRelationship)
                        {
                            encoded = (UInt32)((NodeNumx << 3) + Destination._CUSTOMERCOLUMN);
                        }
                        else if ((allowedRelationships & currentNode.GetRelationshipTypeOfNeighbor(oppositeNode)) == RelationshipType.PeerOf)
                        {
                            encoded = (UInt32)((NodeNumx << 3) + Destination._PEERCOLUMN);
                        }

                        UInt32 encoded0 = (UInt32)((NodeNumx << 3) + Destination._PROVIDERCOLUMN);
                        UInt32 encoded1 = (UInt32)((NodeNumx << 3) + Destination._CUSTOMERCOLUMN);
                        UInt32 encoded2 = (UInt32)((NodeNumx << 3) + Destination._PEERCOLUMN);


                        if (!((BestNew[oppositeNode.NodeNum].Exists(element => element == encoded0)) || (BestNew[oppositeNode.NodeNum].Exists(element => element == encoded1)) || (BestNew[oppositeNode.NodeNum].Exists(element => element == encoded2))))
                        {
                            //Console.WriteLine(oppositeNode.NodeNum + "--> Entered for: " + ((UInt32)(((uint)encoded) >> 3) + " relation: " + (int)(encoded & 7)));
                            //Console.WriteLine("encoded = " + encoded);
                            if (encoded != 0)
                            {
                                //Console.WriteLine(oppositeNode.NodeNum + "--> Entered for: " + ((UInt32)(((uint)encoded) >> 3) + " relation: " + (int)(encoded & 7)));
                                //if ((((allowedRelationships & RelationshipType.ProviderTo) == RelationshipType.ProviderTo) && oppositeNode.InProcessBfsStatus == NodeInProcessBfsStatus.ProcessedInCurrentRun))
                                //{
                                //    Console.Write("Rel: " + allowedRelationships + " & Node status: " + oppositeNode.InProcessBfsStatus + "\n");
                                //}
                                //else
                                {
                                    BestNew[oppositeNode.NodeNum].Add(encoded);
                                }
                            }
                        }
                    }
                }
                // Update the in-process BFS status
                currentNode.InProcessBfsStatus = NodeInProcessBfsStatus.ProcessedInCurrentRun;
            }

            // Finished the BFS... lock the discovered nodes into the BFS tree
            foreach (AsNode node in graph.GetAllNodes())
            {
                // FYI In limitedDiscovery mode, some nodes may have been left in the SeenInCurrentRun state
                // (instead of ProcessedInCurrentRun).
                if (node.InProcessBfsStatus != NodeInProcessBfsStatus.UnseenInCurrentRun)
                {
                    node.PriorBfsStatus = NodePriorBfsStatus.DiscoveredInPriorBfs;
                }
                node.InProcessBfsStatus = NodeInProcessBfsStatus.UnseenInCurrentRun;
            }
        }