Warning: session_start(): open(/var/lib/php/sessions/sess_ou6pmjgcrnedgegfjjk840fr8d, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
// Copyright (c) 2017 Pierantonio Cangianiello (original name: SelfExpiringHashMap)
// thread-safe.
sclass ExpiringHashMap implements Map {
final Map internalMap;
final Map> expiringKeys;
final DelayQueue delayQueue = new DelayQueue();
long maxLifeTimeMillis;
bool renewOnGet, renewOnOverwrite = true;
*() {
this(Long.MAX_VALUE);
}
*(long defaultMaxLifeTimeMillis) {
internalMap = new ConcurrentHashMap();
expiringKeys = new WeakHashMap>();
this.maxLifeTimeMillis = defaultMaxLifeTimeMillis;
}
public int size() {
cleanup();
return internalMap.size();
}
public boolean isEmpty() {
cleanup();
return internalMap.isEmpty();
}
public boolean containsKey(Object key) {
cleanup();
return internalMap.containsKey((K) key);
}
public boolean containsValue(Object value) {
cleanup();
return internalMap.containsValue((V) value);
}
public V get(Object key) {
cleanup();
if (renewOnGet) renewKey((K) key);
return internalMap.get((K) key);
}
public V put(K key, V value) {
return this.put(key, value, maxLifeTimeMillis);
}
public V put(K key, V value, long lifeTimeMillis) {
cleanup();
ExpiringKey delayedKey = new ExpiringKey(key, lifeTimeMillis);
ExpiringKey oldKey = expiringKeys.put((K) key, delayedKey);
if(oldKey != null) {
if (!renewOnOverwrite) {
delayedKey.startTime = oldKey.startTime;
delayedKey.maxLifeTimeMillis = oldKey.maxLifeTimeMillis;
}
expireKey(oldKey);
expiringKeys.put((K) key, delayedKey);
}
delayQueue.offer(delayedKey);
return internalMap.put(key, value);
}
public V remove(Object key) {
V removedValue = internalMap.remove((K) key);
expireKey(expiringKeys.remove((K) key));
return removedValue;
}
public void putAll(Map extends K, ? extends V> m) {
throw new UnsupportedOperationException();
}
public boolean renewKey(K key) {
ExpiringKey delayedKey = expiringKeys.get((K) key);
if (delayedKey != null) {
delayedKey.renew();
return true;
}
return false;
}
private void expireKey(ExpiringKey delayedKey) {
if (delayedKey != null) {
delayedKey.expire();
cleanup();
}
}
public void clear() {
delayQueue.clear();
expiringKeys.clear();
internalMap.clear();
}
public Set keySet() {
cleanup();
ret internalMap.keySet(); // TODO: sync
}
public Collection values() {
throw new UnsupportedOperationException();
}
public Set> entrySet() {
throw new UnsupportedOperationException();
}
private void cleanup() {
ExpiringKey delayedKey = delayQueue.poll();
while (delayedKey != null) {
internalMap.remove(delayedKey.getKey());
expiringKeys.remove(delayedKey.getKey());
delayedKey = delayQueue.poll();
}
}
class ExpiringKey implements Delayed {
private long startTime = System.currentTimeMillis();
private long maxLifeTimeMillis;
private final K key;
public ExpiringKey(K key, long maxLifeTimeMillis) {
this.maxLifeTimeMillis = maxLifeTimeMillis;
this.key = key;
}
public K getKey() {
return key;
}
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ExpiringKey other = (ExpiringKey) obj;
if (this.key != other.key && (this.key == null || !this.key.equals(other.key))) {
return false;
}
return true;
}
public int hashCode() {
int hash = 7;
hash = 31 * hash + (this.key != null ? this.key.hashCode() : 0);
return hash;
}
public long getDelay(TimeUnit unit) {
return unit.convert(getDelayMillis(), TimeUnit.MILLISECONDS);
}
private long getDelayMillis() {
return (startTime + maxLifeTimeMillis) - System.currentTimeMillis();
}
public void renew() {
startTime = System.currentTimeMillis();
}
public void expire() {
startTime = System.currentTimeMillis() - maxLifeTimeMillis - 1;
}
public int compareTo(Delayed that) {
return Long.compare(this.getDelayMillis(), ((ExpiringKey) that).getDelayMillis());
}
}
ExpiringHashMap dontRenewOnOverwrite() {
renewOnOverwrite = false;
this;
}
}