KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > ubik > rmi > server > ObjectTable


1 package org.sapia.ubik.rmi.server;
2
3 import java.rmi.NoSuchObjectException JavaDoc;
4 import java.rmi.server.Unreferenced JavaDoc;
5 import java.util.Collections JavaDoc;
6 import java.util.HashMap JavaDoc;
7 import java.util.Map JavaDoc;
8
9 import org.sapia.ubik.rmi.Consts;
10
11 /**
12  * A server-side class that performs reference counting and that is used
13  * in distributed garbage collection.
14  *
15  * @author Yanick Duchesne
16  * <dl>
17  * <dt><b>Copyright:</b><dd>Copyright &#169; 2002-2003 <a HREF="http://www.sapia-oss.org">Sapia Open Source Software</a>. All Rights Reserved.</dd></dt>
18  * <dt><b>License:</b><dd>Read the license.txt file of the jar or visit the
19  * <a HREF="http://www.sapia-oss.org/license.html">license page</a> at the Sapia OSS web site</dd></dt>
20  * </dl>
21  */

22 public class ObjectTable {
23   
24   static final float DEFAULT_LOAD_FACTOR = 0.75f;
25   static final int DEFAULT_INIT_CAPACITY = 2000;
26   
27   Map JavaDoc _refs;
28   
29   ObjectTable(){
30     float loadFactor = DEFAULT_LOAD_FACTOR;
31     int initCapacity = DEFAULT_INIT_CAPACITY;
32     String JavaDoc loadFactorProp = System.getProperty(Consts.OBJECT_TABLE_LOAD_FACTOR);
33     String JavaDoc initCapacityProp = System.getProperty(Consts.OBJECT_TABLE_INITCAPACITY);
34     if(loadFactorProp != null){
35       try{
36         loadFactor = Float.parseFloat(loadFactorProp);
37       }catch(NumberFormatException JavaDoc e){
38         Log.error(getClass(), "Invalid load factor: " + loadFactorProp + " - using: " + DEFAULT_LOAD_FACTOR);
39       }
40     }
41     if(initCapacityProp != null){
42       try{
43         initCapacity = Integer.parseInt(initCapacityProp);
44       }catch(NumberFormatException JavaDoc e){
45         Log.error(getClass(), "Invalid initial capacity: " + loadFactorProp + " - using: " + DEFAULT_INIT_CAPACITY);
46       }
47       
48     }
49     _refs = Collections.synchronizedMap(new HashMap JavaDoc(initCapacity, loadFactor));
50   }
51
52   /**
53    * Registers the given object (for which a stub will eventually be
54    * sent on the client side) with the given object identifier.
55    *
56    * @param oid the <code>OID</code> of the object passed in.
57    * @param o the object whose stub will be sent to the client.
58    */

59   public synchronized void register(OID oid, Object JavaDoc o) {
60     if (Log.isDebug()) {
61       Log.debug(ObjectTable.class, "registering: " + oid);
62     }
63
64     Ref ref = (Ref) _refs.get(oid);
65
66     if (ref == null) {
67       ref = new Ref(oid, o);
68       _refs.put(oid, ref);
69     }
70
71     ref.inc(); /* TO DO: REMOVE CLEAN OBJECTS */
72   }
73
74   /**
75    * Increases the reference count of the object whose identifier
76    * is passed as a parameter.
77    *
78    * @param oid the <code>OID</code> of the object whose reference count
79    * should be incremented.
80    */

81   public synchronized void reference(OID oid) {
82     if (Log.isDebug()) {
83       Log.debug(ObjectTable.class, "referencing to: " + oid);
84     }
85
86     Ref ref = (Ref) _refs.get(oid);
87
88     if (ref == null) {
89       if(Log.isDebug()){
90         Log.debug(getClass(), "No object reference for: " + oid);
91         Log.debug(getClass(), "Current objects: " + _refs);
92       }
93       throw new NullPointerException JavaDoc("no object reference for: " + oid);
94     }
95
96     ref.inc();
97   }
98
99   /**
100    * Decrements the reference count of the object whose identifier is given.
101    *
102    * @param oid the <code>OID</code> of an object whose reference count is
103    * to be decremented.
104    * @param decrement the value that should be substracted from the OID's reference count.
105    */

106   public synchronized void dereference(OID oid, int decrement) {
107     Ref ref = (Ref) _refs.get(oid);
108
109     if (ref != null) {
110       ref.dec(decrement);
111
112       if (ref.count() <= 0) {
113         if (Log.isDebug()) {
114           Log.debug(ObjectTable.class,
115             "dereferencing: " + oid + " - available for GC");
116         }
117
118         _refs.remove(oid);
119
120         if (ref._obj instanceof Unreferenced JavaDoc) {
121           ((Unreferenced JavaDoc) ref._obj).unreferenced();
122         }
123       }
124     }
125   }
126
127   /**
128    * Returns the object whose identifier is passed in.
129    *
130    * @param oid the identifier of the object to return
131    * @throws NoSuchObjectException if no object exists for the given identifier
132    */

133   public Object JavaDoc getObjectFor(OID oid) throws NoSuchObjectException JavaDoc {
134     Ref ref = (Ref) _refs.get(oid);
135
136     if ((ref != null) && (ref.count() > 0)) {
137       return ref.get();
138     } else {
139       if(Log.isDebug()){
140         Log.debug(getClass(), "No object reference for: " + oid);
141         Log.debug(getClass(), "Current objects: " + _refs);
142       }
143       throw new NullPointerException JavaDoc("no object reference for: " + oid);
144     }
145   }
146
147   /**
148    * Removes the given object from this instance.
149    *
150    * @return <code>true</code> if the given object was removed from this instance.
151    */

152   public boolean remove(Object JavaDoc o) {
153     Ref[] refs = (Ref[]) _refs.values().toArray(new Ref[_refs.size()]);
154     boolean removed = false;
155
156     for (int i = 0; i < refs.length; i++) {
157       if (refs[i]._obj.equals(o)) {
158         _refs.remove(refs[i]._oid);
159         removed = true;
160       }
161     }
162
163     return removed;
164   }
165
166   /**
167    * Removes all objects whose class was loaded by the given
168    * classloader.
169    *
170    * @param loader a <code>ClassLoader</code>.
171    *
172    * @return <code>true</code> if any objects were removed that correspond to the
173    * given classloader.
174    */

175   public boolean remove(ClassLoader JavaDoc loader) {
176     Ref[] refs = (Ref[]) _refs.values().toArray(new Ref[_refs.size()]);
177     boolean removed = false;
178
179     for (int i = 0; i < refs.length; i++) {
180       if (refs[i]._obj.getClass().getClassLoader().equals(loader)) {
181         _refs.remove(refs[i]._oid);
182
183         if (refs[i]._obj instanceof Unreferenced JavaDoc) {
184           ((Unreferenced JavaDoc) refs[i]._obj).unreferenced();
185         }
186
187         removed = true;
188       }
189     }
190
191     return removed;
192   }
193
194   /**
195    * Returns the reference count of the object whose identifier is given.
196    *
197    * @return the reference count of the object corresponding to the
198    * <code>OID</code> passed in.
199    */

200   public int getRefCount(OID oid) {
201     Ref ref = (Ref) _refs.get(oid);
202
203     if (ref == null) {
204       return 0;
205     } else {
206       return ref.count();
207     }
208   }
209
210   /**
211    * Decrements the reference count of the objects whose object identifiers are
212    * passed as a set.
213    *
214    * @param oids the <code>Collection</code> of <cod>OID</code>s whose corresponding
215    * objects should have their reference count decremented.
216    */

217
218   // public synchronized void dereference(Collection oids) {
219
// OID oid;
220
// Ref ref;
221
//
222
// for (Iterator iter = oids.iterator(); iter.hasNext();) {
223
// oid = (OID) iter.next();
224
// ref = (Ref) _refs.get(oid);
225
//
226
// if (ref != null) {
227
// ref.dec();
228
//
229
// if (ref.count() <= 0) {
230
// if (Log.isDebug()) {
231
// Log.debug(ObjectTable.class,
232
// "dereferencing: " + oid + " - available for GC");
233
// }
234
//
235
// _refs.remove(oid);
236
// }
237
// }
238
// }
239
// }
240
public synchronized void clear() {
241     _refs.clear();
242   }
243
244   public Map JavaDoc getRefs() {
245     return _refs;
246   }
247
248   public synchronized void clear(OID oid) {
249     Ref ref = (Ref) _refs.get(oid);
250
251     if (ref != null) {
252       ref._count = 0;
253     }
254   }
255
256   /*////////////////////////////////////////////////////////////////////
257                               INNER CLASSES
258   ////////////////////////////////////////////////////////////////////*/

259   protected static class Ref {
260     int _count;
261     Object JavaDoc _obj;
262     OID _oid;
263
264     Ref(OID oid, Object JavaDoc o) {
265       _obj = o;
266       _oid = oid;
267     }
268
269     void dec() {
270       _count--;
271     }
272
273     void dec(int count) {
274       _count = _count - count;
275
276       if (_count < 0) {
277         _count = 0;
278       }
279     }
280
281     void inc() {
282       _count++;
283     }
284
285     int count() {
286       return _count;
287     }
288
289     Object JavaDoc get() {
290       return _obj;
291     }
292   }
293 }
294
Popular Tags