refactoring

pull/6249/head
Nikita Koksharov 4 months ago
parent 1a92a610f8
commit 71e5c16ead

@ -23,10 +23,11 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
/**
*
*
* @author Nikita Koksharov
*
* @param <K> key
@ -38,6 +39,7 @@ public abstract class AbstractCacheMap<K, V> implements Cache<K, V> {
final ConcurrentMap<K, CachedValue<K, V>> map = new ConcurrentHashMap<>();
private final long timeToLiveInMillis;
private final long maxIdleInMillis;
private Consumer<CachedValue<K, V>> removalListener;
public AbstractCacheMap(int size, long timeToLiveInMillis, long maxIdleInMillis) {
@ -50,14 +52,19 @@ public abstract class AbstractCacheMap<K, V> implements Cache<K, V> {
}
protected void onValueRead(CachedValue<K, V> value) {
}
protected void onValueRemove(CachedValue<K, V> value) {
if (removalListener != null) {
removalListener.accept(value);
}
}
public final void removalListener(Consumer<CachedValue<K, V>> removalListener) {
this.removalListener = removalListener;
}
/*
* (non-Javadoc)
* @see java.util.Map#size()
@ -85,7 +92,7 @@ public abstract class AbstractCacheMap<K, V> implements Cache<K, V> {
if (key == null) {
throw new NullPointerException();
}
CachedValue<K, V> entry = map.get(key);
if (entry == null) {
return false;
@ -147,7 +154,7 @@ public abstract class AbstractCacheMap<K, V> implements Cache<K, V> {
if (key == null) {
throw new NullPointerException();
}
CachedValue<K, V> entry = map.get(key);
if (entry == null) {
return null;
@ -166,7 +173,7 @@ public abstract class AbstractCacheMap<K, V> implements Cache<K, V> {
onValueRead(entry);
return (V) entry.getValue();
}
/*
* (non-Javadoc)
* @see java.util.Map#put(java.lang.Object, java.lang.Object)
@ -175,7 +182,7 @@ public abstract class AbstractCacheMap<K, V> implements Cache<K, V> {
public V put(K key, V value) {
return put(key, value, timeToLiveInMillis, TimeUnit.MILLISECONDS, maxIdleInMillis, TimeUnit.MILLISECONDS);
}
private V put(K key, V value, long ttl, TimeUnit ttlUnit, long maxIdleTime, TimeUnit maxIdleUnit) {
CachedValue<K, V> entry = create(key, value, ttlUnit.toMillis(ttl), maxIdleUnit.toMillis(maxIdleTime));
if (isFull(key)) {
@ -197,7 +204,7 @@ public abstract class AbstractCacheMap<K, V> implements Cache<K, V> {
protected CachedValue<K, V> create(K key, V value, long ttl, long maxIdleTime) {
return new StdCachedValue<K, V>(key, value, ttl, maxIdleTime);
}
protected void onValueCreate(CachedValue<K, V> entry) {
}
@ -211,7 +218,7 @@ public abstract class AbstractCacheMap<K, V> implements Cache<K, V> {
for (CachedValue<K, V> value : map.values()) {
if (isValueExpired(value)) {
if (map.remove(value.getKey(), value)) {
onValueRemove(value);
onValueRemove(value);
removed = true;
}
}
@ -230,7 +237,7 @@ public abstract class AbstractCacheMap<K, V> implements Cache<K, V> {
}
return false;
}
/*
* (non-Javadoc)
* @see java.util.Map#remove(java.lang.Object)
@ -246,7 +253,7 @@ public abstract class AbstractCacheMap<K, V> implements Cache<K, V> {
}
return null;
}
/*
* (non-Javadoc)
* @see java.util.Map#putAll(java.util.Map)
@ -297,13 +304,13 @@ public abstract class AbstractCacheMap<K, V> implements Cache<K, V> {
removeExpiredEntries();
return new EntrySet();
}
abstract class MapIterator<M> implements Iterator<M> {
private final Iterator<Map.Entry<K, CachedValue<K, V>>> keyIterator = map.entrySet().iterator();
Map.Entry<K, CachedValue<K, V>> mapEntry;
@Override
public boolean hasNext() {
if (mapEntry != null) {
@ -313,7 +320,7 @@ public abstract class AbstractCacheMap<K, V> implements Cache<K, V> {
while (keyIterator.hasNext()) {
Map.Entry<K, CachedValue<K, V>> entry = keyIterator.next();
if (isValueExpired(entry.getValue())) {
continue;
continue;
}
mapEntry = entry;
break;
@ -339,7 +346,7 @@ public abstract class AbstractCacheMap<K, V> implements Cache<K, V> {
if (mapEntry == null) {
throw new NoSuchElementException();
}
K key = mapEntry.getKey();
mapEntry = null;
return key;
@ -388,7 +395,7 @@ public abstract class AbstractCacheMap<K, V> implements Cache<K, V> {
if (mapEntry == null) {
throw new NoSuchElementException();
}
V value = readValue(mapEntry.getValue());
mapEntry = null;
return value;
@ -431,7 +438,7 @@ public abstract class AbstractCacheMap<K, V> implements Cache<K, V> {
if (mapEntry == null) {
throw new NoSuchElementException();
}
SimpleEntry<K, V> result = new SimpleEntry<K, V>(mapEntry.getKey(), readValue(mapEntry.getValue()));
mapEntry = null;
return result;
@ -572,4 +579,4 @@ public abstract class AbstractCacheMap<K, V> implements Cache<K, V> {
return null;
}
}
}

@ -84,28 +84,29 @@ public class LFUCacheMap<K, V> extends AbstractCacheMap<K, V> {
protected CachedValue<K, V> create(K key, V value, long ttl, long maxIdleTime) {
return new LFUCachedValue<K, V>(idGenerator.incrementAndGet(), key, value, ttl, maxIdleTime);
}
@Override
protected void onValueCreate(CachedValue<K, V> value) {
MapKey key = toKey((LFUCachedValue<K, V>) value);
accessMap.put(key, (LFUCachedValue<K, V>) value);
}
@Override
protected void onValueRead(CachedValue<K, V> value) {
addAccessCount((LFUCachedValue<K, V>) value, 1);
}
private MapKey toKey(LFUCachedValue<K, V> value) {
return new MapKey(value.accessCount, value);
}
@Override
protected void onValueRemove(CachedValue<K, V> value) {
value.getLock().execute(() -> {
MapKey key = toKey((LFUCachedValue<K, V>) value);
accessMap.remove(key);
});
super.onValueRemove(value);
}
private void addAccessCount(LFUCachedValue<K, V> value, long c) {
@ -136,8 +137,10 @@ public class LFUCacheMap<K, V> extends AbstractCacheMap<K, V> {
if (entry == null) {
return;
}
map.remove(entry.getValue().getKey(), entry.getValue());
if (map.remove(entry.getValue().getKey(), entry.getValue())) {
super.onValueRemove(entry.getValue());
}
if (entry.getValue().accessCount == 0) {
return;
}
@ -154,5 +157,5 @@ public class LFUCacheMap<K, V> extends AbstractCacheMap<K, V> {
accessMap.clear();
super.clear();
}
}
}

@ -74,7 +74,7 @@ public class LRUCacheMap<K, V> extends AbstractCacheMap<K, V> {
public LRUCacheMap(int size, long timeToLiveInMillis, long maxIdleInMillis) {
super(size, timeToLiveInMillis, maxIdleInMillis);
for (int i = 0; i < Runtime.getRuntime().availableProcessors()*2; i++) {
queues.add(new OrderedSet<>());
}
@ -89,13 +89,14 @@ public class LRUCacheMap<K, V> extends AbstractCacheMap<K, V> {
private OrderedSet<CachedValue<K, V>> getQueue(CachedValue<K, V> value) {
return queues.get(Math.abs(value.hashCode() % queues.size()));
}
@Override
protected void onValueRemove(CachedValue<K, V> value) {
OrderedSet<CachedValue<K, V>> queue = getQueue(value);
queue.remove(value);
super.onValueRemove(value);
}
@Override
protected void onValueRead(CachedValue<K, V> value) {
OrderedSet<CachedValue<K, V>> queue = getQueue(value);
@ -120,12 +121,14 @@ public class LRUCacheMap<K, V> extends AbstractCacheMap<K, V> {
OrderedSet<CachedValue<K, V>> queue = queues.get(queueIndex);
CachedValue<K, V> removedValue = queue.removeFirst();
if (removedValue != null) {
map.remove(removedValue.getKey(), removedValue);
if (map.remove(removedValue.getKey(), removedValue)) {
super.onValueRemove(removedValue);
}
return;
}
}
}
@Override
public void clear() {
for (OrderedSet<CachedValue<K, V>> collection : queues) {

@ -49,7 +49,7 @@ public class ReferenceCacheMap<K, V> extends AbstractCacheMap<K, V> {
protected CachedValue<K, V> create(K key, V value, long ttl, long maxIdleTime) {
return new ReferenceCachedValue<K, V>(key, value, ttl, maxIdleTime, queue, type);
}
@Override
protected boolean isFull(K key) {
return true;
@ -62,13 +62,15 @@ public class ReferenceCacheMap<K, V> extends AbstractCacheMap<K, V> {
if (value == null) {
break;
}
map.remove(value.getOwner().getKey(), value.getOwner());
if (map.remove(value.getOwner().getKey(), value.getOwner())) {
onValueRemove((CachedValue<K, V>) value.getOwner());
}
}
return super.removeExpiredEntries();
}
@Override
protected void onMapFull() {
}
}
}
Loading…
Cancel
Save