blob: 75afea6052820ece532155e23aad9856899279ba [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012 The University of York.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* Dimitrios Kolovos - initial API and implementation
******************************************************************************/
package org.eclipse.epsilon.eol.util;
import java.lang.ref.ReferenceQueue;
import java.util.HashMap;
import java.util.Map;
public class Cache<K, V> {
protected ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
protected Map<IdentityBasedWeakReference, V> map = new HashMap<>();
protected Thread cleanUpThread;
public Map<IdentityBasedWeakReference, V> getMap() {
return map;
}
protected Thread createCleanUpThread() {
return new Thread(() -> {
try {
while (!map.isEmpty() && !Thread.currentThread().isInterrupted()) {
IdentityBasedWeakReference reference = (IdentityBasedWeakReference) referenceQueue.remove();
if (reference != null) {
synchronized (map) {
map.remove(reference);
}
}
}
} catch (InterruptedException ie) {}
});
}
public V get(Object key) {
synchronized (map) {
return map.get(new IdentityBasedWeakReference(key, referenceQueue));
}
}
public V put(K key, V value) {
IdentityBasedWeakReference reference = new IdentityBasedWeakReference(key, referenceQueue);
synchronized (map) {
if (!map.containsKey(reference)) {
map.put(reference, value);
if (map.size() == 1) {
try {
cleanUpThread = createCleanUpThread();
cleanUpThread.setDaemon(true);
cleanUpThread.start();
}
catch (Exception ex) {}
}
}
return value;
}
}
public int size() {
return map.size();
}
public void dispose() {
if (cleanUpThread != null) {
cleanUpThread.interrupt();
cleanUpThread = null;
}
map.clear();
}
}