// $Id: DistributedHashtableDemo.java,v 1.7 2006/10/25 16:26:25 belaban Exp $
package org.jgroups.demos;
import org.jgroups.ChannelException;
import org.jgroups.ChannelFactory;
import org.jgroups.JChannelFactory;
import org.jgroups.blocks.DistributedHashtable;
import org.jgroups.persistence.PersistenceFactory;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector;
/**
* Uses the DistributedHashtable building block. The latter subclasses java.util.Hashtable and overrides
* the methods that modify the hashtable (e.g. put()). Those methods are multicast to the group, whereas
* read-only methods such as get() use the local copy. A DistributedHashtable is created given the name
* of a group; all hashtables with the same name find each other and form a group.
* @author Bela Ban
*/
public class DistributedHashtableDemo extends Frame implements WindowListener, ActionListener,
DistributedHashtable.Notification {
static final String groupname="HashDemo";
DistributedHashtable h=null;
final JButton get=new JButton("Get");
final JButton set=new JButton("Set");
final JButton quit=new JButton("Quit");
final JButton get_all=new JButton("All");
final JButton delete=new JButton("Delete");
final JLabel stock=new JLabel("Key");
final JLabel value=new JLabel("Value");
final JLabel err_msg=new JLabel("Error");
final JTextField stock_field=new JTextField();
final JTextField value_field=new JTextField();
final java.awt.List listbox=new java.awt.List();
final Font default_font=new Font("Helvetica", Font.PLAIN,12);
public DistributedHashtableDemo() {
super();
addWindowListener(this);
}
private void showMsg(String msg) {
err_msg.setText(msg);
err_msg.setVisible(true);
}
private void clearMsg() {err_msg.setVisible(false);}
private void removeItem() {
int index=listbox.getSelectedIndex();
if(index == -1) {
showMsg("No item selected in listbox to be deleted !");
return;
}
String s=listbox.getSelectedItem();
String key=s.substring(0, s.indexOf(':', 0));
if(key != null)
h.remove(key);
}
private void showAll() {
if(listbox.getItemCount() > 0)
listbox.removeAll();
if(h.size() == 0)
return;
clearMsg();
String key;
Float val;
for(Enumeration en=h.keys(); en.hasMoreElements();) {
key=(String)en.nextElement();
val=(Float)h.get(key);
if(val == null)
continue;
listbox.add(key + ": " + val.toString());
}
}
public void start(ChannelFactory factory, String props, boolean persist)
throws ChannelException {
h=new DistributedHashtable(groupname, factory, props, persist, 10000);
h.addNotifier(this);
setLayout(null);
setSize(400, 300);
setFont(default_font);
stock.setBounds(new Rectangle(10, 30, 60, 30));
value.setBounds(new Rectangle(10, 60, 60, 30));
stock_field.setBounds(new Rectangle(100, 30, 100, 30));
value_field.setBounds(new Rectangle(100, 60, 100, 30));
listbox.setBounds(new Rectangle(210, 30, 150, 160));
err_msg.setBounds(new Rectangle(10, 200, 350, 30));
err_msg.setFont(new Font("Helvetica",Font.ITALIC,12));
err_msg.setForeground(Color.red);
err_msg.setVisible(false);
get.setBounds(new Rectangle(10, 250, 60, 30));
set.setBounds(new Rectangle(80, 250, 60, 30));
quit.setBounds(new Rectangle(150, 250, 60, 30));
get_all.setBounds(new Rectangle(220, 250, 60, 30));
delete.setBounds(new Rectangle(290, 250, 80, 30));
get.addActionListener(this);
set.addActionListener(this);
quit.addActionListener(this);
get_all.addActionListener(this);
delete.addActionListener(this);
add(stock); add(value);
add(stock_field); add(value_field);
add(err_msg);
add(get); add(set); add(quit); add(get_all); add(delete);
add(listbox);
setTitle("DistributedHashtable Demo");
showAll();
pack();
setVisible(true);
// new Thread() {
// public void run() {
// System.out.println("-- sleeping");
// Util.sleep(10000);
// for(int i=0; i < 10; i++) {
// System.out.println("-- put()");
// h.put("Bela#" + i, new Float(i));
// }
// while(true) {
// Util.sleep(500);
// System.out.println(h.get("Bela#1"));
// }
// }
// }.start();
}
public void windowActivated(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
public void windowClosing(WindowEvent e) {System.exit(0);}
public void windowDeactivated(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowOpened(WindowEvent e) {}
public void actionPerformed(ActionEvent e) {
String command=e.getActionCommand();
try {
if(command == "Get") {
String stock_name=stock_field.getText();
if(stock_name == null || stock_name.length() == 0) {
showMsg("Key is empty !");
return;
}
showMsg("Looking up value for " + stock_name + ':');
Float val=(Float)h.get(stock_name);
if(val != null) {
value_field.setText(val.toString());
clearMsg();
}
else {
value_field.setText("");
showMsg("Value for " + stock_name + " not found");
}
}
else if(command == "Set") {
String stock_name=stock_field.getText();
String stock_val=value_field.getText();
if(stock_name == null || stock_val == null || stock_name.length() == 0 ||
stock_val.length() == 0) {
showMsg("Both key and value have to be present to create a new entry");
return;
}
Float val=new Float(stock_val);
h.put(stock_name, val);
showMsg("Key " + stock_name + " set to " + val);
}
else if(command == "All") {
showAll();
}
else if(command == "Quit") {
setVisible(false);
System.exit(0);
}
else if(command == "Delete")
removeItem();
else
System.out.println("Unknown action");
}
catch(Exception ex) {
value_field.setText("");
showMsg(ex.toString());
}
}
public void entrySet(Object key, Object value) {showAll();}
public void entryRemoved(Object key) {showAll();}
public void viewChange(Vector joined, Vector left) {
System.out.println("New members: " + joined + ", left members: " + left);
}
public void contentsSet(Map m) {
System.out.println("new contents: " + m);
}
public void contentsCleared() {
System.out.println("contents cleared");
}
public static void main(String args[]) {
DistributedHashtableDemo client=new DistributedHashtableDemo();
ChannelFactory factory=new JChannelFactory();
String arg;
boolean persist=false;
// test for pbcast
/*
String props="UDP:" +
"PING(num_initial_members=2;timeout=3000):" +
"FD:" +
// "DISCARD(down=0.1):" + // this is for discarding of 10% of the up messages !
"pbcast.PBCAST(gossip_interval=5000;gc_lag=50):" +
"UNICAST:" +
"FRAG:" +
"pbcast.GMS:" +
"pbcast.STATE_TRANSFER";
*/
String props="UDP(mcast_addr=228.8.8.8;mcast_port=45566;ip_ttl=32;" +
"mcast_send_buf_size=150000;mcast_recv_buf_size=80000):" +
"PING(timeout=2000;num_initial_members=3):" +
"MERGE2(min_interval=5000;max_interval=10000):" +
"FD_SOCK:" +
"VERIFY_SUSPECT(timeout=1500):" +
"pbcast.NAKACK(gc_lag=50;retransmit_timeout=300,600,1200,2400,4800):" +
"UNICAST(timeout=5000):" +
"pbcast.STABLE(desired_avg_gossip=20000):" +
"FRAG(frag_size=4096;down_thread=false;up_thread=false):" +
"pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;" +
"shun=false;print_local_addr=true):" +
"pbcast.STATE_TRANSFER";
try {
for(int i=0; i < args.length; i++) {
arg=args[i];
if("-persist".equals(arg) && i+1<args.length) {
persist=true;
PersistenceFactory.getInstance().createManager(args[++i]);
continue;
}
if("-props".equals(arg)) {
props=args[++i];
continue;
}
help();
return;
}
}
catch(Exception e) {
help();
return;
}
try {
client.start(factory, props, persist);
}
catch(Throwable t) {
t.printStackTrace();
}
}
static void help() {
System.out.println("DistributedHashtableDemo [-help] [-persist] [-props <properties>]");
}
}