package com.rubiconproject.oss.kv.backends;
import java.io.IOException;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sf.ehcache.config.Configuration;
import com.rubiconproject.oss.kv.BaseManagedKeyValueStore;
import com.rubiconproject.oss.kv.KeyValueStoreException;
import com.rubiconproject.oss.kv.annotations.Configurable;
import com.rubiconproject.oss.kv.annotations.Configurable.Type;
import com.rubiconproject.oss.kv.transcoder.Transcoder;
public class EhCacheKeyValueStore extends BaseManagedKeyValueStore {
public static final String IDENTIFIER = "ehcache";
private String cacheName = "ehcache";
private int capacity = 5000;
private long capacityBytes = 0;
private int timeToLiveSeconds = 60;
private int timeToIdleSeconds = 60;
private CacheManager mgr;
private Cache cache;
public EhCacheKeyValueStore() {
}
@Configurable(name = "cacheName", accepts = Type.StringType)
public void setCacheName(String cacheName) {
this.cacheName = cacheName;
}
@Configurable(name = "cacheCapacity", accepts = Type.IntType)
public void setCacheCapacity(int capacity) {
this.capacity = capacity;
}
@Configurable(name = "cacheHeapBytes", accepts = Type.LongType)
public void setCacheHeapBytes(long bytes) {
this.capacityBytes = bytes;
}
@Configurable(name = "timeToLive", accepts = Type.IntType)
public void setTimeToLive(int timeToLiveSeconds) {
this.timeToLiveSeconds = timeToLiveSeconds;
}
@Configurable(name = "timeToIdle", accepts = Type.IntType)
public void setTimeToIdle(int timeToIdleSeconds) {
this.timeToIdleSeconds = timeToIdleSeconds;
}
public String getIdentifier() {
return IDENTIFIER;
}
public void start() throws IOException {
if (capacityBytes == 0) {
mgr = CacheManager.create();
} else {
// Default value in default config is also 0,
// but might as well play it safe
Configuration managerConfig = new Configuration();
managerConfig.setMaxBytesLocalHeap(capacityBytes);
mgr = CacheManager.create(managerConfig);
}
cache = new Cache(cacheName, capacity, false, false, timeToLiveSeconds,
timeToIdleSeconds);
mgr.addCache(cache);
super.start();
}
public void stop() {
CacheManager.getInstance().shutdown();
cache = null;
mgr = null;
super.stop();
}
public boolean exists(String key) throws KeyValueStoreException,
IOException {
assertReadable();
boolean result = false;
Element el = cache.get(key);
result = (el == null) ? false : true;
return result;
}
public Object get(String key) throws KeyValueStoreException, IOException {
assertReadable();
Element el = cache.get(key);
return (el == null) ? null : el.getObjectValue();
}
public Object get(String key, Transcoder transcoder)
throws KeyValueStoreException, IOException {
return get(key);
}
public Map<String, Object> getBulk(String... keys)
throws KeyValueStoreException, IOException {
Map<String, Object> results = new HashMap<String, Object>();
for (String key : keys) {
Object obj = get(key);
if (obj != null)
results.put(key, obj);
}
return results;
}
public Map<String, Object> getBulk(final List<String> keys)
throws KeyValueStoreException, IOException {
Map<String, Object> results = new HashMap<String, Object>();
for (String key : keys) {
Object obj = get(key);
if (obj != null)
results.put(key, obj);
}
return results;
}
public Map<String, Object> getBulk(final List<String> keys,
Transcoder transcoder) throws KeyValueStoreException, IOException {
Map<String, Object> results = new HashMap<String, Object>();
for (String key : keys) {
Object obj = get(key, transcoder);
if (obj != null)
results.put(key, obj);
}
return results;
}
public void set(String key, Object value) throws KeyValueStoreException,
IOException {
assertWriteable();
cache.put(new Element(key, value));
}
public void set(String key, Object value, Transcoder transcoder)
throws KeyValueStoreException, IOException {
assertWriteable();
set(key, value);
}
public void set(String key, Object value, int timeToIdleSeconds,
int timeToLiveSeconds) throws KeyValueStoreException, IOException {
assertWriteable();
cache.put(new Element(key, value, Boolean.FALSE, timeToIdleSeconds,
timeToLiveSeconds));
}
public void delete(String key) throws KeyValueStoreException, IOException {
assertWriteable();
cache.remove(key);
}
}