KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > retrotranslator > runtime > impl > WeakIdentityTable


1 /***
2  * Retrotranslator: a Java bytecode transformer that translates Java classes
3  * compiled with JDK 5.0 into classes that can be run on JVM 1.4.
4  *
5  * Copyright (c) 2005 - 2007 Taras Puchko
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the copyright holders nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30  * THE POSSIBILITY OF SUCH DAMAGE.
31  */

32 package net.sf.retrotranslator.runtime.impl;
33
34 import java.lang.ref.*;
35 import java.util.concurrent.*;
36
37 /**
38  * @author Taras Puchko
39  */

40 public class WeakIdentityTable<K, V> {
41
42     private final ConcurrentMap<IdentityKey<K>, V> map = new ConcurrentHashMap<IdentityKey<K>, V>();
43     private final ReferenceQueue<K> queue = new ReferenceQueue<K>();
44
45     public WeakIdentityTable() {
46     }
47
48     public V lookup(K key) {
49         return map.get(new StrongKey<K>(key));
50     }
51
52     public V obtain(K key) {
53         V currentValue = map.get(new StrongKey<K>(key));
54         if (currentValue != null) {
55             return currentValue;
56         }
57         cleanup();
58         V newValue = initialValue();
59         V previousValue = map.putIfAbsent(new WeakKey<K>(key, queue), newValue);
60         return previousValue != null ? previousValue : newValue;
61     }
62
63     public void putIfAbsent(K key, V value) {
64         cleanup();
65         map.putIfAbsent(new WeakKey<K>(key, queue), value);
66     }
67
68     public int size() {
69         cleanup();
70         return map.size();
71     }
72
73     protected V initialValue() {
74         return null;
75     }
76
77     private void cleanup() {
78         Reference reference;
79         while ((reference = queue.poll()) != null) {
80             map.remove(reference);
81         }
82     }
83
84     private interface IdentityKey<T> {
85         T get();
86     }
87
88     private static class StrongKey<T> implements IdentityKey<T> {
89
90         private T referent;
91
92         public StrongKey(T referent) {
93             if (referent == null) {
94                 throw new NullPointerException JavaDoc();
95             }
96             this.referent = referent;
97         }
98
99         public T get() {
100             return referent;
101         }
102
103         public int hashCode() {
104             return System.identityHashCode(referent);
105         }
106
107         public boolean equals(Object JavaDoc obj) {
108             return obj instanceof IdentityKey && ((IdentityKey) obj).get() == referent;
109         }
110     }
111
112     private static class WeakKey<T> extends WeakReference<T> implements IdentityKey<T> {
113
114         private int hashCode;
115
116         public WeakKey(T referent, ReferenceQueue<T> queue) {
117             super(referent, queue);
118             if (referent == null) {
119                 throw new NullPointerException JavaDoc();
120             }
121             hashCode = System.identityHashCode(referent);
122         }
123
124         public int hashCode() {
125             return hashCode;
126         }
127
128         public boolean equals(Object JavaDoc obj) {
129             return obj == this || (obj instanceof IdentityKey && ((IdentityKey) obj).get() == get());
130         }
131
132     }
133
134 }
135
Popular Tags