From 10f7df6ea9685aa7e82e89fe13325988ee383b64 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 22 Jan 2013 14:39:40 +0400 Subject: [PATCH] factor common code --- .../intellij/util/containers/RefHashMap.java | 2 +- .../util/containers/RefValueHashMap.java | 135 ++++++++++++++++++ .../intellij/util/containers/SoftHashMap.java | 7 +- .../util/containers/SoftValueHashMap.java | 96 +++---------- .../intellij/util/containers/WeakHashMap.java | 4 +- .../util/containers/WeakValueHashMap.java | 106 ++------------ 6 files changed, 171 insertions(+), 179 deletions(-) create mode 100644 platform/util/src/com/intellij/util/containers/RefValueHashMap.java diff --git a/platform/util/src/com/intellij/util/containers/RefHashMap.java b/platform/util/src/com/intellij/util/containers/RefHashMap.java index 057b96604e60..e597291a2493 100644 --- a/platform/util/src/com/intellij/util/containers/RefHashMap.java +++ b/platform/util/src/com/intellij/util/containers/RefHashMap.java @@ -116,7 +116,7 @@ abstract class RefHashMap extends AbstractMap implements Map { T get(); } - protected abstract Key createKey(T k, ReferenceQueue q); + protected abstract Key createKey(@NotNull T k, @NotNull ReferenceQueue q); private static class HardKey implements Key { private T myObject; diff --git a/platform/util/src/com/intellij/util/containers/RefValueHashMap.java b/platform/util/src/com/intellij/util/containers/RefValueHashMap.java new file mode 100644 index 000000000000..5eebc6ef7d8f --- /dev/null +++ b/platform/util/src/com/intellij/util/containers/RefValueHashMap.java @@ -0,0 +1,135 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util.containers; + +import gnu.trove.THashMap; +import gnu.trove.TObjectHashingStrategy; +import org.jetbrains.annotations.NotNull; + +import java.lang.ref.ReferenceQueue; +import java.util.*; + +abstract class RefValueHashMap implements Map{ + private final Map> myMap; + private final ReferenceQueue myQueue = new ReferenceQueue(); + + protected interface MyReference { + K getKey(); + T get(); + } + + public RefValueHashMap() { + myMap = new THashMap>(); + } + + public RefValueHashMap(@NotNull TObjectHashingStrategy strategy) { + myMap = new THashMap>(strategy); + } + + protected abstract MyReference createReference(@NotNull K key, V value, @NotNull ReferenceQueue queue); + + private void processQueue() { + while (true) { + @SuppressWarnings("unchecked") + MyReference ref = (MyReference)myQueue.poll(); + if (ref == null) { + return; + } + K key = ref.getKey(); + if (myMap.get(key) == ref) { + myMap.remove(key); + } + } + } + + @Override + public V get(Object key) { + MyReference ref = myMap.get(key); + if (ref == null) return null; + return ref.get(); + } + + @Override + public V put(@NotNull K key, V value) { + processQueue(); + MyReference reference = createReference(key, value, myQueue); + MyReference oldRef = myMap.put(key, reference); + return oldRef != null ? oldRef.get() : null; + } + + @Override + public V remove(Object key) { + processQueue(); + MyReference ref = myMap.remove(key); + return ref != null ? ref.get() : null; + } + + @Override + public void putAll(@NotNull Map t) { + throw new RuntimeException("method not implemented"); + } + + @Override + public void clear() { + myMap.clear(); + } + + @Override + public int size() { + return myMap.size(); //? + } + + @Override + public boolean isEmpty() { + return myMap.isEmpty(); //? + } + + @Override + public boolean containsKey(Object key) { + return get(key) != null; + } + + @Override + public boolean containsValue(Object value) { + throw new RuntimeException("method not implemented"); + } + + @NotNull + @Override + public Set keySet() { + return myMap.keySet(); + } + + @NotNull + @Override + public Collection values() { + List result = new ArrayList(); + final Collection> refs = myMap.values(); + for (MyReference ref : refs) { + final V value = ref.get(); + if (value != null) { + result.add(value); + } + } + return result; + } + + @NotNull + @Override + public Set> entrySet() { + throw new RuntimeException("method not implemented"); + } +} diff --git a/platform/util/src/com/intellij/util/containers/SoftHashMap.java b/platform/util/src/com/intellij/util/containers/SoftHashMap.java index df94dae0cb81..73662c41f14c 100644 --- a/platform/util/src/com/intellij/util/containers/SoftHashMap.java +++ b/platform/util/src/com/intellij/util/containers/SoftHashMap.java @@ -16,7 +16,6 @@ package com.intellij.util.containers; import com.intellij.reference.SoftReference; -import gnu.trove.THashMap; import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -24,6 +23,10 @@ import org.jetbrains.annotations.NotNull; import java.lang.ref.ReferenceQueue; import java.util.Map; +/** + * Soft keys hash map. + * Null keys are not supported. + */ public final class SoftHashMap extends RefHashMap { public SoftHashMap(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor); @@ -46,7 +49,7 @@ public final class SoftHashMap extends RefHashMap { } @Override - protected Key createKey(T k, ReferenceQueue q) { + protected Key createKey(@NotNull T k, ReferenceQueue q) { return new SoftKey(k, q); } diff --git a/platform/util/src/com/intellij/util/containers/SoftValueHashMap.java b/platform/util/src/com/intellij/util/containers/SoftValueHashMap.java index ca8bc69a0265..9a1a7302b7f5 100644 --- a/platform/util/src/com/intellij/util/containers/SoftValueHashMap.java +++ b/platform/util/src/com/intellij/util/containers/SoftValueHashMap.java @@ -16,97 +16,35 @@ package com.intellij.util.containers; import com.intellij.reference.SoftReference; -import gnu.trove.THashMap; +import gnu.trove.TObjectHashingStrategy; +import org.jetbrains.annotations.NotNull; import java.lang.ref.ReferenceQueue; -import java.util.Collection; -import java.util.Map; -import java.util.Set; -public final class SoftValueHashMap implements Map{ - private final THashMap> myMap; - private final ReferenceQueue> myQueue = new ReferenceQueue>(); +public final class SoftValueHashMap extends RefValueHashMap{ + private static class MySoftReference extends SoftReference implements MyReference { + private final K key; - private static class MyReference extends SoftReference { - final K key; - public MyReference(K key, V referent, ReferenceQueue q) { - super(referent, (ReferenceQueue)q); + public MySoftReference(@NotNull K key, T referent, @NotNull ReferenceQueue q) { + super(referent, q); this.key = key; } + + @Override + public K getKey() { + return key; + } } public SoftValueHashMap() { - myMap = new THashMap>(); } - private void processQueue() { - //int count = 0; - while(true){ - MyReference ref = (MyReference)myQueue.poll(); - if (ref == null) { - //if (count > 0){ - // System.out.println("SoftValueHashMap: " + count + " references have been collected"); - //} - return; - } - if (myMap.get(ref.key) == ref){ - myMap.remove(ref.key); - } - //count++; - } + public SoftValueHashMap(@NotNull TObjectHashingStrategy strategy) { + super(strategy); } - public V get(Object key) { - MyReference ref = myMap.get(key); - if (ref == null) return null; - return ref.get(); - } - - public V put(K key, V value) { - processQueue(); - MyReference oldRef = myMap.put(key, new MyReference(key, value, myQueue)); - return oldRef != null ? (V)oldRef.get() : null; - } - - public V remove(Object key) { - processQueue(); - MyReference ref = myMap.remove(key); - return ref != null ? ref.get() : null; - } - - public void putAll(Map t) { - throw new RuntimeException("method not implemented"); - } - - public void clear() { - myMap.clear(); - } - - public int size() { - return myMap.size(); //? - } - - public boolean isEmpty() { - return myMap.isEmpty(); //? - } - - public boolean containsKey(Object key) { - return get(key) != null; - } - - public boolean containsValue(Object value) { - throw new RuntimeException("method not implemented"); - } - - public Set keySet() { - return myMap.keySet(); - } - - public Collection values() { - throw new RuntimeException("method not implemented"); - } - - public Set> entrySet() { - throw new RuntimeException("method not implemented"); + @Override + protected MyReference createReference(@NotNull K key, V value, @NotNull ReferenceQueue queue) { + return new MySoftReference(key, value, queue); } } diff --git a/platform/util/src/com/intellij/util/containers/WeakHashMap.java b/platform/util/src/com/intellij/util/containers/WeakHashMap.java index 8d43140c1d4b..f95bac9bb66e 100644 --- a/platform/util/src/com/intellij/util/containers/WeakHashMap.java +++ b/platform/util/src/com/intellij/util/containers/WeakHashMap.java @@ -41,14 +41,14 @@ public final class WeakHashMap extends RefHashMap { } @Override - protected Key createKey(T k, ReferenceQueue q) { + protected Key createKey(@NotNull T k, ReferenceQueue q) { return new WeakKey(k, q); } private static class WeakKey extends WeakReference implements Key { private final int myHash; /* Hashcode of key, stored here since the key may be tossed by the GC */ - private WeakKey(T k, ReferenceQueue q) { + private WeakKey(@NotNull T k, ReferenceQueue q) { super(k, q); myHash = k.hashCode(); } diff --git a/platform/util/src/com/intellij/util/containers/WeakValueHashMap.java b/platform/util/src/com/intellij/util/containers/WeakValueHashMap.java index e6abe4e559d4..50b94dde1a65 100644 --- a/platform/util/src/com/intellij/util/containers/WeakValueHashMap.java +++ b/platform/util/src/com/intellij/util/containers/WeakValueHashMap.java @@ -15,120 +15,36 @@ */ package com.intellij.util.containers; -import gnu.trove.THashMap; import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NotNull; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; -import java.util.*; -public final class WeakValueHashMap implements Map{ - private final Map> myMap; - private final ReferenceQueue myQueue = new ReferenceQueue(); - - private static class MyReference extends WeakReference { +public final class WeakValueHashMap extends RefValueHashMap { + private static class MyWeakReference extends WeakReference implements MyReference { private final K key; - private MyReference(K key, T referent, ReferenceQueue q) { + private MyWeakReference(K key, T referent, ReferenceQueue q) { super(referent, q); this.key = key; } + + @Override + public K getKey() { + return key; + } } public WeakValueHashMap() { - myMap = new THashMap>(); } public WeakValueHashMap(@NotNull TObjectHashingStrategy strategy) { - myMap = new THashMap>(strategy); - } - - private void processQueue() { - while(true){ - MyReference ref = (MyReference)myQueue.poll(); - if (ref == null) { - return; - } - @SuppressWarnings("unchecked") - K key = (K)ref.key; - if (myMap.get(key) == ref){ - myMap.remove(key); - } - } + super(strategy); } @Override - public V get(Object key) { - MyReference ref = myMap.get(key); - if (ref == null) return null; - return ref.get(); - } - - @Override - public V put(K key, V value) { - processQueue(); - MyReference oldRef = myMap.put(key, new MyReference(key, value, myQueue)); - return oldRef != null ? oldRef.get() : null; - } - - @Override - public V remove(Object key) { - processQueue(); - MyReference ref = myMap.remove(key); - return ref != null ? ref.get() : null; - } - - @Override - public void putAll(Map t) { - throw new RuntimeException("method not implemented"); - } - - @Override - public void clear() { - myMap.clear(); - } - - @Override - public int size() { - return myMap.size(); //? - } - - @Override - public boolean isEmpty() { - return myMap.isEmpty(); //? - } - - @Override - public boolean containsKey(Object key) { - return get(key) != null; - } - - @Override - public boolean containsValue(Object value) { - throw new RuntimeException("method not implemented"); - } - - @Override - public Set keySet() { - return myMap.keySet(); - } - - @Override - public Collection values() { - List result = new ArrayList(); - final Collection> refs = myMap.values(); - for (MyReference ref : refs) { - final V value = ref.get(); - if (value != null) { - result.add(value); - } - } - return result; - } - - @Override - public Set> entrySet() { - throw new RuntimeException("method not implemented"); + protected MyReference createReference(@NotNull K key, V value, @NotNull ReferenceQueue queue) { + return new MyWeakReference(key, value, queue); } }