001: // $Id: DISCARD.java,v 1.10 2005/08/24 13:12:04 belaban Exp $
002:
003: package org.jgroups.protocols;
004:
005: import org.jgroups.Address;
006: import org.jgroups.Event;
007: import org.jgroups.Message;
008: import org.jgroups.stack.Protocol;
009:
010: import java.util.Properties;
011: import java.util.Vector;
012: import java.util.Map;
013: import java.util.HashMap;
014:
015: /**
016: * Discards up or down messages based on a percentage; e.g., setting property 'up' to 0.1 causes 10%
017: * of all up messages to be discarded. Setting 'down' or 'up' to 0 causes no loss, whereas 1 discards
018: * all messages (not very useful).
019: */
020:
021: public class DISCARD extends Protocol {
022: final Vector members = new Vector();
023: double up = 0.0; // probability of dropping up msgs
024: double down = 0.0; // probability of dropping down msgs
025: boolean excludeItself = false; //if true don't discard messages sent/received in this stack
026: Address localAddress;
027: int num_down = 0, num_up = 0;
028:
029: /**
030: * All protocol names have to be unique !
031: */
032: public String getName() {
033: return "DISCARD";
034: }
035:
036: public boolean setProperties(Properties props) {
037: String str;
038:
039: super .setProperties(props);
040: str = props.getProperty("up");
041: if (str != null) {
042: up = Double.parseDouble(str);
043: props.remove("up");
044: }
045:
046: str = props.getProperty("down");
047: if (str != null) {
048: down = Double.parseDouble(str);
049: props.remove("down");
050: }
051:
052: str = props.getProperty("excludeitself");
053: if (str != null) {
054: excludeItself = Boolean.valueOf(str).booleanValue();
055: props.remove("excludeitself");
056: }
057:
058: if (props.size() > 0) {
059: log
060: .error("DISCARD.setProperties(): these properties are not recognized: "
061: + props);
062:
063: return false;
064: }
065: return true;
066: }
067:
068: public void up(Event evt) {
069: Message msg;
070: double r;
071:
072: if (evt.getType() == Event.SET_LOCAL_ADDRESS)
073: localAddress = (Address) evt.getArg();
074:
075: if (evt.getType() == Event.MSG) {
076: msg = (Message) evt.getArg();
077: if (up > 0) {
078: r = Math.random();
079: if (r < up) {
080: if (excludeItself
081: && msg.getSrc().equals(localAddress)) {
082: if (log.isTraceEnabled())
083: log.trace("excluding itself");
084: } else {
085: if (log.isTraceEnabled())
086: log.trace("dropping message");
087: num_up++;
088: return;
089: }
090: }
091: }
092: }
093:
094: passUp(evt);
095: }
096:
097: public void down(Event evt) {
098: Message msg;
099: double r;
100:
101: if (evt.getType() == Event.MSG) {
102: msg = (Message) evt.getArg();
103:
104: if (down > 0) {
105: r = Math.random();
106: if (r < down) {
107: if (excludeItself
108: && msg.getSrc().equals(localAddress)) {
109: if (log.isTraceEnabled())
110: log.trace("excluding itself");
111: } else {
112: if (log.isTraceEnabled())
113: log.trace("dropping message");
114: num_down++;
115: return;
116: }
117: }
118: }
119:
120: }
121: passDown(evt);
122: }
123:
124: public void resetStats() {
125: super .resetStats();
126: num_down = num_up = 0;
127: }
128:
129: public Map dumpStats() {
130: Map m = new HashMap(2);
131: m.put("num_dropped_down", new Integer(num_down));
132: m.put("num_dropped_up", new Integer(num_up));
133: return m;
134: }
135: }
|