Browse Source

add Expiration.maxExpiration, elements expire after this timeout even if they have been recently used

tags/2.0.1
Jonathan Cobb 5 years ago
parent
commit
677d1230bf
1 changed files with 16 additions and 32 deletions
  1. +16
    -32
      src/main/java/org/cobbzilla/util/collection/ExpirationMap.java

+ 16
- 32
src/main/java/org/cobbzilla/util/collection/ExpirationMap.java View File

@@ -2,6 +2,7 @@ package org.cobbzilla.util.collection;


import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;


import java.util.Collection; import java.util.Collection;
@@ -15,53 +16,36 @@ import java.util.stream.Collectors;
import static org.cobbzilla.util.daemon.ZillaRuntime.notSupported; import static org.cobbzilla.util.daemon.ZillaRuntime.notSupported;
import static org.cobbzilla.util.daemon.ZillaRuntime.now; import static org.cobbzilla.util.daemon.ZillaRuntime.now;


@Accessors(chain=true)
public class ExpirationMap<K, V> implements Map<K, V> { public class ExpirationMap<K, V> implements Map<K, V> {


private final Map<K, ExpirationMapEntry<V>> map; private final Map<K, ExpirationMapEntry<V>> map;
private long expiration = TimeUnit.HOURS.toMillis(1);
private long cleanInterval = TimeUnit.HOURS.toMillis(4);
private long lastCleaned = 0;


public ExpirationMap() {
this.map = new ConcurrentHashMap<>();
}

public ExpirationMap(long expiration) {
this.map = new ConcurrentHashMap<>();
this.expiration = expiration;
}
@Getter @Setter private long expiration = TimeUnit.HOURS.toMillis(1);
@Getter @Setter private long maxExpiration = TimeUnit.HOURS.toMillis(2);
@Getter @Setter private long cleanInterval = TimeUnit.HOURS.toMillis(4);


public ExpirationMap(long expiration, long cleanInterval) {
this(expiration);
this.cleanInterval = cleanInterval;
public ExpirationMap<K, V> setExpirations(long val) {
this.expiration = this.maxExpiration = this.cleanInterval = val;
return this;
} }


public ExpirationMap(long expiration, long cleanInterval, int initialCapacity) {
this.map = new ConcurrentHashMap<>(initialCapacity);
this.expiration = expiration;
this.cleanInterval = cleanInterval;
}

public ExpirationMap(long expiration, long cleanInterval, int initialCapacity, float loadFactor) {
this.map = new ConcurrentHashMap<>(initialCapacity, loadFactor);
this.expiration = expiration;
this.cleanInterval = cleanInterval;
}
private long lastCleaned = 0;


public ExpirationMap(long expiration, long cleanInterval, int initialCapacity, float loadFactor, int concurrencyLevel) {
this.map = new ConcurrentHashMap<>(initialCapacity, loadFactor, concurrencyLevel);
this.expiration = expiration;
this.cleanInterval = cleanInterval;
public ExpirationMap() {
this.map = new ConcurrentHashMap<>();
} }
public ExpirationMap(long val) { this(); setExpirations(val); }


@Accessors(chain=true) @Accessors(chain=true)
private class ExpirationMapEntry<VAL> { private class ExpirationMapEntry<VAL> {
public final VAL value; public final VAL value;
public volatile long ctime = now();
public volatile long atime = now(); public volatile long atime = now();
public ExpirationMapEntry(VAL value) { this.value = value; } public ExpirationMapEntry(VAL value) { this.value = value; }


public VAL touch() { atime = now(); return value; }
public boolean expired() { return now() > atime+expiration; }
public ExpirationMapEntry<VAL> touch() { atime = now(); return this; }
public boolean expired() { return now() > ctime+maxExpiration || now() > atime+expiration; }
} }


@Override public int size() { return map.size(); } @Override public int size() { return map.size(); }
@@ -79,7 +63,7 @@ public class ExpirationMap<K, V> implements Map<K, V> {


@Override public V get(Object key) { @Override public V get(Object key) {
final ExpirationMapEntry<V> value = map.get(key); final ExpirationMapEntry<V> value = map.get(key);
return value == null ? null : value.touch();
return value == null || value.touch().expired() ? null : value.touch().value;
} }


@Override public V put(K key, V value) { @Override public V put(K key, V value) {


Loading…
Cancel
Save