1 | // by Apache; modified |
2 | sclass WeakIdentityHashMap<K, V> implements Map<K, V> { |
3 | private final ReferenceQueue<K> queue = new ReferenceQueue<K>(); |
4 | private Map<IdentityWeakReference, V> backingStore |
5 | = new HashMap<IdentityWeakReference, V>(); |
6 | |
7 | *() { |
8 | _registerWeakMap(this); |
9 | } |
10 | |
11 | public synchronized void clear() { |
12 | backingStore.clear(); |
13 | reap(); |
14 | } |
15 | |
16 | public synchronized boolean containsKey(Object key) { |
17 | reap(); |
18 | return backingStore.containsKey(new IdentityWeakReference(key)); |
19 | } |
20 | |
21 | public synchronized boolean containsValue(Object value) { |
22 | reap(); |
23 | return backingStore.containsValue(value); |
24 | } |
25 | |
26 | public synchronized Set<Map.Entry<K, V>> entrySet() { |
27 | reap(); |
28 | Set<Map.Entry<K, V>> ret = new HashSet<Map.Entry<K, V>>(); |
29 | for (Map.Entry<IdentityWeakReference, V> ref : backingStore.entrySet()) { |
30 | final K key = ref.getKey().get(); |
31 | final V value = ref.getValue(); |
32 | Map.Entry<K, V> entry = new Map.Entry<K, V>() { |
33 | public synchronized K getKey() { |
34 | return key; |
35 | } |
36 | public synchronized V getValue() { |
37 | return value; |
38 | } |
39 | public synchronized V setValue(V value) { |
40 | throw new UnsupportedOperationException(); |
41 | } |
42 | }; |
43 | ret.add(entry); |
44 | } |
45 | return Collections.unmodifiableSet(ret); |
46 | } |
47 | |
48 | public synchronized Set<K> keySet() { |
49 | reap(); |
50 | new IdentityHashMap<K, Bool> map; |
51 | for (IdentityWeakReference ref : backingStore.keySet()) { |
52 | K k = ref.get(); |
53 | if (k != null) map.put(k, Bool.TRUE); |
54 | } |
55 | return map.keySet(); |
56 | } |
57 | |
58 | public synchronized boolean equals(Object o) { |
59 | if (!(o instanceof WeakIdentityHashMap)) { |
60 | return false; |
61 | } |
62 | return backingStore.equals(((WeakIdentityHashMap)o).backingStore); |
63 | } |
64 | |
65 | public synchronized V get(Object key) { |
66 | reap(); |
67 | return backingStore.get(new IdentityWeakReference(key)); |
68 | } |
69 | |
70 | // return value seems unreliable (see ButtonImageLoader) |
71 | public synchronized V put(K key, V value) { |
72 | reap(); |
73 | return backingStore.put(new IdentityWeakReference(key), value); |
74 | } |
75 | |
76 | public synchronized int hashCode() { |
77 | reap(); |
78 | return backingStore.hashCode(); |
79 | } |
80 | public synchronized boolean isEmpty() { |
81 | reap(); |
82 | return backingStore.isEmpty(); |
83 | } |
84 | public synchronized void putAll(Map t) { |
85 | throw new UnsupportedOperationException(); |
86 | } |
87 | |
88 | // TODO: the IdentityWeakReference made is later enqueued, |
89 | // even though it's not added to the map. Is that a problem? |
90 | public synchronized V remove(Object key) { |
91 | reap(); |
92 | return backingStore.remove(new IdentityWeakReference(key)); |
93 | } |
94 | public synchronized int size() { |
95 | reap(); |
96 | return backingStore.size(); |
97 | } |
98 | public synchronized Collection<V> values() { |
99 | reap(); |
100 | return backingStore.values(); |
101 | } |
102 | |
103 | private synchronized void reap() { |
104 | O zombie = queue.poll(); |
105 | |
106 | while (zombie != null) { |
107 | IdentityWeakReference victim = (IdentityWeakReference) zombie; |
108 | ifdef WeakIdentityHashMap_debug |
109 | print("WeakIdentityHashMap removing: " + victim.get()); |
110 | endifdef |
111 | backingStore.remove(victim); |
112 | zombie = queue.poll(); |
113 | } |
114 | } |
115 | |
116 | class IdentityWeakReference extends WeakReference<K> { |
117 | int hash; |
118 | |
119 | @SuppressWarnings("unchecked") |
120 | IdentityWeakReference(Object obj) { |
121 | super((K)obj, queue); |
122 | hash = System.identityHashCode(obj); |
123 | } |
124 | |
125 | public synchronized int hashCode() { |
126 | return hash; |
127 | } |
128 | |
129 | public synchronized boolean equals(Object o) { |
130 | if (this == o) { |
131 | return true; |
132 | } |
133 | if (!(o instanceof WeakIdentityHashMap.IdentityWeakReference)) { |
134 | return false; |
135 | } |
136 | IdentityWeakReference ref = (IdentityWeakReference)o; |
137 | if (this.get() == ref.get()) { |
138 | return true; |
139 | } |
140 | return false; |
141 | } |
142 | } |
143 | } |
/** * Implements a combination of WeakHashMap and IdentityHashMap. * Useful for caches that need to key off of a == comparison * instead of a .equals. * * <b> * This class is not a general-purpose Map implementation! While * this class implements the Map interface, it intentionally violates * Map's general contract, which mandates the use of the equals method * when comparing objects. This class is designed for use only in the * rare cases wherein reference-equality semantics are required. * * Note that this implementation is not synchronized. * </b> */
download show line numbers debug dex old transpilations
Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1010613 |
Snippet name: | WeakIdentityHashMap |
Eternal ID of this version: | #1010613/10 |
Text MD5: | 14f1e5c9bc0f22afaded52438ab1040f |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2018-06-06 12:25:09 |
Source code size: | 3959 bytes / 143 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 454 / 1592 |
Version history: | 9 change(s) |
Referenced in: | [show references] |