KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jgroups > util > MutableDigest


1 package org.jgroups.util;
2
3 import org.jgroups.Address;
4
5 import java.util.Iterator JavaDoc;
6 import java.util.Map JavaDoc;
7
8 /**
9  * A mutable version of Digest (which is immutable
10  * @author Bela Ban
11  * @version $Id: MutableDigest.java,v 1.6 2007/05/29 10:10:47 belaban Exp $
12  */

13 public class MutableDigest extends Digest {
14     private boolean sealed=false;
15
16     /** Used for externalization */
17     public MutableDigest() {
18         super();
19     }
20
21     public MutableDigest(int size) {
22         super(size);
23     }
24
25
26     public MutableDigest(Map JavaDoc<Address,Entry> map) {
27         super(map);
28     }
29
30
31     public MutableDigest(Digest digest) {
32         super(digest.getSenders());
33     }
34
35
36     public Map JavaDoc<Address, Entry> getSenders() {
37         return senders;
38     }
39
40     public void add(Address sender, long low_seqno, long highest_delivered_seqno) {
41         checkSealed();
42         add(sender, low_seqno, highest_delivered_seqno, -1);
43     }
44
45
46     public void add(Address sender, long low_seqno, long highest_delivered_seqno, long highest_received_seqno) {
47         checkSealed();
48         add(sender, new Digest.Entry(low_seqno, highest_delivered_seqno, highest_received_seqno));
49     }
50
51     private void add(Address sender, Entry entry) {
52         if(sender == null || entry == null) {
53             if(log.isErrorEnabled())
54                 log.error("sender (" + sender + ") or entry (" + entry + ")is null, will not add entry");
55             return;
56         }
57         checkSealed();
58         Object JavaDoc retval=senders.put(sender, entry);
59         if(retval != null && log.isWarnEnabled())
60             log.warn("entry for " + sender + " was overwritten with " + entry);
61     }
62
63
64     public void add(Digest digest) {
65         if(digest != null) {
66             checkSealed();
67             Map.Entry JavaDoc<Address,Entry> entry;
68             Address key;
69             Entry val;
70             for(Iterator JavaDoc<Map.Entry JavaDoc<Address,Entry>> it=digest.senders.entrySet().iterator(); it.hasNext();) {
71                 entry=it.next();
72                 key=entry.getKey();
73                 val=entry.getValue();
74                 add(key, val.getLow(), val.getHighestDeliveredSeqno(), val.getHighestReceivedSeqno());
75             }
76         }
77     }
78
79     public void replace(Digest d) {
80         if(d != null) {
81             clear();
82             add(d);
83         }
84     }
85
86     public boolean set(Address sender, long low_seqno, long highest_delivered_seqno, long highest_received_seqno) {
87         checkSealed();
88         Entry entry=senders.put(sender, new Entry(low_seqno, highest_delivered_seqno, highest_received_seqno));
89         return entry == null;
90     }
91
92     /**
93      * Adds a digest to this digest. This digest must have enough space to add the other digest; otherwise an error
94      * message will be written. For each sender in the other digest, the merge() method will be called.
95      */

96     public void merge(Digest digest) {
97         if(digest == null) {
98             if(log.isErrorEnabled()) log.error("digest to be merged with is null");
99             return;
100         }
101         checkSealed();
102         Map.Entry JavaDoc<Address,Entry> entry;
103         Address sender;
104         Entry val;
105         for(Iterator JavaDoc<Map.Entry JavaDoc<Address,Entry>> it=digest.senders.entrySet().iterator(); it.hasNext();) {
106             entry=it.next();
107             sender=entry.getKey();
108             val=entry.getValue();
109             if(val != null) {
110                 merge(sender, val.getLow(), val.getHighestDeliveredSeqno(), val.getHighestReceivedSeqno());
111             }
112         }
113     }
114
115
116     /**
117      * Similar to add(), but if the sender already exists, its seqnos will be modified (no new entry) as follows:
118      * <ol>
119      * <li>this.low_seqno=min(this.low_seqno, low_seqno)
120      * <li>this.highest_delivered_seqno=max(this.highest_delivered_seqno, highest_delivered_seqno)
121      * <li>this.highest_received_seqno=max(this.highest_received_seqno, highest_received_seqno)
122      * </ol>
123      * If the sender doesn not exist, a new entry will be added (provided there is enough space)
124      */

125     public void merge(Address sender, long low_seqno, long highest_delivered_seqno, long highest_received_seqno) {
126         if(sender == null) {
127             if(log.isErrorEnabled()) log.error("sender == null");
128             return;
129         }
130         checkSealed();
131         Entry entry=senders.get(sender);
132         if(entry == null) {
133             add(sender, low_seqno, highest_delivered_seqno, highest_received_seqno);
134         }
135         else {
136             Entry new_entry=new Entry(Math.min(entry.getLow(), low_seqno),
137                                       Math.max(entry.getHighestDeliveredSeqno(), highest_delivered_seqno),
138                                       Math.max(entry.getHighestReceivedSeqno(), highest_received_seqno));
139             senders.put(sender, new_entry);
140         }
141     }
142
143
144
145     /**
146      * Increments the sender's high_seqno by 1.
147      */

148     public void incrementHighestDeliveredSeqno(Address sender) {
149         Entry entry=senders.get(sender);
150         if(entry == null)
151             return;
152         checkSealed();
153         Entry new_entry=new Entry(entry.getLow(), entry.getHighestDeliveredSeqno() +1, entry.getHighestReceivedSeqno());
154         senders.put(sender, new_entry);
155     }
156
157
158     /**
159      * Resets the seqnos for the sender at 'index' to 0. This happens when a member has left the group,
160      * but it is still in the digest. Resetting its seqnos ensures that no-one will request a message
161      * retransmission from the dead member.
162      */

163     public void resetAt(Address sender) {
164         Entry entry=senders.get(sender);
165         if(entry != null)
166             checkSealed();
167             senders.put(sender, new Entry());
168     }
169
170
171     public void clear() {
172         checkSealed();
173         senders.clear();
174     }
175
176
177
178     public void setHighestDeliveredAndSeenSeqnos(Address sender, long low_seqno, long highest_delivered_seqno, long highest_received_seqno) {
179         Entry entry=senders.get(sender);
180         if(entry != null) {
181             checkSealed();
182             Entry new_entry=new Entry(low_seqno, highest_delivered_seqno, highest_received_seqno);
183             senders.put(sender, new_entry);
184         }
185     }
186
187     /** Seals the instance against modifications */
188     public boolean seal() {
189         boolean retval=sealed;
190         sealed=true;
191         return retval;
192     }
193
194
195     private final void checkSealed() {
196         if(sealed)
197             throw new IllegalAccessError JavaDoc("instance has been sealed and cannot be modified");
198     }
199
200 }
201
Popular Tags