PageRenderTime 234ms CodeModel.GetById 44ms RepoModel.GetById 1ms app.codeStats 1ms

/projects/jgroups-2.10.0/tests/perf/org/jgroups/tests/perf/IPerf.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 420 lines | 338 code | 69 blank | 13 comment | 30 complexity | 52ae6b845a8693c74b74d6861efe56a5 MD5 | raw file
  1. package org.jgroups.tests.perf;
  2. import org.jgroups.*;
  3. import org.jgroups.util.Util;
  4. import org.jgroups.util.Tuple;
  5. import java.nio.ByteBuffer;
  6. import java.util.*;
  7. import java.util.concurrent.ConcurrentHashMap;
  8. import java.util.concurrent.ConcurrentMap;
  9. import java.util.concurrent.TimeUnit;
  10. import java.util.concurrent.locks.Lock;
  11. import java.util.concurrent.locks.ReentrantLock;
  12. import java.util.concurrent.locks.Condition;
  13. import java.net.InetAddress;
  14. import java.text.NumberFormat;
  15. /**
  16. * Tests sending large messages from one sender to multiple receivers. The following messages are exchanged:
  17. * <pre>
  18. * | START (1 byte) |
  19. * | DATA (1 byte) | size (int, 4 bytes) | byte[] buf |
  20. * | STOP (1 byte) |
  21. * | RESULT (1 byte) | total time (long, 8 bytes) | total_bytes (long, 8 bytes)|
  22. * | REGISTER (1 byte) |
  23. *
  24. * </pre>
  25. * @author Bela Ban
  26. * @version $Id: IPerf.java,v 1.13 2008/10/10 16:00:44 belaban Exp $
  27. */
  28. public class IPerf implements Receiver {
  29. private final Configuration config;
  30. private final ConcurrentMap<Object,Entry> receiver_table=new ConcurrentHashMap<Object,Entry>();
  31. private Transport transport=null;
  32. private ResultSet results=null;
  33. private final Set<Object> members=new HashSet<Object>();
  34. private final static NumberFormat f;
  35. static {
  36. f=NumberFormat.getNumberInstance();
  37. f.setGroupingUsed(false);
  38. f.setMaximumFractionDigits(2);
  39. }
  40. public IPerf(Configuration config) {
  41. this.config=config;
  42. }
  43. public void start() throws Exception {
  44. transport=(Transport)Class.forName(config.getTransport()).newInstance();
  45. transport.create(config);
  46. transport.setReceiver(this);
  47. transport.start();
  48. members.add(transport.getLocalAddress());
  49. byte[] buf=createRegisterMessage();
  50. transport.send(null, buf, false);
  51. if(config.isSender()) {
  52. send();
  53. transport.stop();
  54. transport.destroy();
  55. }
  56. else {
  57. System.out.println("Transport " + transport.getClass().getName() + " started at " + new Date());
  58. System.out.println("Listening on " + transport.getLocalAddress());
  59. }
  60. }
  61. public void receive(Object sender, byte[] payload) {
  62. ByteBuffer buf=ByteBuffer.wrap(payload);
  63. byte b=buf.get();
  64. Type type=Type.getType(b);
  65. switch(type) {
  66. case START:
  67. receiver_table.remove(sender);
  68. receiver_table.putIfAbsent(sender, new Entry());
  69. break;
  70. case DATA:
  71. Entry entry=receiver_table.get(sender);
  72. if(entry == null) {
  73. err("entry for " + sender + " not found");
  74. return;
  75. }
  76. int length=buf.getInt();
  77. entry.total_bytes+=length;
  78. break;
  79. case STOP:
  80. entry=receiver_table.get(sender);
  81. if(entry == null) {
  82. err("entry for " + sender + " not found");
  83. return;
  84. }
  85. if(entry.stop_time == 0) {
  86. entry.stop_time=System.currentTimeMillis();
  87. }
  88. System.out.println("result for " + sender + ": " + entry);
  89. sendResult(sender, entry);
  90. break;
  91. case RESULT:
  92. long total_time=buf.getLong(), total_bytes=buf.getLong();
  93. results.add(sender, total_time, total_bytes);
  94. break;
  95. case REGISTER:
  96. members.add(sender);
  97. break;
  98. }
  99. }
  100. private void send() throws Exception {
  101. int size=config.getSize();
  102. long time=config.getTime();
  103. int chunk_size=config.getChunkSize();
  104. results=new ResultSet(members, size);
  105. byte[] buf=createStartMessage();
  106. transport.send(null, buf, false);
  107. if(time > 0) {
  108. ByteBuffer buffer=createDataBuffer(chunk_size);
  109. buffer.put(Type.DATA.getByte());
  110. buffer.putInt(chunk_size);
  111. buf=buffer.array();
  112. long end_time=System.currentTimeMillis() + time;
  113. while(System.currentTimeMillis() < end_time) {
  114. transport.send(null, buf, false);
  115. }
  116. }
  117. else {
  118. int sent=0;
  119. int to_send, remaining;
  120. while(sent < size) {
  121. remaining=size - sent;
  122. to_send=Math.min(remaining, chunk_size);
  123. buf=createDataMessage(to_send);
  124. transport.send(null, buf, false);
  125. sent+=to_send;
  126. }
  127. }
  128. buf=createStopMessage();
  129. transport.send(null, buf, false);
  130. boolean rc=results.block(30000L);
  131. if(rc)
  132. log("got all results");
  133. else
  134. err("didnt get all results");
  135. System.out.println("\nResults:\n" + results);
  136. results.reset();
  137. }
  138. private static byte[] createRegisterMessage() {
  139. return createMessage(Type.REGISTER);
  140. }
  141. private void sendResult(Object destination, Entry entry) {
  142. ByteBuffer buf=ByteBuffer.allocate(Global.BYTE_SIZE + Global.LONG_SIZE * 2);
  143. buf.put(Type.RESULT.getByte());
  144. buf.putLong(entry.stop_time - entry.start_time);
  145. buf.putLong(entry.total_bytes);
  146. try {
  147. transport.send(destination, buf.array(), false);
  148. }
  149. catch(Exception e) {
  150. err(e.toString());
  151. }
  152. }
  153. private static byte[] createStartMessage() {
  154. return createMessage(Type.START);
  155. }
  156. private static byte[] createDataMessage(int length) {
  157. ByteBuffer buf=ByteBuffer.allocate(Global.BYTE_SIZE + length + Global.INT_SIZE);
  158. buf.put(Type.DATA.getByte());
  159. buf.putInt(length);
  160. return buf.array();
  161. }
  162. private static ByteBuffer createDataBuffer(int length) {
  163. ByteBuffer buf=ByteBuffer.allocate(Global.BYTE_SIZE + length + Global.INT_SIZE);
  164. buf.put(Type.DATA.getByte());
  165. buf.putInt(length);
  166. return buf;
  167. }
  168. private static byte[] createStopMessage() {
  169. return createMessage(Type.STOP);
  170. }
  171. private static byte[] createMessage(Type type) {
  172. ByteBuffer buf=ByteBuffer.allocate(Global.BYTE_SIZE);
  173. buf.put(type.getByte());
  174. return buf.array();
  175. }
  176. public static void main(String[] args) throws Exception {
  177. Configuration config=new Configuration();
  178. List<String> unused_args=new ArrayList<String>(args.length);
  179. for(int i=0; i < args.length; i++) {
  180. String tmp=args[i];
  181. if(tmp.equalsIgnoreCase("-sender")) {
  182. config.setSender(true);
  183. continue;
  184. }
  185. if(tmp.equalsIgnoreCase("-size")) {
  186. config.setSize(Integer.parseInt(args[++i]));
  187. continue;
  188. }
  189. if(tmp.equals("-time")) {
  190. config.setTime(Long.parseLong(args[++i]));
  191. continue;
  192. }
  193. if(tmp.equals("-chunk_size")) {
  194. config.setChunkSize(Integer.parseInt(args[++i]));
  195. continue;
  196. }
  197. if(tmp.equals("-transport")) {
  198. config.setTransport(args[++i]);
  199. continue;
  200. }
  201. if(tmp.equals("-bind_addr")) {
  202. config.setBindAddress(InetAddress.getByName(args[++i]));
  203. continue;
  204. }
  205. if(tmp.equals("-h") || tmp.equals("-help")) {
  206. help(config.getTransport());
  207. return;
  208. }
  209. unused_args.add(tmp);
  210. }
  211. if(!unused_args.isEmpty()) {
  212. String[] tmp=new String[unused_args.size()];
  213. for(int i=0; i < unused_args.size(); i++)
  214. tmp[i]=unused_args.get(i);
  215. config.setTransportArgs(tmp);
  216. }
  217. new IPerf(config).start();
  218. }
  219. static void help(String transport) {
  220. StringBuilder sb=new StringBuilder();
  221. sb.append("IPerf [-sender] [-bind_addr <addr>] [-transport <class name>] [-size <bytes> | -time <ms>] [-chunk_size <bytes>]");
  222. try {
  223. Transport tp=(Transport)Class.forName(transport).newInstance();
  224. String tmp=tp.help();
  225. if(tmp != null && tmp.length() > 0)
  226. sb.append("\nTransport specific options for " + tp.getClass().getName() + ":\n" + tp.help());
  227. }
  228. catch(Exception e) {
  229. e.printStackTrace();
  230. }
  231. System.out.println(sb);
  232. }
  233. private static void log(String msg) {
  234. System.out.println(msg);
  235. }
  236. private static void err(String msg) {
  237. System.err.println(msg);
  238. }
  239. public static enum Type {
  240. START(1),
  241. DATA(2),
  242. STOP(3),
  243. RESULT(4),
  244. REGISTER(5);
  245. final byte b;
  246. Type(int i) {
  247. b=(byte)i;
  248. }
  249. public byte getByte() {
  250. return b;
  251. }
  252. public static Type getType(byte input) {
  253. switch(input) {
  254. case 1: return START;
  255. case 2: return DATA;
  256. case 3: return STOP;
  257. case 4: return RESULT;
  258. case 5: return REGISTER;
  259. }
  260. throw new IllegalArgumentException("type " + input + " is not valid");
  261. }
  262. }
  263. private static class Entry {
  264. private final long start_time;
  265. private long stop_time=0;
  266. private long total_bytes=0;
  267. public Entry() {
  268. this.start_time=System.currentTimeMillis();
  269. }
  270. public String toString() {
  271. double throughput=total_bytes / ((stop_time - start_time) / 1000.0);
  272. return stop_time - start_time + " ms for " + Util.printBytes(total_bytes) +
  273. " (" + Util.printBytes(throughput) + " / sec)";
  274. }
  275. }
  276. private static class ResultSet {
  277. private final Set<Object> not_heard_from;
  278. private final ConcurrentMap<Object, Tuple<Long,Long>> results=new ConcurrentHashMap<Object,Tuple<Long,Long>>();
  279. private final Lock lock=new ReentrantLock();
  280. private final Condition cond=lock.newCondition();
  281. private long expected_bytes=0;
  282. public ResultSet(Collection<Object> not_heard_from, long expected_bytes) {
  283. this.not_heard_from=new HashSet<Object>(not_heard_from); // make a copy
  284. this.expected_bytes=expected_bytes;
  285. }
  286. public boolean add(Object sender, long time, long total_bytes) {
  287. results.putIfAbsent(sender, new Tuple<Long,Long>(time, total_bytes));
  288. lock.lock();
  289. try {
  290. if(not_heard_from.remove(sender))
  291. cond.signalAll();
  292. return not_heard_from.isEmpty();
  293. }
  294. finally {
  295. lock.unlock();
  296. }
  297. }
  298. public boolean block(long timeout) {
  299. long target=System.currentTimeMillis() + timeout;
  300. long curr_time;
  301. lock.lock();
  302. try {
  303. while((curr_time=System.currentTimeMillis()) < target && !not_heard_from.isEmpty()) {
  304. long wait_time=target - curr_time;
  305. try {
  306. cond.await(wait_time, TimeUnit.MILLISECONDS);
  307. }
  308. catch(InterruptedException e) {
  309. ;
  310. }
  311. }
  312. return not_heard_from.isEmpty();
  313. }
  314. finally {
  315. lock.unlock();
  316. }
  317. }
  318. public int size() {
  319. return results.size();
  320. }
  321. public void reset() {
  322. lock.lock();
  323. try {
  324. not_heard_from.clear();
  325. results.clear();
  326. cond.signalAll();
  327. }
  328. finally {
  329. lock.unlock();;
  330. }
  331. }
  332. public String toString() {
  333. StringBuilder sb=new StringBuilder();
  334. for(Map.Entry<Object,Tuple<Long,Long>> entry: results.entrySet()) {
  335. Tuple<Long, Long> val=entry.getValue();
  336. sb.append(entry.getKey()).append(" time=" + val.getVal1() + " ms for " + Util.printBytes(val.getVal2()));
  337. if(expected_bytes > 0) {
  338. long total_received_bytes=val.getVal2();
  339. long missing=expected_bytes - total_received_bytes;
  340. double loss_rate=100.0 / expected_bytes * missing;
  341. double throughput=val.getVal2() / (val.getVal1() / 1000.0);
  342. sb.append(" (" + Util.printBytes(throughput) + " / sec, loss rate=" + f.format(loss_rate) + "%)");
  343. }
  344. sb.append("\n");
  345. }
  346. if(!not_heard_from.isEmpty())
  347. sb.append("(not heard from " + not_heard_from + ")\n");
  348. return sb.toString();
  349. }
  350. }
  351. }