/// <summary> /// Generates source-target pairs among the previously generated Chirper users. /// </summary> /// <param name="graphDoc">The GraphML document that the code is building.</param> /// <param name="duplicateEdgeStatistic"> /// A passed in statistic that will be incremented each time a duplicate edge is generated. /// </param> /// <returns>The length of time used to generate the edges among the nodes.</returns> private TimeSpan GenerateChirperFollowerEdge(ChirperGraphMLDocument graphDoc, ref int duplicateEdgeStatistic) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); int edgeId = this.edgeIDStartValue; int maxNodeId = this.nodeIdStartValue + this.networkNodeCount; int minNodeId = this.edgeNodeStartIdValue; Random randomGenerator = new Random(); Console.Write("\t"); while (edgeId < this.networkEdgeCount + this.edgeIDStartValue) { int source = 0; int target = 0; if (this.random) { // Use while loops to prevent keeping source and target values of zero. while (source == 0) { source = randomGenerator.Next(this.nodeIdStartValue, maxNodeId); } while (target == 0) { target = randomGenerator.Next(this.nodeIdStartValue, maxNodeId); } } else { int relativeEdgeId = edgeId - this.edgeIDStartValue; int edgesPerNode = this.networkEdgeCount / this.networkNodeCount; int relativeSource = relativeEdgeId / edgesPerNode; int relativeTarget = (relativeSource + 1 + (relativeEdgeId % edgesPerNode)); int range = maxNodeId - minNodeId; source = relativeSource + minNodeId; target = (relativeTarget % range) + minNodeId; } // Don't allow the source to be equal to the target. while (source == target) { target = randomGenerator.Next(minNodeId, maxNodeId); } if (graphDoc.AddEdge(edgeId, source, target)) { // Don't increment if the add fails due to a duplicate. edgeId++; } else { duplicateEdgeStatistic++; } if ((edgeId % ProgressInterval) == 0) Console.Write("."); // Show progress } Console.WriteLine("."); stopwatch.Stop(); return TimeSpan.FromSeconds(stopwatch.Elapsed.TotalSeconds); }
/// <summary> /// Generates Chirper "User Ids" and adds them to the GraphML document. /// </summary> /// <param name="graphDoc">The GraphML document that the code is building.</param> /// <returns>The length of time used to generate the nodes.</returns> private TimeSpan GenerateChirperUserNodes(ChirperGraphMLDocument graphDoc) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Console.Write("\t"); for (int nodeIndex = this.nodeIdStartValue; nodeIndex < this.networkNodeCount + nodeIdStartValue; nodeIndex++) { // Since we are using a for loop, these will never be duplicates. // If the method of generating the indexes is changed to one that could produce duplicates, // the return value of AddNode() must be taken into account. string userId = "U" + nodeIndex.ToString(CultureInfo.InvariantCulture); graphDoc.AddNode(nodeIndex, userId); if ((nodeIndex % ProgressInterval) == 0) Console.Write("."); // Show progress } Console.WriteLine("."); stopwatch.Stop(); TimeSpan nodeGenerationTime = TimeSpan.FromSeconds(stopwatch.Elapsed.TotalSeconds); return nodeGenerationTime; }
internal int Run() { string thisProcessName = Process.GetCurrentProcess().ProcessName; using (PerformanceCounter memoryMonitor = new PerformanceCounter("Process", "Working Set", thisProcessName)) { memoryMonitor.NextSample(); using (PerformanceCounter processorMonitor = new PerformanceCounter("Process", "% Processor Time", thisProcessName)) { processorMonitor.NextSample(); networkGeneratorLog = new List<string>(); LogMessage("********************************************************"); LogMessage(string.Format("{0,25}\t{1:G}", "Start Network Generation:", DateTime.Now)); LogMessage(string.Format("{0,25}\t{1:N0}\tEdges: {2:N0}", "Requested Nodes:", this.networkNodeCount, this.networkEdgeCount)); LogMessage(string.Format("{0,25}\t{1:N0}\tEdges: {2:N0}", "Start Ids - Nodes:", this.nodeIdStartValue, this.edgeIDStartValue)); ChirperGraphMLDocument graphDoc = new ChirperGraphMLDocument(); LogMessage(string.Empty); LogMessage("Starting node generation..."); TimeSpan nodeGenerationTime = GenerateChirperUserNodes(graphDoc); LogMessage("\tNode generation complete in " + nodeGenerationTime); LogPerformanceCounterData(memoryMonitor, processorMonitor); LogMessage(string.Empty); FlushLog(); int duplicateEdgeStatistic = 0; TimeSpan edgeGenerationTime = default(TimeSpan); if (this.networkEdgeCount > 0) { LogMessage("Starting edge generation..."); edgeGenerationTime = GenerateChirperFollowerEdge(graphDoc, ref duplicateEdgeStatistic); LogMessage("\tEdge generation complete in " + edgeGenerationTime); LogMessage("\tDuplicates generated: " + duplicateEdgeStatistic); LogPerformanceCounterData(memoryMonitor, processorMonitor); LogMessage(string.Empty); } else { LogMessage("Edge generation suppressed from command line."); LogMessage(string.Empty); } Stopwatch stopwatch = new Stopwatch(); FlushLog(); LogMessage("Starting GraphML File write..."); stopwatch.Restart(); graphDoc.WriteXmlWithWriter(this.graphMLFile); stopwatch.Stop(); TimeSpan xmlWriteTime = TimeSpan.FromSeconds(stopwatch.Elapsed.TotalSeconds); LogMessage("\tGraphML file write complete in " + xmlWriteTime); LogPerformanceCounterData(memoryMonitor, processorMonitor); LogMessage(string.Empty); LogMessage(string.Format(CultureInfo.InvariantCulture, "{0,30}\t{1}", "Total Graph Generation Time:", (nodeGenerationTime + edgeGenerationTime + xmlWriteTime))); LogMessage(string.Empty); FlushLog(); // Get the size of the file so we can add the statistic. FileInfo fileInfo = new FileInfo(this.graphMLFile); fileInfo.Refresh(); long fileLength = fileInfo.Length; string range = "bytes"; if (fileLength > Kilo) { fileLength = fileLength / Kilo; range = "KB"; } if (fileLength > Kilo) { fileLength = fileLength / Kilo; range = "MB"; } LogMessage(string.Format(CultureInfo.InvariantCulture, "{0,30}\t{1:N0} {2}", "GraphML File Size:", fileLength, range)); LogMessage(string.Empty); FlushLog(); } } // Using Linq to XML here to insert the statistic comment won't adversely affect performance. //XComment statisticsComment = new XComment(summaryMessageStringBuilder.ToString()); //XDocument generatedGraphMLDoc = XDocument.Load(graphMLFile); //XElement graphElement = generatedGraphMLDoc.Root; //graphElement.AddFirst(statisticsComment); //graphElement.Document.Save(this.graphMLFile); return 0; }