mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
factor common code
This commit is contained in:
@@ -116,7 +116,7 @@ abstract class RefHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V> {
|
||||
T get();
|
||||
}
|
||||
|
||||
protected abstract <T> Key<T> createKey(T k, ReferenceQueue<? super T> q);
|
||||
protected abstract <T> Key<T> createKey(@NotNull T k, @NotNull ReferenceQueue<? super T> q);
|
||||
|
||||
private static class HardKey<T> implements Key<T> {
|
||||
private T myObject;
|
||||
|
||||
@@ -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<K,V> implements Map<K,V>{
|
||||
private final Map<K,MyReference<K,V>> myMap;
|
||||
private final ReferenceQueue<V> myQueue = new ReferenceQueue<V>();
|
||||
|
||||
protected interface MyReference<K,T> {
|
||||
K getKey();
|
||||
T get();
|
||||
}
|
||||
|
||||
public RefValueHashMap() {
|
||||
myMap = new THashMap<K, MyReference<K,V>>();
|
||||
}
|
||||
|
||||
public RefValueHashMap(@NotNull TObjectHashingStrategy<K> strategy) {
|
||||
myMap = new THashMap<K, MyReference<K,V>>(strategy);
|
||||
}
|
||||
|
||||
protected abstract MyReference<K,V> createReference(@NotNull K key, V value, @NotNull ReferenceQueue<V> queue);
|
||||
|
||||
private void processQueue() {
|
||||
while (true) {
|
||||
@SuppressWarnings("unchecked")
|
||||
MyReference<K,V> ref = (MyReference<K,V>)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<K,V> ref = myMap.get(key);
|
||||
if (ref == null) return null;
|
||||
return ref.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V put(@NotNull K key, V value) {
|
||||
processQueue();
|
||||
MyReference<K, V> reference = createReference(key, value, myQueue);
|
||||
MyReference<K,V> oldRef = myMap.put(key, reference);
|
||||
return oldRef != null ? oldRef.get() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V remove(Object key) {
|
||||
processQueue();
|
||||
MyReference<K,V> ref = myMap.remove(key);
|
||||
return ref != null ? ref.get() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(@NotNull Map<? extends K, ? extends V> 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<K> keySet() {
|
||||
return myMap.keySet();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<V> values() {
|
||||
List<V> result = new ArrayList<V>();
|
||||
final Collection<MyReference<K, V>> refs = myMap.values();
|
||||
for (MyReference<K, V> ref : refs) {
|
||||
final V value = ref.get();
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<Entry<K, V>> entrySet() {
|
||||
throw new RuntimeException("method not implemented");
|
||||
}
|
||||
}
|
||||
@@ -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<K,V> extends RefHashMap<K,V> {
|
||||
public SoftHashMap(int initialCapacity, float loadFactor) {
|
||||
super(initialCapacity, loadFactor);
|
||||
@@ -46,7 +49,7 @@ public final class SoftHashMap<K,V> extends RefHashMap<K,V> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> Key<T> createKey(T k, ReferenceQueue<? super T> q) {
|
||||
protected <T> Key<T> createKey(@NotNull T k, ReferenceQueue<? super T> q) {
|
||||
return new SoftKey<T>(k, q);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<K,V> implements Map<K,V>{
|
||||
private final THashMap<K,MyReference<K,V>> myMap;
|
||||
private final ReferenceQueue<MyReference<K,V>> myQueue = new ReferenceQueue<MyReference<K,V>>();
|
||||
public final class SoftValueHashMap<K,V> extends RefValueHashMap<K,V>{
|
||||
private static class MySoftReference<K, T> extends SoftReference<T> implements MyReference<K, T> {
|
||||
private final K key;
|
||||
|
||||
private static class MyReference<K,V> extends SoftReference<V> {
|
||||
final K key;
|
||||
public MyReference(K key, V referent, ReferenceQueue q) {
|
||||
super(referent, (ReferenceQueue<? super V>)q);
|
||||
public MySoftReference(@NotNull K key, T referent, @NotNull ReferenceQueue<? super T> q) {
|
||||
super(referent, q);
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public K getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
public SoftValueHashMap() {
|
||||
myMap = new THashMap<K, MyReference<K,V>>();
|
||||
}
|
||||
|
||||
private void processQueue() {
|
||||
//int count = 0;
|
||||
while(true){
|
||||
MyReference<K,V> ref = (MyReference<K,V>)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<K> strategy) {
|
||||
super(strategy);
|
||||
}
|
||||
|
||||
public V get(Object key) {
|
||||
MyReference<K,V> ref = myMap.get(key);
|
||||
if (ref == null) return null;
|
||||
return ref.get();
|
||||
}
|
||||
|
||||
public V put(K key, V value) {
|
||||
processQueue();
|
||||
MyReference<K,V> oldRef = myMap.put(key, new MyReference<K,V>(key, value, myQueue));
|
||||
return oldRef != null ? (V)oldRef.get() : null;
|
||||
}
|
||||
|
||||
public V remove(Object key) {
|
||||
processQueue();
|
||||
MyReference<K,V> ref = myMap.remove(key);
|
||||
return ref != null ? ref.get() : null;
|
||||
}
|
||||
|
||||
public void putAll(Map<? extends K, ? extends V> 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<K> keySet() {
|
||||
return myMap.keySet();
|
||||
}
|
||||
|
||||
public Collection<V> values() {
|
||||
throw new RuntimeException("method not implemented");
|
||||
}
|
||||
|
||||
public Set<Map.Entry<K, V>> entrySet() {
|
||||
throw new RuntimeException("method not implemented");
|
||||
@Override
|
||||
protected MyReference<K, V> createReference(@NotNull K key, V value, @NotNull ReferenceQueue<V> queue) {
|
||||
return new MySoftReference<K, V>(key, value, queue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,14 +41,14 @@ public final class WeakHashMap<K, V> extends RefHashMap<K, V> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> Key<T> createKey(T k, ReferenceQueue<? super T> q) {
|
||||
protected <T> Key<T> createKey(@NotNull T k, ReferenceQueue<? super T> q) {
|
||||
return new WeakKey<T>(k, q);
|
||||
}
|
||||
|
||||
private static class WeakKey<T> extends WeakReference<T> implements Key<T> {
|
||||
private final int myHash; /* Hashcode of key, stored here since the key may be tossed by the GC */
|
||||
|
||||
private WeakKey(T k, ReferenceQueue<? super T> q) {
|
||||
private WeakKey(@NotNull T k, ReferenceQueue<? super T> q) {
|
||||
super(k, q);
|
||||
myHash = k.hashCode();
|
||||
}
|
||||
|
||||
@@ -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<K,V> implements Map<K,V>{
|
||||
private final Map<K,MyReference<K,V>> myMap;
|
||||
private final ReferenceQueue<V> myQueue = new ReferenceQueue<V>();
|
||||
|
||||
private static class MyReference<K,T> extends WeakReference<T> {
|
||||
public final class WeakValueHashMap<K,V> extends RefValueHashMap<K,V> {
|
||||
private static class MyWeakReference<K, T> extends WeakReference<T> implements MyReference<K, T> {
|
||||
private final K key;
|
||||
|
||||
private MyReference(K key, T referent, ReferenceQueue<? super T> q) {
|
||||
private MyWeakReference(K key, T referent, ReferenceQueue<? super T> q) {
|
||||
super(referent, q);
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public K getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
public WeakValueHashMap() {
|
||||
myMap = new THashMap<K, MyReference<K,V>>();
|
||||
}
|
||||
|
||||
public WeakValueHashMap(@NotNull TObjectHashingStrategy<K> strategy) {
|
||||
myMap = new THashMap<K, MyReference<K,V>>(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<K,V> ref = myMap.get(key);
|
||||
if (ref == null) return null;
|
||||
return ref.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public V put(K key, V value) {
|
||||
processQueue();
|
||||
MyReference<K,V> oldRef = myMap.put(key, new MyReference<K,V>(key, value, myQueue));
|
||||
return oldRef != null ? oldRef.get() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V remove(Object key) {
|
||||
processQueue();
|
||||
MyReference<K,V> ref = myMap.remove(key);
|
||||
return ref != null ? ref.get() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends K, ? extends V> 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<K> keySet() {
|
||||
return myMap.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<V> values() {
|
||||
List<V> result = new ArrayList<V>();
|
||||
final Collection<MyReference<K, V>> refs = myMap.values();
|
||||
for (MyReference<K, V> ref : refs) {
|
||||
final V value = ref.get();
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Entry<K, V>> entrySet() {
|
||||
throw new RuntimeException("method not implemented");
|
||||
protected MyReference<K, V> createReference(@NotNull K key, V value, @NotNull ReferenceQueue<V> queue) {
|
||||
return new MyWeakReference<K, V>(key, value, queue);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user