1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.util;
21
22 import java.lang.ref.ReferenceQueue;
23 import java.lang.ref.SoftReference;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Comparator;
27 import java.util.LinkedHashSet;
28 import java.util.Map;
29 import java.util.Set;
30 import java.util.SortedMap;
31 import java.util.TreeMap;
32 import java.util.TreeSet;
33
34
35
36
37
38
39
40
41
42 public class SoftValueSortedMap<K,V> implements SortedMap<K,V> {
43 private final SortedMap<K, SoftValue<K,V>> internalMap;
44 private final ReferenceQueue rq = new ReferenceQueue();
45
46
47 public SoftValueSortedMap() {
48 this(new TreeMap<K, SoftValue<K,V>>());
49 }
50
51
52
53
54
55 public SoftValueSortedMap(final Comparator<K> c) {
56 this(new TreeMap<K, SoftValue<K,V>>(c));
57 }
58
59
60
61
62 private SoftValueSortedMap(SortedMap<K,SoftValue<K,V>> original) {
63 this.internalMap = original;
64 }
65
66
67
68
69
70
71
72 private int checkReferences() {
73 int i = 0;
74 for (Object obj; (obj = this.rq.poll()) != null;) {
75 i++;
76
77 this.internalMap.remove(((SoftValue<K,V>)obj).key);
78 }
79 return i;
80 }
81
82 public synchronized V put(K key, V value) {
83 checkReferences();
84 SoftValue<K,V> oldValue = this.internalMap.put(key,
85 new SoftValue<K,V>(key, value, this.rq));
86 return oldValue == null ? null : oldValue.get();
87 }
88
89 @SuppressWarnings("unchecked")
90 public synchronized void putAll(Map map) {
91 throw new RuntimeException("Not implemented");
92 }
93
94 @SuppressWarnings({"SuspiciousMethodCalls"})
95 public synchronized V get(Object key) {
96 checkReferences();
97 SoftValue<K,V> value = this.internalMap.get(key);
98 if (value == null) {
99 return null;
100 }
101 if (value.get() == null) {
102 this.internalMap.remove(key);
103 return null;
104 }
105 return value.get();
106 }
107
108 public synchronized V remove(Object key) {
109 checkReferences();
110 SoftValue<K,V> value = this.internalMap.remove(key);
111 return value == null ? null : value.get();
112 }
113
114 public synchronized boolean containsKey(Object key) {
115 checkReferences();
116 return this.internalMap.containsKey(key);
117 }
118
119 public synchronized boolean containsValue(Object value) {
120
121
122 throw new UnsupportedOperationException("Don't support containsValue!");
123 }
124
125 public synchronized K firstKey() {
126 checkReferences();
127 return internalMap.firstKey();
128 }
129
130 public synchronized K lastKey() {
131 checkReferences();
132 return internalMap.lastKey();
133 }
134
135 public synchronized SoftValueSortedMap<K,V> headMap(K key) {
136 checkReferences();
137 return new SoftValueSortedMap<K,V>(this.internalMap.headMap(key));
138 }
139
140 public synchronized SoftValueSortedMap<K,V> tailMap(K key) {
141 checkReferences();
142 return new SoftValueSortedMap<K,V>(this.internalMap.tailMap(key));
143 }
144
145 public synchronized SoftValueSortedMap<K,V> subMap(K fromKey, K toKey) {
146 checkReferences();
147 return new SoftValueSortedMap<K,V>(this.internalMap.subMap(fromKey, toKey));
148 }
149
150 public synchronized boolean isEmpty() {
151 checkReferences();
152 return this.internalMap.isEmpty();
153 }
154
155 public synchronized int size() {
156 checkReferences();
157 return this.internalMap.size();
158 }
159
160 public synchronized void clear() {
161 checkReferences();
162 this.internalMap.clear();
163 }
164
165 public synchronized Set<K> keySet() {
166 checkReferences();
167 return this.internalMap.keySet();
168 }
169
170 @SuppressWarnings("unchecked")
171 public synchronized Comparator comparator() {
172 return this.internalMap.comparator();
173 }
174
175 public synchronized Set<Map.Entry<K,V>> entrySet() {
176 checkReferences();
177 Set<Map.Entry<K, SoftValue<K, V>>> entries = this.internalMap.entrySet();
178 Set<Map.Entry<K, V>> realEntries = new LinkedHashSet<Map.Entry<K, V>>();
179 for (Map.Entry<K, SoftValue<K, V>> entry : entries) {
180 realEntries.add(entry.getValue());
181 }
182 return realEntries;
183 }
184
185 public synchronized Collection<V> values() {
186 checkReferences();
187 Collection<SoftValue<K,V>> softValues = this.internalMap.values();
188 ArrayList<V> hardValues = new ArrayList<V>();
189 for(SoftValue<K,V> softValue : softValues) {
190 hardValues.add(softValue.get());
191 }
192 return hardValues;
193 }
194
195 private static class SoftValue<K,V> extends SoftReference<V> implements Map.Entry<K, V> {
196 final K key;
197
198 SoftValue(K key, V value, ReferenceQueue q) {
199 super(value, q);
200 this.key = key;
201 }
202
203 public K getKey() {
204 return this.key;
205 }
206
207 public V getValue() {
208 return get();
209 }
210
211 public V setValue(V value) {
212 throw new RuntimeException("Not implemented");
213 }
214 }
215 }