PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/traces/old/traceGen/src/sim/Simulator.java

https://code.google.com/p/synoptic/
Java | 187 lines | 121 code | 38 blank | 28 comment | 17 complexity | 869472d03a6cb7f95b6614408a82897e MD5 | raw file
  1. package sim;
  2. import prototrace.ProtoTrace.GenericMessage;
  3. import prototrace.ProtoTrace.PingPongMessage;
  4. import prototrace.ProtoTrace.Trace;
  5. import com.google.protobuf.ByteString;
  6. import java.io.FileOutputStream;
  7. import java.util.Random;
  8. class Simulator {
  9. static Random r = new Random();
  10. private static void printTypes(){
  11. System.err.println("\tTYPE=random #NODES #MESSAGES");
  12. System.err.println("\tTYPE=pingpong #NODES #PINGS ORDER{node | time | structure}");
  13. }
  14. //Ask the user for the name of the tracefile to generate, and
  15. //the type of trace to simulate, and create the trace.
  16. public static void main(String[] args) throws Exception {
  17. if (args.length < 2) {
  18. System.err.println("Usage: Simulator TRACE_FILE TYPE <ARGS>");
  19. printTypes();
  20. System.exit(-1);
  21. }
  22. Trace.Builder trace = Trace.newBuilder();
  23. if(args[1].equalsIgnoreCase("random")){
  24. generateRandom(Integer.parseInt(args[2]), Integer.parseInt(args[3]), trace);
  25. } else if(args[1].equalsIgnoreCase("pingpong")){
  26. generatePingPong(Integer.parseInt(args[2]), Integer.parseInt(args[3]), trace);
  27. //re-order the trace if requested
  28. if(args[4].equalsIgnoreCase("node")){
  29. trace = numericOrder(trace, "time");
  30. trace = numericOrder(trace, "src");
  31. }else if(args[4].equalsIgnoreCase("time")){
  32. trace = numericOrder(trace, "time");
  33. }
  34. } else{
  35. System.err.println("Unknown simulation type. Available types:");
  36. printTypes();
  37. System.exit(-1);
  38. }
  39. /*
  40. // Write the trace out to disk.
  41. System.out.println("Writing the following trace to " + args[0] + ":");
  42. for(GenericMessage m : trace.getGenericMessageList()){
  43. System.out.println("Src: " + m.getSrc() + "Dst: " + m.getDst() +
  44. "Time: " + m.getTimestamp() + "PL: " + m.getPayload().toString());
  45. }
  46. */
  47. // Write the trace out to disk.
  48. FileOutputStream output = new FileOutputStream(args[0]);
  49. trace.build().writeTo(output);
  50. output.close();
  51. }
  52. // This method creates a generic message given the input
  53. static GenericMessage createMessage(int src, int dst, long timestamp, byte[] payload){
  54. GenericMessage.Builder message = GenericMessage.newBuilder();
  55. //stdout.print("Building message...");
  56. message.setSrc(src);
  57. message.setDst(dst);
  58. message.setTimestamp(timestamp);
  59. ByteString bytes = ByteString.copyFrom(payload);
  60. message.setPayload(bytes);
  61. return message.build();
  62. }
  63. //Generate a sequence of messages, with random lengths of random bytes
  64. //as the payload. The only restrictions are that src != dest, and each
  65. //message increases in time.
  66. private static void generateRandom(int nodes, int times, Trace.Builder trace){
  67. for(int i = 0; i < times; i++){
  68. byte[] randomBytes = new byte[r.nextInt(10)];
  69. r.nextBytes(randomBytes);
  70. int[] pair = randomPair(nodes);
  71. GenericMessage message = createMessage(pair[0], pair[1], i, randomBytes);
  72. trace.addGenericMessage(message);
  73. }
  74. }
  75. // generates a trace of ping pong messages, sending a ping every second. Each ping produces a pong 80% of the time
  76. // and when a pong is produced half of the time it is followed by a status message.
  77. // pings and pongs are separated by random intervals of 0-10 seconds. pongs and status messages
  78. // are separated by random intervals of 0-2 seconds.
  79. // NOTE: trace will not be in time-order.
  80. private static void generatePingPong(int nodes, int pings, Trace.Builder trace){
  81. for(int i=0; i<pings; i++){
  82. int[] pair = randomPair(nodes);
  83. int delay = r.nextInt(11); //random delay between the ping and the pong, up to 10 seconds
  84. PingPongMessage ping = createPingPong(pair[0], pair[1], i, "ping");
  85. trace.addPingPongMessage(ping);
  86. if(r.nextDouble() <= 0.8){
  87. PingPongMessage pong = createPingPong(pair[1], pair[0], i+delay, "pong");
  88. trace.addPingPongMessage(pong);
  89. if(r.nextDouble() <= 0.5){
  90. int delay2 = r.nextInt(3);
  91. PingPongMessage status = createPingPong(pair[1], pair[0], i+delay+delay2, "status");
  92. trace.addPingPongMessage(status);
  93. }
  94. }
  95. }
  96. }
  97. // Construct a PingPong message
  98. private static PingPongMessage createPingPong(int src, int dst, long timestamp, String type){
  99. PingPongMessage.Builder message = PingPongMessage.newBuilder();
  100. //stdout.print("Building message...");
  101. message.setSrc(src);
  102. message.setDst(dst);
  103. message.setTimestamp(timestamp);
  104. message.setType(type);
  105. return message.build();
  106. }
  107. //Orders a ping-pong trace by a numeric field and returns the new trace.
  108. //Not the most efficient sort, but it works.
  109. private static Trace.Builder numericOrder(Trace.Builder trace, String field){
  110. Trace.Builder trace2 = Trace.newBuilder();
  111. long lowest = Long.MAX_VALUE;
  112. boolean[] added = new boolean[trace.getPingPongMessageCount()];
  113. int lowestIndex = 0;
  114. while(trace2.getPingPongMessageCount() < trace.getPingPongMessageCount()){
  115. for(int i =0; i < trace.getPingPongMessageCount(); i++){
  116. PingPongMessage current = trace.getPingPongMessage(i);
  117. long currentField;
  118. if(field.equals("time")){
  119. currentField = current.getTimestamp();
  120. }else if(field.equals("src")){
  121. currentField = current.getSrc();
  122. } else {
  123. currentField = current.getDst();
  124. }
  125. if(currentField < lowest && !added[i]){
  126. lowestIndex = i;
  127. lowest = currentField;
  128. }
  129. }
  130. trace2.addPingPongMessage(trace.getPingPongMessage(lowestIndex));
  131. added[lowestIndex] = true;
  132. lowest = Long.MAX_VALUE;
  133. }
  134. return trace2;
  135. }
  136. // returns a 2 element array of a random distinct pair of nodes
  137. // (nodes numbered 0 .. nodes-1)
  138. private static int[] randomPair(int nodes){
  139. int node1 = r.nextInt(nodes);
  140. int node2 = r.nextInt(nodes);
  141. while(node1 == node2){
  142. node2 = r.nextInt(nodes);
  143. }
  144. int[] result = new int[2];
  145. result[0] = node1;
  146. result[1] = node2;
  147. return result;
  148. }
  149. }