KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > util > collection > SoftSet


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.util.collection;
23
24 import java.lang.ref.ReferenceQueue JavaDoc;
25 import java.lang.ref.SoftReference JavaDoc;
26 import java.lang.reflect.Array JavaDoc;
27 import java.util.Collection JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.Set JavaDoc;
31
32 /**
33  * An implementation of Set that manages a map of soft references to
34  * the set values. The map is keyed by the value hashCode and so this
35  * is only useful for value whose hashCode is a valid identity
36  * representation (String, primative wrappers, etc).
37  *
38  * @author Scott.Stark@jboss.org
39  * @version $Revision: 1958 $
40  */

41 public class SoftSet implements Set JavaDoc
42 {
43    private HashMap JavaDoc map = new HashMap JavaDoc();
44    /** The queue of garbage collected soft references */
45    private ReferenceQueue JavaDoc gcqueue = new ReferenceQueue JavaDoc();
46
47    static class ComparableSoftReference extends SoftReference JavaDoc
48    {
49       private Integer JavaDoc key;
50       ComparableSoftReference(Integer JavaDoc key, Object JavaDoc o, ReferenceQueue JavaDoc q)
51       {
52          super(o, q);
53          this.key = key;
54       }
55       Integer JavaDoc getKey()
56       {
57          return key;
58       }
59    }
60    static class ComparableSoftReferenceIterator implements Iterator JavaDoc
61    {
62       Iterator JavaDoc theIter;
63       ComparableSoftReferenceIterator(Iterator JavaDoc theIter)
64       {
65          this.theIter = theIter;
66       }
67       public boolean hasNext()
68       {
69          return theIter.hasNext();
70       }
71       public Object JavaDoc next()
72       {
73          ComparableSoftReference csr = (ComparableSoftReference) theIter.next();
74          return csr.get();
75       }
76       public void remove()
77       {
78          theIter.remove();
79       }
80    }
81
82    /**
83     *
84     */

85    public SoftSet()
86    {
87    }
88
89    public int size()
90    {
91       processQueue();
92       return map.size();
93    }
94
95    public boolean isEmpty()
96    {
97       processQueue();
98       return map.isEmpty();
99    }
100
101    public boolean contains(Object JavaDoc o)
102    {
103       processQueue();
104       Integer JavaDoc key = new Integer JavaDoc(o.hashCode());
105       boolean contains = map.containsKey(key);
106       return contains;
107    }
108
109    public Iterator JavaDoc iterator()
110    {
111       processQueue();
112       Iterator JavaDoc theIter = map.values().iterator();
113       return new ComparableSoftReferenceIterator(theIter);
114    }
115
116    public Object JavaDoc[] toArray()
117    {
118       processQueue();
119       return toArray(new Object JavaDoc[0]);
120    }
121
122    public Object JavaDoc[] toArray(Object JavaDoc[] a)
123    {
124       processQueue();
125       int size = map.size();
126       Object JavaDoc[] array = {};
127       if( a.length >= size )
128          array = a;
129       Iterator JavaDoc iter = map.values().iterator();
130       int index = 0;
131       while( iter.hasNext() )
132       {
133          ComparableSoftReference csr = (ComparableSoftReference) iter.next();
134          Object JavaDoc value = csr.get();
135          // Create the correct array type
136
if( array.length == 0 )
137          {
138             if( value == null )
139             {
140                index ++;
141                continue;
142             }
143             Array.newInstance(value.getClass(), size);
144          }
145          array[index] = value;
146          index ++;
147       }
148       return array;
149    }
150
151    public boolean add(Object JavaDoc o)
152    {
153       processQueue();
154       Integer JavaDoc key = new Integer JavaDoc(o.hashCode());
155       ComparableSoftReference sr = new ComparableSoftReference(key, o, gcqueue);
156       return map.put(key, sr) == null;
157    }
158
159    public boolean remove(Object JavaDoc o)
160    {
161       processQueue();
162       Integer JavaDoc key = new Integer JavaDoc(o.hashCode());
163       return map.remove(key) != null;
164    }
165
166    public boolean containsAll(Collection JavaDoc c)
167    {
168       processQueue();
169       Iterator JavaDoc iter = c.iterator();
170       boolean contains = true;
171       while( iter.hasNext() )
172       {
173          Object JavaDoc value = iter.next();
174          Integer JavaDoc key = new Integer JavaDoc(value.hashCode());
175          contains &= map.containsKey(key);
176       }
177       return contains;
178    }
179
180    public boolean addAll(Collection JavaDoc c)
181    {
182       processQueue();
183       Iterator JavaDoc iter = c.iterator();
184       boolean added = false;
185       while( iter.hasNext() )
186       {
187          Object JavaDoc value = iter.next();
188          Integer JavaDoc key = new Integer JavaDoc(value.hashCode());
189          ComparableSoftReference sr = new ComparableSoftReference(key, value, gcqueue);
190          added |= map.put(key, sr) == null;
191       }
192       return added;
193    }
194
195    public boolean retainAll(Collection JavaDoc c)
196    {
197       Iterator JavaDoc iter = iterator();
198       boolean removed = false;
199       while( iter.hasNext() )
200       {
201          Object JavaDoc value = iter.next();
202          if( c.contains(value) == false )
203          {
204             iter.remove();
205             removed = true;
206          }
207       }
208       return removed;
209    }
210
211    public boolean removeAll(Collection JavaDoc c)
212    {
213       processQueue();
214       Iterator JavaDoc iter = c.iterator();
215       boolean removed = false;
216       while( iter.hasNext() )
217       {
218          Object JavaDoc value = iter.next();
219          removed |= remove(value);
220       }
221       return removed;
222    }
223
224    public void clear()
225    {
226       while( gcqueue.poll() != null )
227          ;
228       map.clear();
229    }
230
231    public boolean equals(Object JavaDoc o)
232    {
233       return map.equals(o);
234    }
235
236    public int hashCode()
237    {
238       return map.hashCode();
239    }
240
241    /**
242     * Iterate through the gcqueue for for any cleared reference, remove
243     * the associated value from the underlying set.
244     */

245    private void processQueue()
246    {
247       ComparableSoftReference cr;
248       while( (cr = (ComparableSoftReference) gcqueue.poll()) != null )
249       {
250          map.remove(cr.getKey());
251       }
252    }
253
254 }
255
Popular Tags