1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package jgroup.relacs.daemon;
20
21 import java.util.Collection;
22 import java.util.HashSet;
23 import java.util.Iterator;
24 import java.util.Map;
25 import java.util.Set;
26 import java.util.SortedMap;
27 import java.util.TreeMap;
28
29 import jgroup.core.EndPoint;
30
31 import org.apache.log4j.Logger;
32
33
34
35
36
37
38
39 final class Estimate
40 {
41
42
43
44
45
46
47 private static final Logger log = Logger.getLogger(Estimate.class);
48
49
50
51
52
53
54
55 private final SortedMap<EndPoint,HostData> estimate = new TreeMap<EndPoint,HostData>();
56
57
58 private final Set<EndPoint> toSynchronize = new HashSet<EndPoint>();
59
60
61 private boolean changed;
62
63
64 private final SendBuffer sbuffer;
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 Estimate(SendBuffer sbuffer, Map thosts, EndPoint[] rset)
81 {
82
83 this.sbuffer = sbuffer;
84 initEstimate(thosts, rset);
85 }
86
87
88 void reset(Map thosts, EndPoint[] rset)
89 {
90 estimate.clear();
91 toSynchronize.clear();
92 initEstimate(thosts, rset);
93 }
94
95
96 private void initEstimate(Map thosts, EndPoint[] rset)
97 {
98
99 for (int i=0; i < rset.length; i++) {
100 if (log.isDebugEnabled())
101 log.debug("rset[" +i+ "]: " +rset[i]);
102 HostData host = (HostData) thosts.get(rset[i]);
103 if (host == null) {
104
105
106
107
108
109 continue;
110 }
111 if (!host.isLeaving()) {
112 estimate.put(rset[i], host);
113 if (!host.getHost().isLocal())
114 toSynchronize.add(rset[i]);
115 } else {
116 sbuffer.suspect(host);
117 }
118 }
119
120 if (log.isDebugEnabled())
121 log.debug(toString());
122 }
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137 boolean checkAgreed(EndPoint[] endpoints, int[] agreed)
138 {
139 for (int i=0; i < endpoints.length; i++) {
140 HostData host = estimate.get(endpoints[i]);
141 if (host != null && host.getAgreed() != agreed[i]) {
142 if (log.isDebugEnabled())
143 log.debug(endpoints[i] + ": local agreed=" + host.getAgreed() + ", remote agreed=" + agreed[i]);
144 return false;
145 }
146 }
147 return true;
148 }
149
150
151
152
153
154
155
156
157 void updateAgreed(EndPoint[] hosts, int[] agreed)
158 {
159 if (agreed != null) {
160 for (int i = 0; i < hosts.length; i++) {
161 HostData host = estimate.get(hosts[i]);
162 if (host != null)
163 host.setAgreed(agreed[i]);
164 }
165 }
166 }
167
168
169
170
171
172
173
174
175
176 void intersect(EndPoint[] hosts)
177 {
178
179 Set<EndPoint> toRemove = new HashSet<EndPoint>(estimate.keySet());
180 for (EndPoint host : hosts)
181 toRemove.remove(host);
182
183
184 for (EndPoint endpoint : toRemove) {
185 changed = true;
186 sbuffer.suspect(estimate.get(endpoint));
187 estimate.remove(endpoint);
188 toSynchronize.remove(endpoint);
189 }
190 }
191
192
193
194
195
196
197
198
199
200 void remove(EndPoint endpoint)
201 {
202
203 HostData host = estimate.remove(endpoint);
204 if (host != null) {
205 toSynchronize.remove(endpoint);
206 sbuffer.suspect(host);
207 changed = true;
208 }
209 }
210
211
212
213
214
215
216
217
218
219 void remove(EndPoint[] set)
220 {
221 for (int i=0; i < set.length; i++)
222 remove(set[i]);
223 }
224
225
226
227
228
229
230
231
232 boolean contains(EndPoint endpoint)
233 {
234 return estimate.containsKey(endpoint);
235 }
236
237
238
239
240
241 HostData get(EndPoint endpoint)
242 {
243 return estimate.get(endpoint);
244 }
245
246
247
248
249
250 Collection<HostData> getHosts()
251 {
252 return estimate.values();
253 }
254
255
256
257
258 EndPoint[] getEndPoints()
259 {
260 return estimate.keySet().toArray(new EndPoint[estimate.size()]);
261 }
262
263
264
265
266 int size()
267 {
268 return estimate.size();
269 }
270
271
272
273
274 boolean isEmpty()
275 {
276 return estimate.isEmpty();
277 }
278
279
280
281
282 public boolean equals(Object o)
283 {
284 if (o instanceof Estimate) {
285 Estimate e = (Estimate) o;
286 return (e.estimate.equals(this.estimate) && e.toSynchronize.equals(this.toSynchronize));
287 }
288 return false;
289 }
290
291
292
293
294 void setSynchronized(EndPoint endpoint)
295 {
296 toSynchronize.remove(endpoint);
297 }
298
299
300
301
302 boolean isSynchronized()
303 {
304 return toSynchronize.size() == 0;
305 }
306
307
308
309
310 boolean hasChanged()
311 {
312 boolean ret = changed;
313 changed = false;
314 return ret;
315 }
316
317
318
319
320 EndPoint getCoordinator()
321 {
322 if (estimate.isEmpty()) {
323 log.warn("Estimate is empty: " + estimate);
324 return null;
325 }
326 return (EndPoint) estimate.firstKey();
327 }
328
329
330
331
332
333 public String toString()
334 {
335 StringBuilder buf = new StringBuilder();
336 buf.append("[Estimate: size=");
337 buf.append(estimate.size());
338 buf.append(", comp={");
339 for (Iterator<EndPoint> iter = estimate.keySet().iterator(); iter.hasNext();) {
340 EndPoint endpoint = iter.next();
341 buf.append(endpoint);
342 if (iter.hasNext())
343 buf.append(", ");
344 }
345 buf.append("}");
346 buf.append(", toSynchronize=");
347 buf.append(toSynchronize);
348 buf.append("]");
349 return buf.toString();
350 }
351
352 }