/**
*
*/
package com.eternus.ratelimit;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* {@link TokenStore} that uses a coarse-grained lock to manage access to the internal StoreEntry items.
*
* @author jabley
*
*/
public class CoarseMemoryTokenStore implements TokenStore {
/**
* The Map used to keep track of {@link StoreEntry} instances.
*/
private final Map<Key, StoreEntry> cache;
/**
* The lock used to synchronize on.
*/
private final Lock lock;
/**
* Creates a new {@link CoarseMemoryTokenStore}.
*/
public CoarseMemoryTokenStore() {
this.cache = new HashMap<Key, StoreEntry>();
this.lock = new ReentrantLock();
}
/**
* {@inheritDoc}
*/
public StoreEntry create(Key key, int timeToLiveInSecs) {
try {
StoreEntryImpl result = new StoreEntryImpl(timeToLiveInSecs);
cache.put(key, result);
return result;
} finally {
lock.unlock();
}
}
/**
* {@inheritDoc}
*/
public StoreEntry get(Key key) {
lock.lock();
StoreEntry result = cache.get(key);
if (!(result == null || result.isExpired())) {
/* cache hit with good entry - use it. */
lock.unlock();
return result;
} else {
/* cache miss or expired. keep the lock and the client will call #create(Key, int) */
result = null;
cache.put(key, result);
}
return result;
}
}