KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jdo > spi > persistence > utility > WeakHashSet


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.jdo.spi.persistence.utility;
25
26 import java.util.*;
27 import java.lang.ref.*;
28
29 /**
30  * A weak HashSet. An element stored in the WeakHashSet might be garbage collected,
31  * if there is no strong reference to this element.
32  */

33 public class WeakHashSet
34     extends HashSet
35 {
36     /**
37      * Helps to detect garbage collected values.
38      */

39     ReferenceQueue queue = new ReferenceQueue();
40     
41     /**
42      * Returns an iterator over the elements in this set. The elements
43      * are returned in no particular order.
44      *
45      * @return an Iterator over the elements in this set.
46      */

47     public Iterator iterator ()
48     {
49         // remove garbage collected elements
50
processQueue();
51
52         // get an iterator of the superclass WeakHashSet
53
final Iterator i = super.iterator();
54
55         return new Iterator () {
56             public boolean hasNext ()
57             {
58                 return i.hasNext();
59             }
60             
61             public Object JavaDoc next ()
62             {
63                 // unwrap the element
64
return getReferenceObject((WeakReference)i.next());
65             }
66             
67             public void remove ()
68             {
69                 // remove the element from the HashSet
70
i.remove();
71             }
72         };
73     }
74     
75     /**
76      * Returns <code>true</code> if this set contains the specified element.
77      *
78      * @param o element whose presence in this set is to be tested.
79      * @return <code>true</code> if this set contains the specified element.
80      */

81     public boolean contains (Object JavaDoc o)
82     {
83         return super.contains(WeakElement.create(o));
84     }
85
86     /**
87      * Adds the specified element to this set if it is not already
88      * present.
89      *
90      * @param o element to be added to this set.
91      * @return <code>true</code> if the set did not already contain the specified
92      * element.
93      */

94     public boolean add (Object JavaDoc o)
95     {
96         processQueue();
97         return super.add(WeakElement.create(o, this.queue));
98     }
99     
100     /**
101      * Removes the given element from this set if it is present.
102      *
103      * @param o object to be removed from this set, if present.
104      * @return <code>true</code> if the set contained the specified element.
105      */

106     public boolean remove (Object JavaDoc o)
107     {
108         boolean ret = super.remove(WeakElement.create(o));
109         processQueue();
110         return ret;
111     }
112
113     /**
114      * A convenience method to return the object held by the
115      * weak reference or <code>null</code> if it does not exist.
116      */

117     private final Object JavaDoc getReferenceObject (WeakReference ref)
118     {
119         return ((ref != null) ? ref.get() : null);
120     }
121     
122     /**
123      * Removes all garbage collected values with their keys from the map.
124      * Since we don't know how much the ReferenceQueue.poll() operation
125      * costs, we should call it only in the put() method.
126      */

127     private final void processQueue ()
128     {
129         WeakElement wv = null;
130         
131         while ((wv = (WeakElement)this.queue.poll()) != null)
132         {
133             super.remove(wv);
134         }
135     }
136     
137     /**
138      * A WeakHashSet stores objects of class WeakElement.
139      * A WeakElement wraps the element that should be stored in the WeakHashSet.
140      * WeakElement inherits from java.lang.ref.WeakReference.
141      * It redefines equals and hashCode which delegate to the corresponding methods
142      * of the wrapped element.
143      */

144     static private class WeakElement
145         extends WeakReference
146     {
147         private int hash; /* Hashcode of key, stored here since the key
148                                may be tossed by the GC */

149         
150         private WeakElement (Object JavaDoc o)
151         {
152             super(o);
153             hash = o.hashCode();
154         }
155
156         private WeakElement (Object JavaDoc o, ReferenceQueue q)
157         {
158             super(o, q);
159             hash = o.hashCode();
160         }
161
162         private static WeakElement create (Object JavaDoc o)
163         {
164             return (o == null) ? null : new WeakElement(o);
165         }
166
167         private static WeakElement create (Object JavaDoc o, ReferenceQueue q)
168         {
169             return (o == null) ? null : new WeakElement(o, q);
170         }
171
172         /* A WeakElement is equal to another WeakElement iff they both refer to objects
173                that are, in turn, equal according to their own equals methods */

174         public boolean equals (Object JavaDoc o)
175         {
176             if (this == o)
177                 return true;
178             if (!(o instanceof WeakElement))
179                 return false;
180             Object JavaDoc t = this.get();
181             Object JavaDoc u = ((WeakElement)o).get();
182             if ((t == null) || (u == null))
183                 return false;
184             if (t == u)
185                 return true;
186             return t.equals(u);
187         }
188
189         public int hashCode ()
190         {
191             return hash;
192         }
193         
194     }
195     
196 }
197
198
Popular Tags