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