Skip to content

Instantly share code, notes, and snippets.

@harawata
Last active December 31, 2015 01:48
Show Gist options
  • Save harawata/7916072 to your computer and use it in GitHub Desktop.
Save harawata/7916072 to your computer and use it in GitHub Desktop.
A custom Cache implementation for MyBatis using BlockingCache.
package org.mybatis.caches.ehcache;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.constructs.blocking.BlockingCache;
import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.cache.CacheException;
public class EhBlockingCache implements Cache {
private static final CacheManager CACHE_MANAGER = CacheManager.create();
private final ReadWriteLock readWriteLock = new ReadWriteLock() {
private Lock lock = new DummyLock();
public Lock readLock() {
return lock;
}
public Lock writeLock() {
return lock;
}
class DummyLock implements Lock {
public void lock() {
}
public void lockInterruptibly() throws InterruptedException {
}
public boolean tryLock() {
return true;
}
public boolean tryLock(long paramLong, TimeUnit paramTimeUnit) throws InterruptedException {
return true;
}
public void unlock() {
}
public Condition newCondition() {
return null;
}
}
};
private final String id;
public EhBlockingCache(final String id) {
if (id == null) {
throw new IllegalArgumentException("Cache instances require an ID");
}
this.id = id;
if (!CACHE_MANAGER.cacheExists(this.id)) {
CACHE_MANAGER.addCache(this.id);
Ehcache ehcache = CACHE_MANAGER.getEhcache(this.id);
BlockingCache blockingCache = new BlockingCache(ehcache);
CACHE_MANAGER.replaceCacheWithDecoratedCache(ehcache, blockingCache);
}
}
public void clear() {
this.getCache().removeAll();
}
public String getId() {
return this.id;
}
public Object getObject(Object key) {
try {
Element cachedElement = this.getCache().get(key);
if (cachedElement == null) {
return null;
}
return cachedElement.getObjectValue();
} catch (Throwable t) {
throw new CacheException(t);
}
}
public ReadWriteLock getReadWriteLock() {
return this.readWriteLock;
}
public int getSize() {
try {
return this.getCache().getSize();
} catch (Throwable t) {
throw new CacheException(t);
}
}
public void putObject(Object key, Object value) {
try {
this.getCache().put(new Element(key, value));
} catch (Throwable t) {
throw new CacheException(t);
}
}
public Object removeObject(Object key) {
try {
Object obj = this.getObject(key);
this.getCache().remove(key);
return obj;
} catch (Throwable t) {
throw new CacheException(t);
}
}
private Ehcache getCache() {
return CACHE_MANAGER.getEhcache(this.id);
}
private CacheConfiguration getCacheConfiguration() {
return this.getCache().getCacheConfiguration();
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Cache)) {
return false;
}
Cache otherCache = (Cache) obj;
return this.id.equals(otherCache.getId());
}
public int hashCode() {
return this.id.hashCode();
}
public String toString() {
return "EHBlockingCache {" + this.id + "}";
}
/**
* Sets the time to idle for an element before it expires. Is only used if the element is not eternal.
*
* @param timeToIdleSeconds
* the default amount of time to live for an element from its last accessed or modified date
*/
public void setTimeToIdleSeconds(long timeToIdleSeconds) {
this.getCacheConfiguration().setTimeToIdleSeconds(timeToIdleSeconds);
}
/**
* Sets the time to idle for an element before it expires. Is only used if the element is not eternal.
*
* @param timeToLiveSeconds
* the default amount of time to live for an element from its creation date
*/
public void setTimeToLiveSeconds(long timeToLiveSeconds) {
this.getCacheConfiguration().setTimeToLiveSeconds(timeToLiveSeconds);
}
/**
* Sets the maximum objects to be held in memory (0 = no limit).
*
* @param maxElementsInMemory
* The maximum number of elements in memory, before they are evicted (0 == no limit)
*/
public void setMaxEntriesLocalHeap(long maxEntriesLocalHeap) {
this.getCacheConfiguration().setMaxEntriesLocalHeap(maxEntriesLocalHeap);
}
/**
* Sets the maximum number elements on Disk. 0 means unlimited.
*
* @param maxElementsOnDisk
* the maximum number of Elements to allow on the disk. 0 means unlimited.
*/
public void setMaxEntriesLocalDisk(long maxEntriesLocalDisk) {
this.getCacheConfiguration().setMaxEntriesLocalDisk(maxEntriesLocalDisk);
}
/**
* Sets the eviction policy. An invalid argument will set it to null.
*
* @param memoryStoreEvictionPolicy
* a String representation of the policy. One of "LRU", "LFU" or "FIFO".
*/
public void setMemoryStoreEvictionPolicy(String memoryStoreEvictionPolicy) {
this.getCacheConfiguration().setMemoryStoreEvictionPolicy(memoryStoreEvictionPolicy);
}
/**
* Sets the time to wait to acquire a lock.
*
* @param timeoutMillis the time in ms. Must be a positive number. 0 means wait forever.
*/
public void setTimeoutMillis(int timeoutMillis) {
((BlockingCache)this.getCache()).setTimeoutMillis(timeoutMillis);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment