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.HashMap;
26 import java.util.HashSet;
27 import java.util.Map;
28 import java.util.Set;
29
30
31
32
33
34
35
36 public class SoftValueMap<K,V> implements Map<K,V> {
37 private final Map<K, SoftValue<K,V>> internalMap =
38 new HashMap<K, SoftValue<K,V>>();
39 private final ReferenceQueue<?> rq;
40
41 public SoftValueMap() {
42 this(new ReferenceQueue());
43 }
44
45 public SoftValueMap(final ReferenceQueue<?> rq) {
46 this.rq = rq;
47 }
48
49
50
51
52
53
54 @SuppressWarnings({"unchecked"})
55 public int checkReferences() {
56 int i = 0;
57 for (Object obj; (obj = this.rq.poll()) != null;) {
58 i++;
59 this.internalMap.remove(((SoftValue<K,V>)obj).getKey());
60 }
61 return i;
62 }
63
64 public V put(K key, V value) {
65 checkReferences();
66 SoftValue<K,V> oldValue = this.internalMap.put(key,
67 new SoftValue<K,V>(key, value, this.rq));
68 return oldValue == null ? null : oldValue.get();
69 }
70
71 @SuppressWarnings("unchecked")
72 public void putAll(Map map) {
73 throw new RuntimeException("Not implemented");
74 }
75
76 @SuppressWarnings({"SuspiciousMethodCalls"})
77 public V get(Object key) {
78 checkReferences();
79 SoftValue<K,V> value = this.internalMap.get(key);
80 if (value == null) {
81 return null;
82 }
83 if (value.get() == null) {
84 this.internalMap.remove(key);
85 return null;
86 }
87 return value.get();
88 }
89
90 public V remove(Object key) {
91 checkReferences();
92 SoftValue<K,V> value = this.internalMap.remove(key);
93 return value == null ? null : value.get();
94 }
95
96 public boolean containsKey(Object key) {
97 checkReferences();
98 return this.internalMap.containsKey(key);
99 }
100
101 public boolean containsValue(Object value) {
102
103
104 throw new UnsupportedOperationException("Don't support containsValue!");
105 }
106
107 public boolean isEmpty() {
108 checkReferences();
109 return this.internalMap.isEmpty();
110 }
111
112 public int size() {
113 checkReferences();
114 return this.internalMap.size();
115 }
116
117 public void clear() {
118 checkReferences();
119 this.internalMap.clear();
120 }
121
122 public Set<K> keySet() {
123 checkReferences();
124 return this.internalMap.keySet();
125 }
126
127 public Set<Map.Entry<K,V>> entrySet() {
128 checkReferences();
129 Set<Map.Entry<K, SoftValue<K,V>>> entries = this.internalMap.entrySet();
130 Set<Map.Entry<K, V>> real_entries = new HashSet<Map.Entry<K,V>>();
131 for(Map.Entry<K, SoftValue<K,V>> entry : entries) {
132 real_entries.add(entry.getValue());
133 }
134 return real_entries;
135 }
136
137 public Collection<V> values() {
138 checkReferences();
139 Collection<SoftValue<K,V>> softValues = this.internalMap.values();
140 ArrayList<V> hardValues = new ArrayList<V>();
141 for(SoftValue<K,V> softValue : softValues) {
142 hardValues.add(softValue.get());
143 }
144 return hardValues;
145 }
146 }