Skip to content

Commit 5979d66

Browse files
committed
Add WeakIdentityHashMap implementation (from Apache Avro)
Origin <https://github.com/apache/avro/blob/master/lang/java/avro/src/main/java/org/apache/avro/util/WeakIdentityHashMap.java> from their commit 70260919426f89825ca148f5ee815f3b2cf4764d. Apache License Version 2.0 until. Using our JogAmp 'New BSD 2-Clause License' for changes after this initial commit. Related to Bug 1312, where we like to utilize a WeakIdentityHashMap, allowing to have cached shared GLContext to disappear .. a compromise.
1 parent 1390bc2 commit 5979d66

File tree

2 files changed

+250
-2
lines changed

2 files changed

+250
-2
lines changed

LICENSE.txt

+21-2
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ L.3) The GlueGen source tree contains CGRAM http://www.antlr.org/grammar/cgram/,
140140
A.1) The GlueGen source tree contains code from The Apache Software Foundation
141141
which is covered by the Apache License Version 2.0
142142

143-
Apache Harmony - Open Source Java SE
144-
=====================================
143+
A.1.1) Apache Harmony - Open Source Java SE
144+
===============================================
145145

146146
<http://harmony.apache.org/>
147147

@@ -157,6 +157,25 @@ A.1) The GlueGen source tree contains code from The Apache Software Foundation
157157
- src/java/com/jogamp/common/net/Uri.java
158158
(derived from java.net.URI.Helper and heavily modified)
159159

160+
A.1.2) Apache Avro - A data serialization system.
161+
===============================================
162+
163+
<https://avro.apache.org/>
164+
165+
Copyright 2010-2019 The Apache Software Foundation
166+
167+
Apache License Version 2.0, January 2004
168+
http://www.apache.org/licenses/LICENSE-2.0
169+
Or within this repository: doc/licenses/Apache.LICENSE-2.0
170+
171+
Files:
172+
- src/java/com/jogamp/common/util/WeakIdentityHashMap.java
173+
174+
<https://github.com/apache/avro/blob/master/lang/java/avro/src/main/java/org/apache/avro/util/WeakIdentityHashMap.java>
175+
Taken as commit 70260919426f89825ca148f5ee815f3b2cf4764d
176+
and using our JogAmp 'New BSD 2-Clause License' since migration.
177+
178+
160179
A.2) The GlueGen source tree contains code from Ben Mankin, a.k.a 'Shevek',
161180
which is covered by the Apache License Version 2.0
162181

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
/**
2+
* Copyright 2019 JogAmp Community. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without modification, are
5+
* permitted provided that the following conditions are met:
6+
*
7+
* 1. Redistributions of source code must retain the above copyright notice, this list of
8+
* conditions and the following disclaimer.
9+
*
10+
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
11+
* of conditions and the following disclaimer in the documentation and/or other materials
12+
* provided with the distribution.
13+
*
14+
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15+
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16+
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20+
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22+
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23+
*
24+
* The views and conclusions contained in the software and documentation are those of the
25+
* authors and should not be interpreted as representing official policies, either expressed
26+
* or implied, of JogAmp Community.
27+
*
28+
* Original source code of this class taken from Apache Avro
29+
* <https://github.com/apache/avro/blob/master/lang/java/avro/src/main/java/org/apache/avro/util/WeakIdentityHashMap.java>
30+
* commit 70260919426f89825ca148f5ee815f3b2cf4764d.
31+
* Up until commit 70260919426f89825ca148f5ee815f3b2cf4764d,
32+
* this code has been licensed as described below:
33+
*
34+
* Licensed to the Apache Software Foundation (ASF) under one
35+
* or more contributor license agreements. See the NOTICE file
36+
* distributed with this work for additional information
37+
* regarding copyright ownership. The ASF licenses this file
38+
* to you under the Apache License, Version 2.0 (the
39+
* "License"); you may not use this file except in compliance
40+
* with the License. You may obtain a copy of the License at
41+
*
42+
* https://www.apache.org/licenses/LICENSE-2.0
43+
*
44+
* Unless required by applicable law or agreed to in writing,
45+
* software distributed under the License is distributed on an
46+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
47+
* KIND, either express or implied. See the License for the
48+
* specific language governing permissions and limitations
49+
* under the License.
50+
*/
51+
52+
package com.jogamp.common.util;
53+
54+
import java.lang.ref.ReferenceQueue;
55+
import java.lang.ref.WeakReference;
56+
import java.util.Collection;
57+
import java.util.Collections;
58+
import java.util.HashMap;
59+
import java.util.HashSet;
60+
import java.util.Map;
61+
import java.util.Set;
62+
63+
/**
64+
* Implements a combination of WeakHashMap and IdentityHashMap. Useful for
65+
* caches that need to key off of a == comparison instead of a .equals.
66+
*
67+
* <b> This class is not a general-purpose Map implementation! While this class
68+
* implements the Map interface, it intentionally violates Map's general
69+
* contract, which mandates the use of the equals method when comparing objects.
70+
* This class is designed for use only in the rare cases wherein
71+
* reference-equality semantics are required.
72+
*
73+
* Note that this implementation is not synchronized. </b>
74+
*/
75+
public class WeakIdentityHashMap<K, V> implements Map<K, V> {
76+
private final ReferenceQueue<K> queue = new ReferenceQueue<>();
77+
private Map<IdentityWeakReference, V> backingStore = new HashMap<>();
78+
79+
public WeakIdentityHashMap() {
80+
}
81+
82+
@Override
83+
public void clear() {
84+
backingStore.clear();
85+
reap();
86+
}
87+
88+
@Override
89+
public boolean containsKey(Object key) {
90+
reap();
91+
return backingStore.containsKey(new IdentityWeakReference(key));
92+
}
93+
94+
@Override
95+
public boolean containsValue(Object value) {
96+
reap();
97+
return backingStore.containsValue(value);
98+
}
99+
100+
@Override
101+
public Set<Map.Entry<K, V>> entrySet() {
102+
reap();
103+
Set<Map.Entry<K, V>> ret = new HashSet<>();
104+
for (Map.Entry<IdentityWeakReference, V> ref : backingStore.entrySet()) {
105+
final K key = ref.getKey().get();
106+
final V value = ref.getValue();
107+
Map.Entry<K, V> entry = new Map.Entry<K, V>() {
108+
@Override
109+
public K getKey() {
110+
return key;
111+
}
112+
113+
@Override
114+
public V getValue() {
115+
return value;
116+
}
117+
118+
@Override
119+
public V setValue(V value) {
120+
throw new UnsupportedOperationException();
121+
}
122+
};
123+
ret.add(entry);
124+
}
125+
return Collections.unmodifiableSet(ret);
126+
}
127+
128+
@Override
129+
public Set<K> keySet() {
130+
reap();
131+
Set<K> ret = new HashSet<>();
132+
for (IdentityWeakReference ref : backingStore.keySet()) {
133+
ret.add(ref.get());
134+
}
135+
return Collections.unmodifiableSet(ret);
136+
}
137+
138+
@Override
139+
public boolean equals(Object o) {
140+
if (!(o instanceof WeakIdentityHashMap)) {
141+
return false;
142+
}
143+
return backingStore.equals(((WeakIdentityHashMap) o).backingStore);
144+
}
145+
146+
@Override
147+
public V get(Object key) {
148+
reap();
149+
return backingStore.get(new IdentityWeakReference(key));
150+
}
151+
152+
@Override
153+
public V put(K key, V value) {
154+
reap();
155+
return backingStore.put(new IdentityWeakReference(key), value);
156+
}
157+
158+
@Override
159+
public int hashCode() {
160+
reap();
161+
return backingStore.hashCode();
162+
}
163+
164+
@Override
165+
public boolean isEmpty() {
166+
reap();
167+
return backingStore.isEmpty();
168+
}
169+
170+
@Override
171+
public void putAll(Map t) {
172+
throw new UnsupportedOperationException();
173+
}
174+
175+
@Override
176+
public V remove(Object key) {
177+
reap();
178+
return backingStore.remove(new IdentityWeakReference(key));
179+
}
180+
181+
@Override
182+
public int size() {
183+
reap();
184+
return backingStore.size();
185+
}
186+
187+
@Override
188+
public Collection<V> values() {
189+
reap();
190+
return backingStore.values();
191+
}
192+
193+
private synchronized void reap() {
194+
Object zombie = queue.poll();
195+
196+
while (zombie != null) {
197+
IdentityWeakReference victim = (IdentityWeakReference) zombie;
198+
backingStore.remove(victim);
199+
zombie = queue.poll();
200+
}
201+
}
202+
203+
class IdentityWeakReference extends WeakReference<K> {
204+
int hash;
205+
206+
@SuppressWarnings("unchecked")
207+
IdentityWeakReference(Object obj) {
208+
super((K) obj, queue);
209+
hash = System.identityHashCode(obj);
210+
}
211+
212+
@Override
213+
public int hashCode() {
214+
return hash;
215+
}
216+
217+
@Override
218+
public boolean equals(Object o) {
219+
if (this == o) {
220+
return true;
221+
}
222+
if (!(o instanceof WeakIdentityHashMap.IdentityWeakReference)) {
223+
return false;
224+
}
225+
IdentityWeakReference ref = (IdentityWeakReference) o;
226+
return this.get() == ref.get();
227+
}
228+
}
229+
}

0 commit comments

Comments
 (0)