
eu.cedarsoft.utils.HashedCache Maven / Gradle / Ivy
The newest version!
package eu.cedarsoft.utils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* A cache implementation that is backed up using a map
*/
public class HashedCache implements Cache {
@NotNull
private final ReadWriteLock lock = new ReentrantReadWriteLock();
@NotNull
private final Map store;
@NotNull
private final Factory factory;
/**
* Creates a new hashed cache
*
* @param factory the factory
*/
public HashedCache( @NotNull Factory factory ) {
this.factory = factory;
store = new HashMap();
}
/**
* Use with care. It is preferred to use {@link #HashedCache(Cache.Factory)} instead.
* Uses the given store.
*
* @param store the store
* @param factory the factory
*/
public HashedCache( @NotNull Map store, @NotNull Factory factory ) {
this.factory = factory;
//noinspection AssignmentToCollectionOrArrayFieldFromParameter
this.store = store;
}
/**
* Returns the value for the given key.
* If no value is stored, a new one is created using the registered factory
*
* @param key the key
* @return the value
*/
public T get( @NotNull Object key ) {
lock.writeLock().lock();
try {
T element = store.get( key );
if ( element == null ) {
element = factory.create( ( K ) key );
store.put( ( K ) key, element );
}
return element;
} finally {
lock.writeLock().unlock();
}
}
/*
MAP DELEGATES
*/
public boolean containsKey( Object key ) {
lock.readLock().lock();
try {
return store.containsKey( key );
} finally {
lock.readLock().unlock();
}
}
public boolean containsValue( Object value ) {
lock.readLock().lock();
try {
return store.containsValue( value );
} finally {
lock.readLock().unlock();
}
}
public T put( K key, T value ) {
throw new UnsupportedOperationException( "Use the factory instead" );
}
@Nullable
public T remove( @NotNull Object key ) {
lock.writeLock().lock();
try {
return store.remove( key );
} finally {
lock.writeLock().unlock();
}
}
public void putAll( Map extends K, ? extends T> m ) {
throw new UnsupportedOperationException( "Use the factory instead" );
}
public Set keySet() {
lock.readLock().lock();
try {
return store.keySet();
} finally {
lock.readLock().unlock();
}
}
public Collection values() {
lock.readLock().lock();
try {
return store.values();
} finally {
lock.readLock().unlock();
}
}
/**
* Returns the *LIVE* entry set. Use with care!
*
* @return the live entry set for the cache
*/
@NotNull
public Set> entrySet() {
lock.readLock().lock();
try {
return store.entrySet();
} finally {
lock.readLock().unlock();
}
}
public int size() {
lock.readLock().lock();
try {
return store.size();
} finally {
lock.readLock().unlock();
}
}
public boolean isEmpty() {
lock.readLock().lock();
try {
return store.isEmpty();
} finally {
lock.readLock().unlock();
}
}
/**
* Returns the internal store.
* USE WITH CARE!
*/
@Deprecated
@NotNull
public Map getInternalStore() {
lock.readLock().lock();
try {
//noinspection ReturnOfCollectionOrArrayField
return store;
} finally {
lock.readLock().unlock();
}
}
public void clear() {
throw new UnsupportedOperationException();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy