KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > triactive > jdo > util > ReferenceValueMap


1 /*
2  * Copyright 2002 (C) TJDO.
3  * All rights reserved.
4  *
5  * This software is distributed under the terms of the TJDO License version 1.0.
6  * See the terms of the TJDO License in the documentation provided with this software.
7  *
8  * $Id: ReferenceValueMap.java,v 1.4 2002/11/08 05:06:27 jackknifebarber Exp $
9  */

10
11 package com.triactive.jdo.util;
12
13 import java.lang.ref.Reference JavaDoc;
14 import java.lang.ref.ReferenceQueue JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.Map JavaDoc;
18 import java.util.HashMap JavaDoc;
19 import java.util.Set JavaDoc;
20 import java.util.Collection JavaDoc;
21 import java.util.Collections JavaDoc;
22 import org.apache.log4j.Category;
23
24
25 /**
26  * A <code>java.util.Map</code> implementation using reference values.
27  *
28  * <p>The values are stored in the map as references. If the garbage collector
29  * clears the reference, the corresponding key is automatically removed from the
30  * map.
31  *
32  * @author <a HREF="mailto:mmartin5@austin.rr.com">Mike Martin</a>
33  * @version $Revision: 1.4 $
34  *
35  * @see java.lang.ref.Reference
36  */

37
38 public abstract class ReferenceValueMap implements Map JavaDoc, Cloneable JavaDoc
39 {
40     private static final Category LOG = Category.getInstance(ReferenceValueMap.class);
41
42     private HashMap JavaDoc map;
43     private ReferenceQueue JavaDoc reaped = new ReferenceQueue JavaDoc();
44     private long lastLogTime = 0;
45     private int hits = 0;
46     private int misses = 0;
47     private int cleared = 0;
48
49
50     public ReferenceValueMap()
51     {
52         map = new HashMap JavaDoc();
53     }
54
55
56     public ReferenceValueMap(int initialCapacity)
57     {
58         map = new HashMap JavaDoc(initialCapacity);
59     }
60
61
62     public ReferenceValueMap(int initialCapacity, float loadFactor)
63     {
64         map = new HashMap JavaDoc(initialCapacity, loadFactor);
65     }
66
67
68     public ReferenceValueMap(Map JavaDoc m)
69     {
70         map = new HashMap JavaDoc();
71         putAll(m);
72     }
73
74
75     public Object JavaDoc clone()
76     {
77         reap();
78
79         ReferenceValueMap rvm = null;
80         
81         try { rvm = (ReferenceValueMap)super.clone(); } catch (CloneNotSupportedException JavaDoc e) {}
82
83         rvm.map = (HashMap JavaDoc)map.clone(); /* to preserve initialCapacity, loadFactor */
84         rvm.map.clear();
85         rvm.reaped = new ReferenceQueue JavaDoc();
86         rvm.putAll(entrySet());
87
88         return rvm;
89     }
90
91
92     /**
93      * References returned by <code>newValueReference</code> must implement
94      * this interface to provide the corresponding map key for the value.
95      */

96
97     public interface ValueReference
98     {
99         /**
100          * Returns the key associated with the value referenced by this
101          * <code>Reference</code> object.
102          */

103
104         Object JavaDoc getKey();
105     }
106
107
108     /**
109      * Returns a new <code>Reference</code> object to be inserted into the map.
110      * Subclasses must implement this method to construct <code>Reference</code>
111      * objects of the desired type (e.g. <code>SoftReference</code>, etc.).
112      *
113      * @param key The key that will be inserted.
114      * @param value The associated value to be referenced.
115      * @param queue The <code>ReferenceQueue</code> with which to register the
116      * new <code>Reference</code> object.
117      */

118
119     protected abstract ValueReference newValueReference(Object JavaDoc key, Object JavaDoc value, ReferenceQueue JavaDoc queue);
120
121
122     public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value)
123     {
124         reap();
125         return map.put(key, newValueReference(key, value, reaped));
126     }
127
128     public void putAll(Map JavaDoc m)
129     {
130         putAll(m.entrySet());
131     }
132
133     private void putAll(Set JavaDoc entrySet)
134     {
135         Iterator JavaDoc i = entrySet.iterator();
136
137         while (i.hasNext())
138         {
139             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)i.next();
140             put(entry.getKey(), entry.getValue());
141         }
142     }
143
144     public Object JavaDoc get(Object JavaDoc key)
145     {
146         reap();
147         Reference JavaDoc ref = (Reference JavaDoc)map.get(key);
148
149         Object JavaDoc value = ref == null ? null : ref.get();
150
151         if (value == null)
152             ++misses;
153         else
154             ++hits;
155
156         if (LOG.isDebugEnabled())
157         {
158             if ((System.currentTimeMillis() - lastLogTime) > 1000)
159             {
160                 LOG.debug(getClass().getName() + "(" + System.identityHashCode(this) + ") size = " + size() + ", hits = " + hits + ", misses = " + misses + ", cleared = " + cleared);
161                 lastLogTime = System.currentTimeMillis();
162             }
163         }
164
165         return value;
166     }
167
168     public void clear()
169     {
170         reap();
171         map.clear();
172     }
173
174     public int size()
175     {
176         reap();
177         return map.size();
178     }
179
180     public boolean containsKey(Object JavaDoc obj)
181     {
182         reap();
183         return map.containsKey(obj);
184     }
185
186     public boolean containsValue(Object JavaDoc obj)
187     {
188         reap();
189
190         if (obj != null)
191         {
192             Iterator JavaDoc i = map.values().iterator();
193
194             while (i.hasNext())
195             {
196                 Reference JavaDoc ref = (Reference JavaDoc)i.next();
197
198                 if (obj.equals(ref.get()))
199                     return true;
200             }
201         }
202
203         return false;
204     }
205
206     public boolean isEmpty()
207     {
208         reap();
209         return map.isEmpty();
210     }
211
212     public Set JavaDoc keySet()
213     {
214         reap();
215         return map.keySet();
216     }
217
218     public Collection JavaDoc values()
219     {
220         reap();
221
222         Collection JavaDoc c = map.values();
223         Iterator JavaDoc i = c.iterator();
224         ArrayList JavaDoc l = new ArrayList JavaDoc(c.size());
225
226         while (i.hasNext())
227         {
228             Reference JavaDoc ref = (Reference JavaDoc)i.next();
229             Object JavaDoc obj = ref.get();
230
231             if (obj != null)
232                 l.add(obj);
233         }
234
235         return Collections.unmodifiableList(l);
236     }
237
238     public Set JavaDoc entrySet()
239     {
240         reap();
241
242         Set JavaDoc s = map.entrySet();
243         Iterator JavaDoc i = s.iterator();
244         HashMap JavaDoc m = new HashMap JavaDoc(s.size());
245
246         while (i.hasNext())
247         {
248             Map.Entry JavaDoc entry = (Map.Entry JavaDoc)i.next();
249             Reference JavaDoc ref = (Reference JavaDoc)entry.getValue();
250             Object JavaDoc obj = ref.get();
251
252             if (obj != null)
253                 m.put(entry.getKey(), obj);
254         }
255
256         return Collections.unmodifiableSet(m.entrySet());
257     }
258
259     public Object JavaDoc remove(Object JavaDoc key)
260     {
261         reap();
262         return map.remove(key);
263     }
264
265     public int hashCode()
266     {
267         reap();
268         return map.hashCode();
269     }
270
271     public boolean equals(Object JavaDoc o)
272     {
273         reap();
274         return map.equals(o);
275     }
276
277     public void reap()
278     {
279         ValueReference ref;
280
281         while ((ref = (ValueReference)reaped.poll()) != null)
282         {
283             map.remove(ref.getKey());
284             ++cleared;
285         }
286     }
287 }
288
Popular Tags