
redis.clients.jedis.csc.AbstractCache Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.apache.servicemix.bundles.jedis
Show all versions of org.apache.servicemix.bundles.jedis
This OSGi bundle wraps the ${pkgArtifactId} ${pkgVersion} jar file.
The newest version!
package redis.clients.jedis.csc;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import redis.clients.jedis.annots.Experimental;
import redis.clients.jedis.util.SafeEncoder;
/**
* The class to manage the client-side caching. User can provide an of implementation of this class
* to the client object.
*/
@Experimental
public abstract class AbstractCache implements Cache {
private Cacheable cacheable;
private final Map>> redisKeysToCacheKeys = new ConcurrentHashMap<>();
private final int maximumSize;
private ReentrantLock lock = new ReentrantLock();
private volatile CacheStats stats = new CacheStats();
protected AbstractCache(int maximumSize) {
this(maximumSize, DefaultCacheable.INSTANCE);
}
protected AbstractCache(int maximumSize, Cacheable cacheable) {
this.maximumSize = maximumSize;
this.cacheable = cacheable;
}
// Cache interface methods
@Override
public int getMaxSize() {
return maximumSize;
}
@Override
public abstract int getSize();
@Override
public abstract Collection getCacheEntries();
@Override
public CacheEntry get(CacheKey cacheKey) {
CacheEntry entry = getFromStore(cacheKey);
if (entry != null) {
getEvictionPolicy().touch(cacheKey);
}
return entry;
}
@Override
public CacheEntry set(CacheKey cacheKey, CacheEntry entry) {
lock.lock();
try {
entry = putIntoStore(cacheKey, entry);
EvictionPolicy policy = getEvictionPolicy();
policy.touch(cacheKey);
CacheKey evictedKey = policy.evictNext();
if (evictedKey != null) {
delete(evictedKey);
stats.evict();
}
for (Object redisKey : cacheKey.getRedisKeys()) {
ByteBuffer mapKey = makeKeyForRedisKeysToCacheKeys(redisKey);
if (redisKeysToCacheKeys.containsKey(mapKey)) {
redisKeysToCacheKeys.get(mapKey).add(cacheKey);
} else {
Set> set = ConcurrentHashMap.newKeySet();
set.add(cacheKey);
redisKeysToCacheKeys.put(mapKey, set);
}
}
stats.load();
return entry;
} finally {
lock.unlock();
}
}
@Override
public boolean delete(CacheKey cacheKey) {
lock.lock();
try {
boolean removed = removeFromStore(cacheKey);
getEvictionPolicy().reset(cacheKey);
// removing it from redisKeysToCacheKeys as well
// TODO: considering not doing it, what is the impact of not doing it ??
for (Object redisKey : cacheKey.getRedisKeys()) {
ByteBuffer mapKey = makeKeyForRedisKeysToCacheKeys(redisKey);
Set> cacheKeysRelatedtoRedisKey = redisKeysToCacheKeys.get(mapKey);
if (cacheKeysRelatedtoRedisKey != null) {
cacheKeysRelatedtoRedisKey.remove(cacheKey);
}
}
return removed;
} finally {
lock.unlock();
}
}
@Override
public List delete(List cacheKeys) {
lock.lock();
try {
return cacheKeys.stream().map(this::delete).collect(Collectors.toList());
} finally {
lock.unlock();
}
}
@Override
public List deleteByRedisKey(Object key) {
lock.lock();
try {
final ByteBuffer mapKey = makeKeyForRedisKeysToCacheKeys(key);
Set> commands = redisKeysToCacheKeys.get(mapKey);
List cacheKeys = new ArrayList<>();
if (commands != null) {
cacheKeys.addAll(commands.stream().filter(this::removeFromStore).collect(Collectors.toList()));
stats.invalidationByServer(cacheKeys.size());
redisKeysToCacheKeys.remove(mapKey);
}
stats.invalidationMessages();
return cacheKeys;
} finally {
lock.unlock();
}
}
@Override
public List deleteByRedisKeys(List keys) {
if (keys == null) {
flush();
return null;
}
lock.lock();
try {
return ((List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy