From c6fabb0ac94000afe29156f170c63080a37c034b Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Tue, 31 Dec 2019 01:11:22 +0100 Subject: WeakIdentityHashMap: Cleanup; Implement putAll(..); Make IdentityWeakReference static --- .../jogamp/common/util/WeakIdentityHashMap.java | 91 +++++++++++++++------- 1 file changed, 61 insertions(+), 30 deletions(-) (limited to 'src/java/com/jogamp/common') diff --git a/src/java/com/jogamp/common/util/WeakIdentityHashMap.java b/src/java/com/jogamp/common/util/WeakIdentityHashMap.java index 92fbbd4..f6a93bd 100644 --- a/src/java/com/jogamp/common/util/WeakIdentityHashMap.java +++ b/src/java/com/jogamp/common/util/WeakIdentityHashMap.java @@ -28,9 +28,9 @@ * Original source code of this class taken from Apache Avro * * commit 70260919426f89825ca148f5ee815f3b2cf4764d. - * Up until commit 70260919426f89825ca148f5ee815f3b2cf4764d, + * Up until commit 70260919426f89825ca148f5ee815f3b2cf4764d, * this code has been licensed as described below: - * + * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information @@ -74,9 +74,28 @@ import java.util.Set; */ public class WeakIdentityHashMap implements Map { private final ReferenceQueue queue = new ReferenceQueue<>(); - private Map backingStore = new HashMap<>(); + private final Map, V> backingStore; + /** + * See {@link HashMap#HashMap()} + */ public WeakIdentityHashMap() { + backingStore = new HashMap<>(); + } + + /** + * See {@link HashMap#HashMap(int, float)} + *

+ * Usable slots before resize are {@code capacity * loadFactor}. + *

+ *

+ * Capacity for n-slots w/o resize would be {@code Math.ceil(n/loadFactor)}. + *

+ * @param initialCapacity default value would be 16, i.e. 12 slots @ 0.75f loadFactor before resize + * @param loadFactor default value would be 0.75f + */ + public WeakIdentityHashMap(final int initialCapacity, final float loadFactor) { + backingStore = new HashMap<>(initialCapacity, loadFactor); } @Override @@ -85,14 +104,15 @@ public class WeakIdentityHashMap implements Map { reap(); } + @SuppressWarnings("unchecked") @Override - public boolean containsKey(Object key) { + public boolean containsKey(final Object key) { reap(); - return backingStore.containsKey(new IdentityWeakReference(key)); + return backingStore.containsKey(new IdentityWeakReference((K) key, queue)); } @Override - public boolean containsValue(Object value) { + public boolean containsValue(final Object value) { reap(); return backingStore.containsValue(value); } @@ -100,11 +120,11 @@ public class WeakIdentityHashMap implements Map { @Override public Set> entrySet() { reap(); - Set> ret = new HashSet<>(); - for (Map.Entry ref : backingStore.entrySet()) { + final Set> ret = new HashSet<>(); + for (final Map.Entry, V> ref : backingStore.entrySet()) { final K key = ref.getKey().get(); final V value = ref.getValue(); - Map.Entry entry = new Map.Entry() { + final Map.Entry entry = new Map.Entry() { @Override public K getKey() { return key; @@ -116,7 +136,7 @@ public class WeakIdentityHashMap implements Map { } @Override - public V setValue(V value) { + public V setValue(final V value) { throw new UnsupportedOperationException(); } }; @@ -128,31 +148,32 @@ public class WeakIdentityHashMap implements Map { @Override public Set keySet() { reap(); - Set ret = new HashSet<>(); - for (IdentityWeakReference ref : backingStore.keySet()) { + final Set ret = new HashSet<>(); + for (final IdentityWeakReference ref : backingStore.keySet()) { ret.add(ref.get()); } return Collections.unmodifiableSet(ret); } @Override - public boolean equals(Object o) { + public boolean equals(final Object o) { if (!(o instanceof WeakIdentityHashMap)) { return false; } - return backingStore.equals(((WeakIdentityHashMap) o).backingStore); + return backingStore.equals(((WeakIdentityHashMap) o).backingStore); } + @SuppressWarnings("unchecked") @Override - public V get(Object key) { + public V get(final Object key) { reap(); - return backingStore.get(new IdentityWeakReference(key)); + return backingStore.get(new IdentityWeakReference((K) key, queue)); } @Override - public V put(K key, V value) { + public V put(final K key, final V value) { reap(); - return backingStore.put(new IdentityWeakReference(key), value); + return backingStore.put(new IdentityWeakReference(key, queue), value); } @Override @@ -168,14 +189,23 @@ public class WeakIdentityHashMap implements Map { } @Override - public void putAll(Map t) { - throw new UnsupportedOperationException(); + public void putAll(final Map t) { + final int n = t.size(); + if ( 0 < n ) { + final Map, V> t2 = new HashMap<>((int)Math.ceil(n/0.75), 0.75f); + for (final Map.Entry e : t.entrySet()) { + t2.put(new IdentityWeakReference(e.getKey(), queue), e.getValue()); + } + backingStore.putAll(t2); + reap(); + } } + @SuppressWarnings("unchecked") @Override - public V remove(Object key) { + public V remove(final Object key) { reap(); - return backingStore.remove(new IdentityWeakReference(key)); + return backingStore.remove(new IdentityWeakReference((K) key, queue)); } @Override @@ -194,18 +224,18 @@ public class WeakIdentityHashMap implements Map { Object zombie = queue.poll(); while (zombie != null) { - IdentityWeakReference victim = (IdentityWeakReference) zombie; + @SuppressWarnings("unchecked") + final IdentityWeakReference victim = (IdentityWeakReference) zombie; backingStore.remove(victim); zombie = queue.poll(); } } - class IdentityWeakReference extends WeakReference { + private static class IdentityWeakReference extends WeakReference { int hash; - @SuppressWarnings("unchecked") - IdentityWeakReference(Object obj) { - super((K) obj, queue); + IdentityWeakReference(final K obj, final ReferenceQueue q) { + super(obj, q); hash = System.identityHashCode(obj); } @@ -215,14 +245,15 @@ public class WeakIdentityHashMap implements Map { } @Override - public boolean equals(Object o) { + public boolean equals(final Object o) { if (this == o) { return true; } - if (!(o instanceof WeakIdentityHashMap.IdentityWeakReference)) { + if (!(o instanceof IdentityWeakReference)) { return false; } - IdentityWeakReference ref = (IdentityWeakReference) o; + @SuppressWarnings("unchecked") + final IdentityWeakReference ref = (IdentityWeakReference) o; return this.get() == ref.get(); } } -- cgit v1.2.3