001: // $Id: AckMcastReceiverWindow.java,v 1.8 2006/05/16 11:14:28 belaban Exp $
002:
003: package org.jgroups.stack;
004:
005: import org.apache.commons.logging.Log;
006: import org.apache.commons.logging.LogFactory;
007: import org.jgroups.Address;
008:
009: import java.util.Enumeration;
010: import java.util.Hashtable;
011: import java.util.Vector;
012: import java.net.UnknownHostException;
013:
014: /**
015: * Keeps track of messages received from various senders. Acks each message received and checks whether
016: * it was already delivered. If yes, the message is discarded, otherwise it is delivered (passed up).
017: * The messages contain sequence numbers of old messages to be deleted, those are removed from the
018: * message table.
019: *
020: * @author Bela Ban June 17 1999
021: */
022: public class AckMcastReceiverWindow {
023: final Hashtable msgs = new Hashtable(); // sender -- Vector (of seqnos)
024:
025: protected static final Log log = LogFactory
026: .getLog(AckMcastReceiverWindow.class);
027:
028: /**
029: Records the sender/seqno pair in the message table
030: @param sender The sender of the message
031: @param seqno The sequence number associated with the message
032: @return boolean If false, message is already present. Otherwise true.
033: */
034: public boolean add(Object sender, long seqno) {
035: Vector seqnos = (Vector) msgs.get(sender);
036: Long val = new Long(seqno);
037:
038: if (seqnos == null) {
039: seqnos = new Vector();
040: seqnos.addElement(val);
041: msgs.put(sender, seqnos);
042: return true;
043: }
044:
045: if (seqnos.contains(val))
046: return false;
047:
048: seqnos.addElement(val);
049: return true;
050: }
051:
052: public void remove(Object sender, Vector seqnos) {
053: Vector v = (Vector) msgs.get(sender);
054: Long seqno;
055:
056: if (v != null && seqnos != null) {
057: for (int i = 0; i < seqnos.size(); i++) {
058: seqno = (Long) seqnos.elementAt(i);
059: v.removeElement(seqno);
060: }
061: }
062: }
063:
064: public long size() {
065: long ret = 0;
066:
067: for (Enumeration e = msgs.elements(); e.hasMoreElements();) {
068: ret += ((Vector) e.nextElement()).size();
069: }
070:
071: return ret;
072: }
073:
074: public void reset() {
075: removeAll();
076: }
077:
078: public void removeAll() {
079: msgs.clear();
080: }
081:
082: public void suspect(Object sender) {
083:
084: if (log.isInfoEnabled())
085: log.info("suspect is " + sender);
086: msgs.remove(sender);
087: }
088:
089: public String toString() {
090: StringBuffer ret = new StringBuffer();
091: Object sender;
092:
093: for (Enumeration e = msgs.keys(); e.hasMoreElements();) {
094: sender = e.nextElement();
095: ret.append(sender).append(" --> ").append(msgs.get(sender))
096: .append('\n');
097: }
098: return ret.toString();
099: }
100:
101: public static void main(String[] args) throws UnknownHostException {
102: AckMcastReceiverWindow win = new AckMcastReceiverWindow();
103: Address sender1 = new IpAddress("janet", 1111);
104: Address sender2 = new IpAddress("janet", 4444);
105: Address sender3 = new IpAddress("janet", 6767);
106: Address sender4 = new IpAddress("janet", 3333);
107:
108: win.add(sender1, 1);
109: win.add(sender1, 2);
110:
111: win.add(sender3, 2);
112: win.add(sender2, 2);
113: win.add(sender4, 2);
114: win.add(sender1, 3);
115: win.add(sender1, 2);
116:
117: System.out.println(win);
118:
119: win.suspect(sender1);
120: System.out.println(win);
121:
122: win.add(sender1, 1);
123: win.add(sender1, 2);
124: win.add(sender1, 3);
125: win.add(sender1, 4);
126: win.add(sender1, 5);
127: win.add(sender1, 6);
128: win.add(sender1, 7);
129: win.add(sender1, 8);
130:
131: System.out.println(win);
132:
133: Vector seqnos = new Vector();
134:
135: seqnos.addElement(new Long(4));
136: seqnos.addElement(new Long(6));
137: seqnos.addElement(new Long(8));
138:
139: win.remove(sender2, seqnos);
140: System.out.println(win);
141:
142: win.remove(sender1, seqnos);
143: System.out.println(win);
144:
145: }
146:
147: }
|