PageRenderTime 53ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/jgroups-2.10.0/src/org/jgroups/demos/TotalOrder.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 757 lines | 578 code | 147 blank | 32 comment | 46 complexity | 88b0b76c18b4557b47fb824c258ae8eb MD5 | raw file
  1. // $Id: TotalOrder.java,v 1.15 2009/06/26 07:35:15 belaban Exp $
  2. package org.jgroups.demos;
  3. import org.jgroups.*;
  4. import org.jgroups.util.Util;
  5. import java.awt.*;
  6. import java.awt.event.ActionEvent;
  7. import java.awt.event.ActionListener;
  8. import java.awt.event.WindowAdapter;
  9. import java.awt.event.WindowEvent;
  10. import java.net.InetAddress;
  11. import java.nio.ByteBuffer;
  12. /**
  13. * Originally written to be a demo for TOTAL order (code to be written by a student). In the meantime,
  14. * it evolved into a state transfer demo. All members maintain a shared matrix and continually
  15. * broadcast changes to be applied to a randomly chosen field (e.g. multiplication of field with new
  16. * value, division, addition, subtraction). Each member can be started independently (starts to
  17. * broadcast update messages to all members). When "Stop" is pressed, a stop message is broadcast to
  18. * all members, causing them to stop sending messages. The "Clear" button clears the shared state;
  19. * "GetState" refreshes it from the shared group state (using the state transfer protocol).<p>If the
  20. * demo is to be used to show TOTAL order, then the TOTAL protocol would have to be added to the
  21. * stack.
  22. *
  23. * @author Bela Ban
  24. */
  25. public class TotalOrder extends Frame {
  26. final Font def_font=new Font("Helvetica", Font.BOLD, 12);
  27. final Font def_font2=new Font("Helvetica", Font.PLAIN, 12);
  28. MyCanvas canvas;
  29. final MenuBar menubar=createMenuBar();
  30. final Button start=new Button("Start");
  31. final Button stop=new Button("Stop");
  32. final Button clear=new Button("Clear");
  33. final Button get_state=new Button("Get State");
  34. final Button quit=new Button("Quit");
  35. final Panel button_panel=new Panel();
  36. SenderThread sender=null;
  37. ReceiverThread receiver=null;
  38. Channel channel;
  39. Dialog error_dlg;
  40. long timeout=0;
  41. int field_size=0;
  42. int num_fields=0;
  43. static final int x_offset=30;
  44. static final int y_offset=40;
  45. private int num=0;
  46. private int num_additions=0, num_subtractions=0, num_divisions=0, num_multiplications=0;
  47. void error(String s) {
  48. System.err.println(s);
  49. }
  50. class EventHandler extends WindowAdapter {
  51. final Frame gui;
  52. public EventHandler(Frame g) {
  53. gui=g;
  54. }
  55. public void windowClosing(WindowEvent e) {
  56. gui.dispose();
  57. System.exit(0);
  58. }
  59. }
  60. class SenderThread extends Thread {
  61. TotOrderRequest req;
  62. boolean running=true;
  63. public void stopSender() {
  64. running=false;
  65. interrupt();
  66. System.out.println("-- num_additions: " + num_additions +
  67. "\n-- num_subtractions: " + num_subtractions +
  68. "\n-- num_divisions: " + num_divisions +
  69. "\n-- num_multiplications: " + num_multiplications);
  70. num_additions=num_subtractions=num_multiplications=num_divisions=0;
  71. }
  72. public void run() {
  73. this.setName("SenderThread");
  74. byte[] buf;
  75. int cnt=0;
  76. while(running) {
  77. try {
  78. req=createRandomRequest();
  79. buf=req.toBuffer();
  80. channel.send(new Message(null, null, buf));
  81. System.out.print("-- num requests sent: " + cnt + "\r");
  82. if(timeout > 0)
  83. Util.sleep(timeout);
  84. cnt++;
  85. if(num > 0 && cnt > num) {
  86. running=false;
  87. cnt=0;
  88. }
  89. }
  90. catch(Exception e) {
  91. error(e.toString());
  92. return;
  93. }
  94. }
  95. }
  96. }
  97. class ReceiverThread extends Thread {
  98. SetStateEvent set_state_evt;
  99. boolean running=true;
  100. public void stopReceiver() {
  101. running=false;
  102. interrupt();
  103. }
  104. public void run() {
  105. this.setName("ReceiverThread");
  106. Message msg;
  107. Object o;
  108. ByteBuffer buf;
  109. TotOrderRequest req;
  110. while(running) {
  111. try {
  112. o=channel.receive(0);
  113. if(o instanceof Message) {
  114. try {
  115. msg=(Message)o;
  116. req=new TotOrderRequest();
  117. buf=ByteBuffer.wrap(msg.getBuffer());
  118. req.init(buf);
  119. processRequest(req);
  120. }
  121. catch(Exception e) {
  122. System.err.println(e);
  123. }
  124. }
  125. else
  126. if(o instanceof GetStateEvent) {
  127. int[][] copy_of_state=canvas.getCopyOfState();
  128. channel.returnState(Util.objectToByteBuffer(copy_of_state));
  129. }
  130. else
  131. if(o instanceof SetStateEvent) { // state was received, set it !
  132. set_state_evt=(SetStateEvent)o;
  133. canvas.setState(Util.objectFromByteBuffer(set_state_evt.getArg()));
  134. }
  135. else
  136. if(o instanceof View) System.out.println(o.toString());
  137. }
  138. catch(ChannelClosedException closed) {
  139. error("Channel has been closed; receiver thread quits");
  140. return;
  141. }
  142. catch(Exception e) {
  143. error(e.toString());
  144. return;
  145. }
  146. }
  147. }
  148. }
  149. void processRequest(TotOrderRequest req) throws Exception {
  150. int x=req.x, y=req.y, val=req.val;
  151. if(req.type == TotOrderRequest.STOP) {
  152. stopSender();
  153. return;
  154. }
  155. switch(req.type) {
  156. case TotOrderRequest.ADDITION:
  157. canvas.addValueTo(x, y, val);
  158. num_additions++;
  159. break;
  160. case TotOrderRequest.SUBTRACTION:
  161. canvas.subtractValueFrom(x, y, val);
  162. num_subtractions++;
  163. break;
  164. case TotOrderRequest.MULTIPLICATION:
  165. canvas.multiplyValueWith(x, y, val);
  166. num_multiplications++;
  167. break;
  168. case TotOrderRequest.DIVISION:
  169. canvas.divideValueBy(x, y, val);
  170. num_divisions++;
  171. break;
  172. }
  173. canvas.update();
  174. }
  175. public TotalOrder(String title, long timeout, int num_fields, int field_size, String props, int num) {
  176. Dimension s;
  177. this.timeout=timeout;
  178. this.num_fields=num_fields;
  179. this.field_size=field_size;
  180. this.num=num;
  181. setFont(def_font);
  182. try {
  183. channel=new JChannel(props);
  184. channel.connect("TotalOrderGroup");
  185. channel.getState(null, 8000);
  186. }
  187. catch(Exception e) {
  188. e.printStackTrace();
  189. System.exit(-1);
  190. }
  191. start.addActionListener(new ActionListener() {
  192. public void actionPerformed(ActionEvent e) {
  193. startSender();
  194. }
  195. });
  196. stop.addActionListener(new ActionListener() {
  197. public void actionPerformed(ActionEvent e) {
  198. try {
  199. TotOrderRequest req=new TotOrderRequest(TotOrderRequest.STOP, 0, 0, 0);
  200. byte[] buf=req.toBuffer();
  201. channel.send(
  202. new Message(
  203. null,
  204. null,
  205. buf));
  206. }
  207. catch(Exception ex) {
  208. }
  209. }
  210. });
  211. clear.addActionListener(new ActionListener() {
  212. public void actionPerformed(ActionEvent e) {
  213. canvas.clear();
  214. }
  215. });
  216. get_state.addActionListener(new ActionListener() {
  217. public void actionPerformed(ActionEvent e) {
  218. try {
  219. boolean rc=channel.getState(null, 3000);
  220. if(rc == false)
  221. error("State could not be retrieved !");
  222. }
  223. catch(Throwable t) {
  224. error("exception fetching state: " + t);
  225. }
  226. }
  227. });
  228. quit.addActionListener(new ActionListener() {
  229. public void actionPerformed(ActionEvent e) {
  230. channel.disconnect();
  231. channel.close();
  232. System.exit(0);
  233. }
  234. });
  235. setTitle(title);
  236. addWindowListener(new EventHandler(this));
  237. setBackground(Color.white);
  238. setMenuBar(menubar);
  239. setLayout(new BorderLayout());
  240. canvas=new MyCanvas(num_fields, field_size, x_offset, y_offset);
  241. add("Center", canvas);
  242. button_panel.setLayout(new FlowLayout());
  243. button_panel.setFont(def_font2);
  244. button_panel.add(start);
  245. button_panel.add(stop);
  246. button_panel.add(clear);
  247. button_panel.add(get_state);
  248. button_panel.add(quit);
  249. add("South", button_panel);
  250. s=canvas.getSize();
  251. s.height+=100;
  252. setSize(s);
  253. startReceiver();
  254. }
  255. void startSender() {
  256. if(sender == null || !sender.isAlive()) {
  257. sender=new SenderThread();
  258. sender.start();
  259. }
  260. }
  261. void stopSender() {
  262. if(sender != null) {
  263. sender.stopSender();
  264. sender=null;
  265. }
  266. }
  267. void startReceiver() {
  268. if(receiver == null) {
  269. receiver=new ReceiverThread();
  270. receiver.start();
  271. }
  272. }
  273. private MenuBar createMenuBar() {
  274. MenuBar ret=new MenuBar();
  275. Menu file=new Menu("File");
  276. MenuItem quitm=new MenuItem("Quit");
  277. ret.setFont(def_font2);
  278. ret.add(file);
  279. file.addSeparator();
  280. file.add(quitm);
  281. quitm.addActionListener(
  282. new ActionListener() {
  283. public void actionPerformed(ActionEvent e) {
  284. System.exit(1);
  285. }
  286. });
  287. return ret;
  288. }
  289. private TotOrderRequest createRandomRequest() {
  290. TotOrderRequest ret=null;
  291. byte op_type=(byte)(((Math.random() * 10) % 4) + 1); // 1 - 4
  292. int x=(int)((Math.random() * num_fields * 2) % num_fields);
  293. int y=(int)((Math.random() * num_fields * 2) % num_fields);
  294. int val=(int)((Math.random() * num_fields * 200) % 10);
  295. ret=new TotOrderRequest(op_type, x, y, val);
  296. return ret;
  297. }
  298. public static void main(String[] args) {
  299. TotalOrder g;
  300. String arg;
  301. long timeout=200;
  302. int num_fields=3;
  303. int field_size=80;
  304. String props=null;
  305. int num=0;
  306. props="udp.xml";
  307. for(int i=0; i < args.length; i++) {
  308. arg=args[i];
  309. if("-timeout".equals(arg)) {
  310. timeout=Long.parseLong(args[++i]);
  311. continue;
  312. }
  313. if("-num_fields".equals(arg)) {
  314. num_fields=Integer.parseInt(args[++i]);
  315. continue;
  316. }
  317. if("-field_size".equals(arg)) {
  318. field_size=Integer.parseInt(args[++i]);
  319. continue;
  320. }
  321. if("-help".equals(arg)) {
  322. System.out.println("\nTotalOrder [-timeout <value>] [-num_fields <value>] " +
  323. "[-field_size <value>] [-props <properties (can be URL)>] [-num <num requests>]\n");
  324. return;
  325. }
  326. if("-props".equals(arg)) {
  327. props=args[++i];
  328. continue;
  329. }
  330. if("-num".equals(arg)) {
  331. num=Integer.parseInt(args[++i]);
  332. }
  333. }
  334. try {
  335. g=new TotalOrder("Total Order Demo on " + InetAddress.getLocalHost().getHostName(),
  336. timeout, num_fields, field_size, props, num);
  337. g.setVisible(true);
  338. }
  339. catch(Exception e) {
  340. System.err.println(e);
  341. }
  342. }
  343. }
  344. class TotOrderRequest {
  345. public static final byte STOP=0;
  346. public static final byte ADDITION=1;
  347. public static final byte SUBTRACTION=2;
  348. public static final byte MULTIPLICATION=3;
  349. public static final byte DIVISION=4;
  350. final static int SIZE=Global.BYTE_SIZE + Global.INT_SIZE * 3;
  351. public byte type=ADDITION;
  352. public int x=0;
  353. public int y=0;
  354. public int val=0;
  355. public TotOrderRequest() {
  356. }
  357. TotOrderRequest(byte type, int x, int y, int val) {
  358. this.type=type;
  359. this.x=x;
  360. this.y=y;
  361. this.val=val;
  362. }
  363. public String printType() {
  364. switch(type) {
  365. case STOP:
  366. return "STOP";
  367. case ADDITION:
  368. return "ADDITION";
  369. case SUBTRACTION:
  370. return "SUBTRACTION";
  371. case MULTIPLICATION:
  372. return "MULTIPLICATION";
  373. case DIVISION:
  374. return "DIVISION";
  375. default:
  376. return "<unknown>";
  377. }
  378. }
  379. // public void writeExternal(ObjectOutput out) throws IOException {
  380. // out.writeByte(type);
  381. // out.writeInt(x);
  382. // out.writeInt(y);
  383. // out.writeInt(val);
  384. // }
  385. //
  386. // public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
  387. // type=in.readByte();
  388. // x=in.readInt();
  389. // y=in.readInt();
  390. // val=in.readInt();
  391. // }
  392. public byte[] toBuffer() {
  393. ByteBuffer buf=ByteBuffer.allocate(SIZE);
  394. buf.put(type);
  395. buf.putInt(x);
  396. buf.putInt(y);
  397. buf.putInt(val);
  398. return buf.array();
  399. }
  400. public void init(ByteBuffer buf) {
  401. type=buf.get();
  402. x=buf.getInt();
  403. y=buf.getInt();
  404. val=buf.getInt();
  405. }
  406. public String toString() {
  407. return "[" + x + ',' + y + ": " + printType() + '(' + val + ")]";
  408. }
  409. }
  410. class MyCanvas extends Canvas {
  411. int field_size=100;
  412. int num_fields=4;
  413. int x_offset=30;
  414. int y_offset=30;
  415. final Font def_font=new Font("Helvetica", Font.BOLD, 14);
  416. int[][] array=null; // state
  417. Dimension off_dimension=null;
  418. Image off_image=null;
  419. Graphics off_graphics=null;
  420. final Font def_font2=new Font("Helvetica", Font.PLAIN, 12);
  421. static final Color checksum_col=Color.blue;
  422. int checksum=0;
  423. public MyCanvas(int num_fields, int field_size, int x_offset, int y_offset) {
  424. this.num_fields=num_fields;
  425. this.field_size=field_size;
  426. this.x_offset=x_offset;
  427. this.y_offset=y_offset;
  428. array=new int[num_fields][num_fields];
  429. setBackground(Color.white);
  430. setSize(2 * x_offset + num_fields * field_size + 30, y_offset + num_fields * field_size + 50);
  431. for(int i=0; i < num_fields; i++)
  432. for(int j=0; j < num_fields; j++)
  433. array[i][j]=0;
  434. }
  435. public void setFieldSize(int fs) {
  436. field_size=fs;
  437. }
  438. public void setNumFields(int nf) {
  439. num_fields=nf;
  440. }
  441. public void setXOffset(int o) {
  442. x_offset=o;
  443. }
  444. public void setYOffset(int o) {
  445. y_offset=o;
  446. }
  447. public void addValueTo(int x, int y, int value) {
  448. synchronized(array) {
  449. array[x][y]+=value;
  450. repaint();
  451. }
  452. }
  453. public void subtractValueFrom(int x, int y, int value) {
  454. synchronized(array) {
  455. array[x][y]-=value;
  456. repaint();
  457. }
  458. }
  459. public void multiplyValueWith(int x, int y, int value) {
  460. synchronized(array) {
  461. array[x][y]*=value;
  462. repaint();
  463. }
  464. }
  465. public void divideValueBy(int x, int y, int value) {
  466. if(value == 0)
  467. return;
  468. synchronized(array) {
  469. array[x][y]/=value;
  470. repaint();
  471. }
  472. }
  473. public void setValueAt(int x, int y, int value) {
  474. synchronized(array) {
  475. array[x][y]=value;
  476. }
  477. repaint();
  478. }
  479. public int getValueAt(int x, int y) {
  480. synchronized(array) {
  481. return array[x][y];
  482. }
  483. }
  484. public void clear() {
  485. synchronized(array) {
  486. for(int i=0; i < num_fields; i++)
  487. for(int j=0; j < num_fields; j++)
  488. array[i][j]=0;
  489. checksum=checksum();
  490. repaint();
  491. }
  492. }
  493. public int[][] getState() {
  494. synchronized(array) {
  495. return array;
  496. }
  497. }
  498. public int[][] getCopyOfState() {
  499. int[][] retval=new int[num_fields][num_fields];
  500. synchronized(array) {
  501. for(int i=0; i < num_fields; i++)
  502. System.arraycopy(array[i], 0, retval[i], 0, num_fields);
  503. return retval;
  504. }
  505. }
  506. public void update() {
  507. checksum=checksum();
  508. repaint();
  509. }
  510. public void setState(Object new_state) {
  511. if(new_state == null)
  512. return;
  513. try {
  514. int[][] new_array=(int[][])new_state;
  515. synchronized(array) {
  516. clear();
  517. for(int i=0; i < num_fields; i++)
  518. System.arraycopy(new_array[i], 0, array[i], 0, num_fields);
  519. checksum=checksum();
  520. repaint();
  521. }
  522. }
  523. catch(Exception e) {
  524. System.err.println(e);
  525. return;
  526. }
  527. }
  528. public int checksum() {
  529. int retval=0;
  530. synchronized(array) {
  531. for(int i=0; i < num_fields; i++)
  532. for(int j=0; j < num_fields; j++)
  533. retval+=array[i][j];
  534. }
  535. return retval;
  536. }
  537. public void update(Graphics g) {
  538. Dimension d=getSize();
  539. if(off_graphics == null ||
  540. d.width != off_dimension.width ||
  541. d.height != off_dimension.height) {
  542. off_dimension=d;
  543. off_image=createImage(d.width, d.height);
  544. off_graphics=off_image.getGraphics();
  545. }
  546. //Erase the previous image.
  547. off_graphics.setColor(getBackground());
  548. off_graphics.fillRect(0, 0, d.width, d.height);
  549. off_graphics.setColor(Color.black);
  550. off_graphics.setFont(def_font);
  551. drawEmptyBoard(off_graphics);
  552. drawNumbers(off_graphics);
  553. g.drawImage(off_image, 0, 0, this);
  554. }
  555. public void paint(Graphics g) {
  556. update(g);
  557. }
  558. /**
  559. * Draws the empty board, no pieces on it yet, just grid lines
  560. */
  561. void drawEmptyBoard(Graphics g) {
  562. int x=x_offset, y=y_offset;
  563. Color old_col=g.getColor();
  564. g.setFont(def_font2);
  565. old_col=g.getColor();
  566. g.setColor(checksum_col);
  567. g.drawString(("Checksum: " + checksum), x_offset + field_size, y_offset - 20);
  568. g.setFont(def_font);
  569. g.setColor(old_col);
  570. for(int i=0; i < num_fields; i++) {
  571. for(int j=0; j < num_fields; j++) { // draws 1 row
  572. g.drawRect(x, y, field_size, field_size);
  573. x+=field_size;
  574. }
  575. g.drawString(("" + (num_fields - i - 1)), x + 20, y + field_size / 2);
  576. y+=field_size;
  577. x=x_offset;
  578. }
  579. for(int i=0; i < num_fields; i++) {
  580. g.drawString(("" + i), x_offset + i * field_size + field_size / 2, y + 30);
  581. }
  582. }
  583. void drawNumbers(Graphics g) {
  584. Point p;
  585. String num;
  586. FontMetrics fm=g.getFontMetrics();
  587. int len=0;
  588. synchronized(array) {
  589. for(int i=0; i < num_fields; i++)
  590. for(int j=0; j < num_fields; j++) {
  591. num="" + array[i][j];
  592. len=fm.stringWidth(num);
  593. p=index2Coord(i, j);
  594. g.drawString(num, p.x - (len / 2), p.y);
  595. }
  596. }
  597. }
  598. Point coord2Index(int x, int y) {
  599. Point ret=new Point();
  600. ret.x=x_offset + (x * field_size);
  601. ret.y=y_offset + ((num_fields - 1 - y) * field_size);
  602. return ret;
  603. }
  604. Point index2Coord(int i, int j) {
  605. int x=x_offset + i * field_size + field_size / 2;
  606. // int y=y_offset + j*field_size + field_size/2;
  607. int y=y_offset + num_fields * field_size - j * field_size - field_size / 2;
  608. return new Point(x, y);
  609. }
  610. }