KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > fr > dyade > aaa > agent > ServersHT


1 package fr.dyade.aaa.agent;
2
3 import java.util.Enumeration JavaDoc;
4 import java.util.NoSuchElementException JavaDoc;
5
6 /**
7  * This class implements a ServerDesc hashtable, which uses sid as keys.
8  */

9 public class ServersHT {
10   /** The hash table data. */
11   private transient ServerDescEntry table[];
12   /** The total number of entries in the hash table. */
13   private transient int count;
14                              
15   /** The default initial capacity for the hashtable: 13. */
16   private static final int initialCapacity = 13;
17   /** The default load factor for the hashtable: 0.75f. */
18   private static final float loadFactor = 0.75f;
19   /** The table is rehashed each time its size exceeds this threshold. */
20   private int threshold;
21
22   /** The number of times this Hashtable has been modified. */
23   private transient int modCount = 0;
24
25   /**
26    * Constructs a new, empty hashtable with the default initial
27    * capacity and load factor.
28    */

29   public ServersHT() {
30     table = new ServerDescEntry[initialCapacity];
31     threshold = (int)(initialCapacity * loadFactor);
32   }
33
34   /**
35    * Returns the number of entries in this hashtable.
36    *
37    * @return the number of entries in this hashtable.
38    */

39   public synchronized int size() {
40     return count;
41   }
42
43   /**
44    * Returns an enumeration of the keys (server id.) in this hashtable.
45    *
46    * @return an enumeration of the keys in this hashtable.
47    * @see Enumeration
48    */

49   public synchronized Enumeration JavaDoc keys() {
50     return new Enumerator(KEYS);
51   }
52
53   /**
54    * Returns an enumeration of the server descriptors in this hashtable.
55    * Use the Enumeration methods on the returned object to fetch the elements
56    * sequentially.
57    *
58    * @return an enumeration of the values in this hashtable.
59    * @see java.util.Enumeration
60    */

61   public synchronized Enumeration JavaDoc elements() {
62     return new Enumerator(VALUES);
63   }
64
65   /**
66    * Returns the descriptor of the corresponding server.
67    *
68    * @param sid The server unique identification.
69    * @return the descriptor of the corresponding server.
70    */

71   public synchronized ServerDesc get(short sid) {
72     ServerDescEntry tab[] = table;
73     int index = (sid & 0x7FFF) % tab.length;
74     for (ServerDescEntry e = tab[index] ; e != null ; e = e.next) {
75       if (e.desc.sid == sid) return e.desc;
76     }
77     return null;
78   }
79
80   /**
81    * Increases the capacity of and internally reorganizes this
82    * hashtable, in order to accommodate and access its entries more
83    * efficiently. This method is called automatically when the
84    * number of keys in the hashtable exceeds this hashtable's capacity
85    * and load factor.
86    */

87   protected void rehash() {
88     int oldCapacity = table.length;
89     ServerDescEntry oldMap[] = table;
90
91     int newCapacity = oldCapacity * 2 + 1;
92     ServerDescEntry newMap[] = new ServerDescEntry[newCapacity];
93
94     modCount++;
95     threshold = (int)(newCapacity * loadFactor);
96     table = newMap;
97
98     for (int i = oldCapacity ; i-- > 0 ;) {
99       for (ServerDescEntry old = oldMap[i] ; old != null ; ) {
100         ServerDescEntry e = old;
101         old = old.next;
102
103         int index = (e.desc.sid & 0x7FFFFFFF) % newCapacity;
104         e.next = newMap[index];
105         newMap[index] = e;
106       }
107     }
108   }
109
110   /**
111    * Maps the specified <code>desc</code> in this hashtable.
112    * The descriptor can be retrieved by calling the <code>get</code>
113    * method with a key that is equal to the server id.
114    *
115    * @param desc the descriptor.
116    * @return the previous value of the descriptor, or <code>null</code>
117    * if it did not have one.
118    * @exception NullPointerException if the descriptor is <code>null</code>.
119    */

120   public synchronized ServerDesc put(ServerDesc desc) {
121     // Make sure the value is not null
122
if (desc == null) throw new NullPointerException JavaDoc();
123
124     // Makes sure the key is not already in the hashtable.
125
ServerDescEntry tab[] = table;
126     int index = (desc.sid & 0x7FFF) % tab.length;
127     for (ServerDescEntry e = tab[index] ; e != null ; e = e.next) {
128       if (e.desc.sid == desc.sid) {
129         ServerDesc old = e.desc;
130         e.desc = desc;
131         return old;
132       }
133     }
134
135     modCount++;
136     if (count >= threshold) {
137       // Rehash the table if the threshold is exceeded
138
rehash();
139
140       tab = table;
141       index = (desc.sid & 0x7FFF) % tab.length;
142     }
143
144     // Creates the new entry.
145
ServerDescEntry e = new ServerDescEntry(desc, tab[index]);
146     tab[index] = e;
147     count++;
148     return null;
149   }
150
151   /**
152    * Removes the descriptor from this hashtable.
153    * This method does nothing if the key is not in the hashtable.
154    *
155    * @param sid the id of server that needs to be removed.
156    * @return the descriptor of the server or <code>null</code> if
157    * it is not defined.
158    */

159   public synchronized ServerDesc remove(short sid) {
160     ServerDescEntry tab[] = table;
161     int index = (sid & 0x7FFF) % tab.length;
162     for (ServerDescEntry e = tab[index], prev = null ; e != null ; prev = e, e = e.next) {
163       if (e.desc.sid == sid) {
164         modCount++;
165         if (prev != null) {
166           prev.next = e.next;
167         } else {
168           tab[index] = e.next;
169         }
170         count--;
171         ServerDesc oldDesc = e.desc;
172         e.desc = null;
173         return oldDesc;
174       }
175     }
176     return null;
177   }
178
179   /**
180    * Clears this hashtable so that it contains no descriptors.
181    */

182   public synchronized void clear() {
183     ServerDescEntry tab[] = table;
184     modCount++;
185     for (int index = tab.length; --index >= 0; )
186       tab[index] = null;
187     count = 0;
188   }
189
190   /**
191    * Returns a string representation of this <tt>Hashtable</tt> object.
192    *
193    * @return a string representation of this hashtable.
194    */

195   public synchronized String JavaDoc toString() {
196     int max = size() - 1;
197     StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
198
199     buf.append("(").append(super.toString());
200 // for (int i = 0; i <= max; i++) {
201
// Map.Entry e = (Map.Entry) (it.next());
202
// Object key = e.getKey();
203
// Object value = e.getValue();
204
// buf.append((key == this ? "(this Map)" : key) + "=" +
205
// (value == this ? "(this Map)" : value));
206

207 // if (i < max)
208
// buf.append(", ");
209
// }
210
buf.append(")");
211     return buf.toString();
212   }
213
214   /**
215    * Hashtable collision list.
216    */

217   private static final class ServerDescEntry {
218     ServerDesc desc;
219     ServerDescEntry next;
220
221     protected ServerDescEntry(ServerDesc desc, ServerDescEntry next) {
222       this.desc = desc;
223       this.next = next;
224     }
225
226     public String JavaDoc toString() {
227       return desc.toString();
228     }
229   }
230
231   // Types of Enumerations/Iterations
232
private static final int KEYS = 0;
233   private static final int VALUES = 1;
234
235   /**
236    * A hashtable enumerator class. This class implements both the
237    * Enumeration and Iterator interfaces, but individual instances
238    * can be created with the Iterator methods disabled. This is necessary
239    * to avoid unintentionally increasing the capabilities granted a user
240    * by passing an Enumeration.
241    */

242   private class Enumerator implements Enumeration JavaDoc {
243     ServerDescEntry[] table = ServersHT.this.table;
244     int index = table.length;
245     ServerDescEntry entry = null;
246     ServerDescEntry lastReturned = null;
247     int type;
248
249     /**
250      * The modCount value that the iterator believes that the backing
251      * List should have. If this expectation is violated, the iterator
252      * has detected concurrent modification.
253      */

254     protected int expectedModCount = modCount;
255
256     Enumerator(int type) {
257       this.type = type;
258     }
259
260     public boolean hasMoreElements() {
261       ServerDescEntry e = entry;
262       int i = index;
263       ServerDescEntry t[] = table;
264       /* Use locals for faster loop iteration */
265       while (e == null && i > 0) {
266         e = t[--i];
267       }
268       entry = e;
269       index = i;
270       return e != null;
271     }
272
273     public Object JavaDoc nextElement() {
274       ServerDescEntry et = entry;
275       int i = index;
276       ServerDescEntry t[] = table;
277       /* Use locals for faster loop iteration */
278       while (et == null && i > 0) {
279         et = t[--i];
280       }
281       entry = et;
282       index = i;
283       if (et != null) {
284         ServerDescEntry e = lastReturned = entry;
285         entry = e.next;
286         return (type == KEYS)?((Object JavaDoc) new Short JavaDoc(e.desc.sid)):((Object JavaDoc) e.desc);
287       }
288       throw new NoSuchElementException JavaDoc("ServersHT Enumerator");
289     }
290   }
291
292 }
293
Popular Tags