/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
- // $Id: TotalOrder.java,v 1.15 2009/06/26 07:35:15 belaban Exp $
- package org.jgroups.demos;
- import org.jgroups.*;
- import org.jgroups.util.Util;
- import java.awt.*;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import java.awt.event.WindowAdapter;
- import java.awt.event.WindowEvent;
- import java.net.InetAddress;
- import java.nio.ByteBuffer;
- /**
- * Originally written to be a demo for TOTAL order (code to be written by a student). In the meantime,
- * it evolved into a state transfer demo. All members maintain a shared matrix and continually
- * broadcast changes to be applied to a randomly chosen field (e.g. multiplication of field with new
- * value, division, addition, subtraction). Each member can be started independently (starts to
- * broadcast update messages to all members). When "Stop" is pressed, a stop message is broadcast to
- * all members, causing them to stop sending messages. The "Clear" button clears the shared state;
- * "GetState" refreshes it from the shared group state (using the state transfer protocol).<p>If the
- * demo is to be used to show TOTAL order, then the TOTAL protocol would have to be added to the
- * stack.
- *
- * @author Bela Ban
- */
- public class TotalOrder extends Frame {
- final Font def_font=new Font("Helvetica", Font.BOLD, 12);
- final Font def_font2=new Font("Helvetica", Font.PLAIN, 12);
- MyCanvas canvas;
- final MenuBar menubar=createMenuBar();
- final Button start=new Button("Start");
- final Button stop=new Button("Stop");
- final Button clear=new Button("Clear");
- final Button get_state=new Button("Get State");
- final Button quit=new Button("Quit");
- final Panel button_panel=new Panel();
- SenderThread sender=null;
- ReceiverThread receiver=null;
- Channel channel;
- Dialog error_dlg;
- long timeout=0;
- int field_size=0;
- int num_fields=0;
- static final int x_offset=30;
- static final int y_offset=40;
- private int num=0;
- private int num_additions=0, num_subtractions=0, num_divisions=0, num_multiplications=0;
- void error(String s) {
- System.err.println(s);
- }
- class EventHandler extends WindowAdapter {
- final Frame gui;
- public EventHandler(Frame g) {
- gui=g;
- }
- public void windowClosing(WindowEvent e) {
- gui.dispose();
- System.exit(0);
- }
- }
- class SenderThread extends Thread {
- TotOrderRequest req;
- boolean running=true;
- public void stopSender() {
- running=false;
- interrupt();
- System.out.println("-- num_additions: " + num_additions +
- "\n-- num_subtractions: " + num_subtractions +
- "\n-- num_divisions: " + num_divisions +
- "\n-- num_multiplications: " + num_multiplications);
- num_additions=num_subtractions=num_multiplications=num_divisions=0;
- }
- public void run() {
- this.setName("SenderThread");
- byte[] buf;
- int cnt=0;
- while(running) {
- try {
- req=createRandomRequest();
- buf=req.toBuffer();
- channel.send(new Message(null, null, buf));
- System.out.print("-- num requests sent: " + cnt + "\r");
- if(timeout > 0)
- Util.sleep(timeout);
- cnt++;
- if(num > 0 && cnt > num) {
- running=false;
- cnt=0;
- }
- }
- catch(Exception e) {
- error(e.toString());
- return;
- }
- }
- }
- }
- class ReceiverThread extends Thread {
- SetStateEvent set_state_evt;
- boolean running=true;
- public void stopReceiver() {
- running=false;
- interrupt();
- }
- public void run() {
- this.setName("ReceiverThread");
- Message msg;
- Object o;
- ByteBuffer buf;
- TotOrderRequest req;
- while(running) {
- try {
- o=channel.receive(0);
- if(o instanceof Message) {
- try {
- msg=(Message)o;
- req=new TotOrderRequest();
- buf=ByteBuffer.wrap(msg.getBuffer());
- req.init(buf);
- processRequest(req);
- }
- catch(Exception e) {
- System.err.println(e);
- }
- }
- else
- if(o instanceof GetStateEvent) {
- int[][] copy_of_state=canvas.getCopyOfState();
- channel.returnState(Util.objectToByteBuffer(copy_of_state));
- }
- else
- if(o instanceof SetStateEvent) { // state was received, set it !
- set_state_evt=(SetStateEvent)o;
- canvas.setState(Util.objectFromByteBuffer(set_state_evt.getArg()));
- }
- else
- if(o instanceof View) System.out.println(o.toString());
- }
- catch(ChannelClosedException closed) {
- error("Channel has been closed; receiver thread quits");
- return;
- }
- catch(Exception e) {
- error(e.toString());
- return;
- }
- }
- }
- }
- void processRequest(TotOrderRequest req) throws Exception {
- int x=req.x, y=req.y, val=req.val;
- if(req.type == TotOrderRequest.STOP) {
- stopSender();
- return;
- }
- switch(req.type) {
- case TotOrderRequest.ADDITION:
- canvas.addValueTo(x, y, val);
- num_additions++;
- break;
- case TotOrderRequest.SUBTRACTION:
- canvas.subtractValueFrom(x, y, val);
- num_subtractions++;
- break;
- case TotOrderRequest.MULTIPLICATION:
- canvas.multiplyValueWith(x, y, val);
- num_multiplications++;
- break;
- case TotOrderRequest.DIVISION:
- canvas.divideValueBy(x, y, val);
- num_divisions++;
- break;
- }
- canvas.update();
- }
- public TotalOrder(String title, long timeout, int num_fields, int field_size, String props, int num) {
- Dimension s;
- this.timeout=timeout;
- this.num_fields=num_fields;
- this.field_size=field_size;
- this.num=num;
- setFont(def_font);
- try {
- channel=new JChannel(props);
- channel.connect("TotalOrderGroup");
- channel.getState(null, 8000);
- }
- catch(Exception e) {
- e.printStackTrace();
- System.exit(-1);
- }
- start.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- startSender();
- }
- });
- stop.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- try {
- TotOrderRequest req=new TotOrderRequest(TotOrderRequest.STOP, 0, 0, 0);
- byte[] buf=req.toBuffer();
- channel.send(
- new Message(
- null,
- null,
- buf));
- }
- catch(Exception ex) {
- }
- }
- });
- clear.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- canvas.clear();
- }
- });
- get_state.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- try {
- boolean rc=channel.getState(null, 3000);
- if(rc == false)
- error("State could not be retrieved !");
- }
- catch(Throwable t) {
- error("exception fetching state: " + t);
- }
- }
- });
- quit.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- channel.disconnect();
- channel.close();
- System.exit(0);
- }
- });
- setTitle(title);
- addWindowListener(new EventHandler(this));
- setBackground(Color.white);
- setMenuBar(menubar);
- setLayout(new BorderLayout());
- canvas=new MyCanvas(num_fields, field_size, x_offset, y_offset);
- add("Center", canvas);
- button_panel.setLayout(new FlowLayout());
- button_panel.setFont(def_font2);
- button_panel.add(start);
- button_panel.add(stop);
- button_panel.add(clear);
- button_panel.add(get_state);
- button_panel.add(quit);
- add("South", button_panel);
- s=canvas.getSize();
- s.height+=100;
- setSize(s);
- startReceiver();
- }
- void startSender() {
- if(sender == null || !sender.isAlive()) {
- sender=new SenderThread();
- sender.start();
- }
- }
- void stopSender() {
- if(sender != null) {
- sender.stopSender();
- sender=null;
- }
- }
- void startReceiver() {
- if(receiver == null) {
- receiver=new ReceiverThread();
- receiver.start();
- }
- }
- private MenuBar createMenuBar() {
- MenuBar ret=new MenuBar();
- Menu file=new Menu("File");
- MenuItem quitm=new MenuItem("Quit");
- ret.setFont(def_font2);
- ret.add(file);
- file.addSeparator();
- file.add(quitm);
- quitm.addActionListener(
- new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- System.exit(1);
- }
- });
- return ret;
- }
- private TotOrderRequest createRandomRequest() {
- TotOrderRequest ret=null;
- byte op_type=(byte)(((Math.random() * 10) % 4) + 1); // 1 - 4
- int x=(int)((Math.random() * num_fields * 2) % num_fields);
- int y=(int)((Math.random() * num_fields * 2) % num_fields);
- int val=(int)((Math.random() * num_fields * 200) % 10);
- ret=new TotOrderRequest(op_type, x, y, val);
- return ret;
- }
- public static void main(String[] args) {
- TotalOrder g;
- String arg;
- long timeout=200;
- int num_fields=3;
- int field_size=80;
- String props=null;
- int num=0;
- props="udp.xml";
- for(int i=0; i < args.length; i++) {
- arg=args[i];
- if("-timeout".equals(arg)) {
- timeout=Long.parseLong(args[++i]);
- continue;
- }
- if("-num_fields".equals(arg)) {
- num_fields=Integer.parseInt(args[++i]);
- continue;
- }
- if("-field_size".equals(arg)) {
- field_size=Integer.parseInt(args[++i]);
- continue;
- }
- if("-help".equals(arg)) {
- System.out.println("\nTotalOrder [-timeout <value>] [-num_fields <value>] " +
- "[-field_size <value>] [-props <properties (can be URL)>] [-num <num requests>]\n");
- return;
- }
- if("-props".equals(arg)) {
- props=args[++i];
- continue;
- }
- if("-num".equals(arg)) {
- num=Integer.parseInt(args[++i]);
- }
- }
- try {
- g=new TotalOrder("Total Order Demo on " + InetAddress.getLocalHost().getHostName(),
- timeout, num_fields, field_size, props, num);
- g.setVisible(true);
- }
- catch(Exception e) {
- System.err.println(e);
- }
- }
- }
- class TotOrderRequest {
- public static final byte STOP=0;
- public static final byte ADDITION=1;
- public static final byte SUBTRACTION=2;
- public static final byte MULTIPLICATION=3;
- public static final byte DIVISION=4;
- final static int SIZE=Global.BYTE_SIZE + Global.INT_SIZE * 3;
- public byte type=ADDITION;
- public int x=0;
- public int y=0;
- public int val=0;
- public TotOrderRequest() {
- }
- TotOrderRequest(byte type, int x, int y, int val) {
- this.type=type;
- this.x=x;
- this.y=y;
- this.val=val;
- }
- public String printType() {
- switch(type) {
- case STOP:
- return "STOP";
- case ADDITION:
- return "ADDITION";
- case SUBTRACTION:
- return "SUBTRACTION";
- case MULTIPLICATION:
- return "MULTIPLICATION";
- case DIVISION:
- return "DIVISION";
- default:
- return "<unknown>";
- }
- }
- // public void writeExternal(ObjectOutput out) throws IOException {
- // out.writeByte(type);
- // out.writeInt(x);
- // out.writeInt(y);
- // out.writeInt(val);
- // }
- //
- // public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- // type=in.readByte();
- // x=in.readInt();
- // y=in.readInt();
- // val=in.readInt();
- // }
- public byte[] toBuffer() {
- ByteBuffer buf=ByteBuffer.allocate(SIZE);
- buf.put(type);
- buf.putInt(x);
- buf.putInt(y);
- buf.putInt(val);
- return buf.array();
- }
- public void init(ByteBuffer buf) {
- type=buf.get();
- x=buf.getInt();
- y=buf.getInt();
- val=buf.getInt();
- }
- public String toString() {
- return "[" + x + ',' + y + ": " + printType() + '(' + val + ")]";
- }
- }
- class MyCanvas extends Canvas {
- int field_size=100;
- int num_fields=4;
- int x_offset=30;
- int y_offset=30;
- final Font def_font=new Font("Helvetica", Font.BOLD, 14);
- int[][] array=null; // state
- Dimension off_dimension=null;
- Image off_image=null;
- Graphics off_graphics=null;
- final Font def_font2=new Font("Helvetica", Font.PLAIN, 12);
- static final Color checksum_col=Color.blue;
- int checksum=0;
- public MyCanvas(int num_fields, int field_size, int x_offset, int y_offset) {
- this.num_fields=num_fields;
- this.field_size=field_size;
- this.x_offset=x_offset;
- this.y_offset=y_offset;
- array=new int[num_fields][num_fields];
- setBackground(Color.white);
- setSize(2 * x_offset + num_fields * field_size + 30, y_offset + num_fields * field_size + 50);
- for(int i=0; i < num_fields; i++)
- for(int j=0; j < num_fields; j++)
- array[i][j]=0;
- }
- public void setFieldSize(int fs) {
- field_size=fs;
- }
- public void setNumFields(int nf) {
- num_fields=nf;
- }
- public void setXOffset(int o) {
- x_offset=o;
- }
- public void setYOffset(int o) {
- y_offset=o;
- }
- public void addValueTo(int x, int y, int value) {
- synchronized(array) {
- array[x][y]+=value;
- repaint();
- }
- }
- public void subtractValueFrom(int x, int y, int value) {
- synchronized(array) {
- array[x][y]-=value;
- repaint();
- }
- }
- public void multiplyValueWith(int x, int y, int value) {
- synchronized(array) {
- array[x][y]*=value;
- repaint();
- }
- }
- public void divideValueBy(int x, int y, int value) {
- if(value == 0)
- return;
- synchronized(array) {
- array[x][y]/=value;
- repaint();
- }
- }
- public void setValueAt(int x, int y, int value) {
- synchronized(array) {
- array[x][y]=value;
- }
- repaint();
- }
- public int getValueAt(int x, int y) {
- synchronized(array) {
- return array[x][y];
- }
- }
- public void clear() {
- synchronized(array) {
- for(int i=0; i < num_fields; i++)
- for(int j=0; j < num_fields; j++)
- array[i][j]=0;
- checksum=checksum();
- repaint();
- }
- }
- public int[][] getState() {
- synchronized(array) {
- return array;
- }
- }
- public int[][] getCopyOfState() {
- int[][] retval=new int[num_fields][num_fields];
- synchronized(array) {
- for(int i=0; i < num_fields; i++)
- System.arraycopy(array[i], 0, retval[i], 0, num_fields);
- return retval;
- }
- }
- public void update() {
- checksum=checksum();
- repaint();
- }
- public void setState(Object new_state) {
- if(new_state == null)
- return;
- try {
- int[][] new_array=(int[][])new_state;
- synchronized(array) {
- clear();
- for(int i=0; i < num_fields; i++)
- System.arraycopy(new_array[i], 0, array[i], 0, num_fields);
- checksum=checksum();
- repaint();
- }
- }
- catch(Exception e) {
- System.err.println(e);
- return;
- }
- }
- public int checksum() {
- int retval=0;
- synchronized(array) {
- for(int i=0; i < num_fields; i++)
- for(int j=0; j < num_fields; j++)
- retval+=array[i][j];
- }
- return retval;
- }
- public void update(Graphics g) {
- Dimension d=getSize();
- if(off_graphics == null ||
- d.width != off_dimension.width ||
- d.height != off_dimension.height) {
- off_dimension=d;
- off_image=createImage(d.width, d.height);
- off_graphics=off_image.getGraphics();
- }
- //Erase the previous image.
- off_graphics.setColor(getBackground());
- off_graphics.fillRect(0, 0, d.width, d.height);
- off_graphics.setColor(Color.black);
- off_graphics.setFont(def_font);
- drawEmptyBoard(off_graphics);
- drawNumbers(off_graphics);
- g.drawImage(off_image, 0, 0, this);
- }
- public void paint(Graphics g) {
- update(g);
- }
- /**
- * Draws the empty board, no pieces on it yet, just grid lines
- */
- void drawEmptyBoard(Graphics g) {
- int x=x_offset, y=y_offset;
- Color old_col=g.getColor();
- g.setFont(def_font2);
- old_col=g.getColor();
- g.setColor(checksum_col);
- g.drawString(("Checksum: " + checksum), x_offset + field_size, y_offset - 20);
- g.setFont(def_font);
- g.setColor(old_col);
- for(int i=0; i < num_fields; i++) {
- for(int j=0; j < num_fields; j++) { // draws 1 row
- g.drawRect(x, y, field_size, field_size);
- x+=field_size;
- }
- g.drawString(("" + (num_fields - i - 1)), x + 20, y + field_size / 2);
- y+=field_size;
- x=x_offset;
- }
- for(int i=0; i < num_fields; i++) {
- g.drawString(("" + i), x_offset + i * field_size + field_size / 2, y + 30);
- }
- }
- void drawNumbers(Graphics g) {
- Point p;
- String num;
- FontMetrics fm=g.getFontMetrics();
- int len=0;
- synchronized(array) {
- for(int i=0; i < num_fields; i++)
- for(int j=0; j < num_fields; j++) {
- num="" + array[i][j];
- len=fm.stringWidth(num);
- p=index2Coord(i, j);
- g.drawString(num, p.x - (len / 2), p.y);
- }
- }
- }
- Point coord2Index(int x, int y) {
- Point ret=new Point();
- ret.x=x_offset + (x * field_size);
- ret.y=y_offset + ((num_fields - 1 - y) * field_size);
- return ret;
- }
- Point index2Coord(int i, int j) {
- int x=x_offset + i * field_size + field_size / 2;
- // int y=y_offset + j*field_size + field_size/2;
- int y=y_offset + num_fields * field_size - j * field_size - field_size / 2;
- return new Point(x, y);
- }
- }