/ Tools / TranscriptAnalysis / Receivers / NodesDegree.cs
NodesDegree.cs
  1  using CodexClient;
  2  using CodexPlugin.OverwatchSupport;
  3  using OverwatchTranscript;
  4  
  5  namespace TranscriptAnalysis.Receivers
  6  {
  7      public class NodesDegree : BaseReceiver<OverwatchCodexEvent>
  8      {
  9          public class Dial
 10          {
 11              public Dial(Node peer, Node target)
 12              {
 13                  Id = GetLineId(peer.Id, target.Id);
 14                  InitiatedBy.Add(peer);
 15                  Peer = peer;
 16                  Target = target;
 17              }
 18  
 19              public string Id { get; }
 20              public int RedialCount => InitiatedBy.Count - 1;
 21              public List<Node> InitiatedBy { get; } = new List<Node>();
 22              public Node Peer { get; }
 23              public Node Target { get; }
 24  
 25              private string GetLineId(string a, string b)
 26              {
 27                  if (string.Compare(a, b) > 0)
 28                  {
 29                      return a + b;
 30                  }
 31                  return b + a;
 32              }
 33          }
 34  
 35          public class Node
 36          {
 37              public Node(string peerId)
 38              {
 39                  Id = peerId;
 40              }
 41  
 42              public string Id { get; }
 43              public List<Dial> Dials { get; } = new List<Dial>();
 44              public int Degree => Dials.Count;
 45          }
 46  
 47          private readonly Dictionary<string, Node> dialingNodes = new Dictionary<string, Node>();
 48          private readonly Dictionary<string, Dial> dials = new Dictionary<string, Dial>();
 49          private long uploadSize;
 50  
 51          public override string Name => "NodesDegree";
 52  
 53          public override void Receive(ActivateEvent<OverwatchCodexEvent> @event)
 54          {
 55              if (@event.Payload.DialSuccessful != null)
 56              {
 57                  var peerId = GetPeerId(@event.Payload.NodeIdentity);
 58                  if (peerId == null) return;
 59                  AddDial(peerId, @event.Payload.DialSuccessful.TargetPeerId);
 60              }
 61              if (@event.Payload.FileUploaded != null)
 62              {
 63                  var uploadEvent = @event.Payload.FileUploaded;
 64                  uploadSize = uploadEvent.ByteSize;
 65              }
 66          }
 67  
 68          public override void Finish()
 69          {
 70              var csv = CsvWriter.CreateNew();
 71  
 72              var numNodes = dialingNodes.Count;
 73              var redialOccurances = new OccuranceMap();
 74              foreach (var dial in dials.Values)
 75              {
 76                  redialOccurances.Add(dial.RedialCount);
 77              }
 78              var degreeOccurances = new OccuranceMap();
 79              foreach (var node in dialingNodes.Values)
 80              {
 81                  degreeOccurances.Add(node.Degree);
 82              }
 83  
 84              Log($"Dialing nodes: {numNodes}");
 85              Log("Redials:");
 86              redialOccurances.PrintContinous((i, count) =>
 87              {
 88                  Log($"{i} redials = {count}x");
 89              });
 90  
 91              float tot = numNodes;
 92              csv.GetColumn("numNodes", Header.Nodes.Length);
 93              csv.GetColumn("filesize", uploadSize.ToString());
 94              var degreeColumn = csv.GetColumn("degree", 0.0f);
 95              var occuranceColumn = csv.GetColumn("occurance", 0.0f);
 96              degreeOccurances.Print((i, count) =>
 97              {
 98                  float n = count;
 99                  float p = 100.0f * (n / tot);
100                  Log($"Degree: {i} = {count}x ({p}%)");
101                  csv.AddRow(
102                      new CsvCell(degreeColumn, i),
103                      new CsvCell(occuranceColumn, n)
104                  );
105              });
106  
107              CsvWriter.Write(csv, SourceFilename + "_nodeDegrees.csv");
108          }
109  
110          private void AddDial(string peerId, string targetPeerId)
111          {
112              peerId = CodexUtils.ToShortId(peerId);
113              targetPeerId = CodexUtils.ToShortId(targetPeerId);
114  
115              var peer = GetNode(peerId);
116              var target = GetNode(targetPeerId); ;
117  
118              var dial = new Dial(peer, target);
119  
120              if (dials.ContainsKey(dial.Id))
121              {
122                  var d = dials[dial.Id];
123                  d.InitiatedBy.Add(peer);
124                  peer.Dials.Add(d);
125                  target.Dials.Add(d);
126              }
127              else
128              {
129                  dials.Add(dial.Id, dial);
130                  peer.Dials.Add(dial);
131                  target.Dials.Add(dial);
132              }
133          }
134  
135          private Node GetNode(string id)
136          {
137              if (!dialingNodes.ContainsKey(id))
138              {
139                  dialingNodes.Add(id, new Node(id));
140              }
141              return dialingNodes[id];
142          }
143      }
144  }