remove event types
We only have removal events. The additional complexity of having a generic interface for many different event types does not pay off.
This commit is contained in:
@@ -3,9 +3,7 @@ package org.lucares.utils.cache;
|
||||
import java.time.Clock;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
@@ -40,30 +38,20 @@ public class HotEntryCache<K, V> {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(HotEntryCache.class);
|
||||
|
||||
public enum EventType {
|
||||
EVICTED, REMOVED
|
||||
}
|
||||
|
||||
public interface EventListener<K, V> {
|
||||
public void onEvent(Event<K, V> event);
|
||||
public void onRemove(K key, V value);
|
||||
}
|
||||
|
||||
public static class Event<K, V> {
|
||||
private final EventType eventType;
|
||||
private final K key;
|
||||
private final V value;
|
||||
|
||||
public Event(final EventType eventType, final K key, final V value) {
|
||||
public Event(final K key, final V value) {
|
||||
super();
|
||||
this.eventType = eventType;
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public EventType getEventType() {
|
||||
return eventType;
|
||||
}
|
||||
|
||||
public K getKey() {
|
||||
return key;
|
||||
}
|
||||
@@ -74,26 +62,7 @@ public class HotEntryCache<K, V> {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Event [eventType=" + eventType + ", key=" + key + ", value=" + value + "]";
|
||||
}
|
||||
}
|
||||
|
||||
private final static class EventSubscribers<K, V> {
|
||||
private final EnumSet<EventType> subscribedEvents;
|
||||
private final EventListener<K, V> listener;
|
||||
|
||||
public EventSubscribers(final EnumSet<EventType> subscribedEvents, final EventListener<K, V> listener) {
|
||||
super();
|
||||
this.subscribedEvents = subscribedEvents;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public EnumSet<EventType> getSubscribedEvents() {
|
||||
return subscribedEvents;
|
||||
}
|
||||
|
||||
public EventListener<K, V> getListener() {
|
||||
return listener;
|
||||
return "Event [key=" + key + ", value=" + value + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,6 +128,7 @@ public class HotEntryCache<K, V> {
|
||||
synchronized (lock) {
|
||||
keySet.addAll(weakCaches.keySet());
|
||||
}
|
||||
LOGGER.trace("update time");
|
||||
for (final HotEntryCache<?, ?> cache : keySet) {
|
||||
cache.updateTime();
|
||||
}
|
||||
@@ -214,8 +184,8 @@ public class HotEntryCache<K, V> {
|
||||
timeToNextEviction = normalizeDurationToNextEviction(minNextEvictionTime);
|
||||
|
||||
if (future != null) {
|
||||
future.complete(null);
|
||||
this.future.set(null);
|
||||
future.complete(null);
|
||||
}
|
||||
} catch (final ConcurrentModificationException e) {
|
||||
// ignore: might happen if an entry in weakCaches is garbage collected
|
||||
@@ -304,7 +274,7 @@ public class HotEntryCache<K, V> {
|
||||
*/
|
||||
private final ConcurrentHashMap<K, Entry<V>> cache = new ConcurrentHashMap<>();
|
||||
|
||||
private final CopyOnWriteArrayList<EventSubscribers<K, V>> listeners = new CopyOnWriteArrayList<>();
|
||||
private final CopyOnWriteArrayList<EventListener<K, V>> listeners = new CopyOnWriteArrayList<>();
|
||||
|
||||
private final Duration timeToLive;
|
||||
|
||||
@@ -342,8 +312,8 @@ public class HotEntryCache<K, V> {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void addListener(final EventListener<K, V> listener, final EventType... eventTypes) {
|
||||
listeners.add(new EventSubscribers<>(EnumSet.copyOf(Arrays.asList(eventTypes)), listener));
|
||||
public void addListener(final EventListener<K, V> listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
static void setMinSleepPeriod(final Duration minSleepPeriod) {
|
||||
@@ -436,7 +406,7 @@ public class HotEntryCache<K, V> {
|
||||
final AtomicReference<Entry<V>> oldValue = new AtomicReference<>();
|
||||
cache.computeIfPresent(key, (k, e) -> {
|
||||
oldValue.set(e);
|
||||
handleEvent(EventType.REMOVED, k, e.getValue());
|
||||
handleEvent(k, e.getValue());
|
||||
return null;
|
||||
});
|
||||
return oldValue.get() != null ? oldValue.get().getValue() : null;
|
||||
@@ -477,7 +447,7 @@ public class HotEntryCache<K, V> {
|
||||
|
||||
cache.computeIfPresent(keyToBeRemoved, (k, e) -> {
|
||||
if (isExpired(e, now)) {
|
||||
handleEvent(EventType.EVICTED, k, e.getValue());
|
||||
handleEvent(k, e.getValue());
|
||||
return null;
|
||||
}
|
||||
return e;
|
||||
@@ -520,12 +490,12 @@ public class HotEntryCache<K, V> {
|
||||
return entry.getLastAccessed().plus(timeToLive).isBefore(now);
|
||||
}
|
||||
|
||||
private void handleEvent(final EventType eventType, final K key, final V value) {
|
||||
private void handleEvent(final K key, final V value) {
|
||||
|
||||
for (final EventListener<K, V> eventSubscribers : listeners) {
|
||||
|
||||
eventSubscribers.onRemove(key, value);
|
||||
|
||||
for (final EventSubscribers<K, V> eventSubscribers : listeners) {
|
||||
if (eventSubscribers.getSubscribedEvents().contains(eventType)) {
|
||||
eventSubscribers.getListener().onEvent(new Event<>(eventType, key, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user