Removed DBBean garbage collector

it it is not needed with WeakReference anymore
This commit is contained in:
Ziver Koc 2018-11-03 20:52:06 +01:00
parent 0ba153b118
commit f8a46f2089

View file

@ -17,96 +17,36 @@ import java.util.logging.Logger;
*/ */
class DBBeanCache { class DBBeanCache {
private static final Logger logger = LogUtil.getLogger(); private static final Logger logger = LogUtil.getLogger();
/** This is the time to live for the cached items **/ /**
public static final long CACHE_DATA_TTL = 1000*60*5; // 5 min in ms * This is the time to live for the cached items
/** A cache for detecting recursion **/ **/
public static final long CACHE_DATA_TTL = 1000 * 60 * 5; // 5 min in ms
/**
* A cache for detecting recursion
**/
private static Map<Class<?>, Map<Long, CacheItem>> cache = private static Map<Class<?>, Map<Long, CacheItem>> cache =
new ConcurrentHashMap<>(); new ConcurrentHashMap<>();
private static ScheduledExecutorService executor;
static {
enableBeanGBC(true); // Initiate DBBeanGarbageCollector
}
/** /**
* A cache container that contains a bean and its last filed update time * A cache container that contains a bean and its last filed update time
*/ */
private static class CacheItem{ private static class CacheItem {
public long updateTimestamp; public long updateTimestamp;
public WeakReference<DBBean> bean; public WeakReference<DBBean> bean;
} }
public static boolean contains(DBBean obj) {
/**
* This function cancels the internal cache garbage collector in DBBean.
* GBC is enabled by default
*/
public static synchronized void enableBeanGBC(boolean enable){
if(enable){
if( executor == null ){
executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate( new DBBeanGarbageCollector(), CACHE_DATA_TTL, CACHE_DATA_TTL *2, TimeUnit.MILLISECONDS );
logger.fine("Bean garbage collection daemon enabled");
}
}
else {
if (executor != null) {
executor.shutdown();
executor = null;
logger.fine("Bean garbage collection daemon disabled");
}
}
}
/**
* This class acts as an garbage collector that removes old DBBeans
*/
private static class DBBeanGarbageCollector implements Runnable {
public void run() {
try {
if (cache == null) {
logger.severe("DBBeanSQLResultHandler not initialized, stopping DBBeanGarbageCollector timer.");
enableBeanGBC(false);
return;
}
int removed = 0;
for (Object classKey : cache.keySet()) {
if (classKey == null) continue;
Map<Long, CacheItem> class_cache = cache.get(classKey);
for (Iterator<Map.Entry<Long, CacheItem>> it = class_cache.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<Long, CacheItem> entry = it.next();
if (entry.getKey() == null) continue;
// Check if session is still valid
if (entry.getValue().bean.get() == null) {
it.remove();
removed++;
}
}
}
if (removed > 0)
logger.info("DBBean GarbageCollector has cleared " + removed + " beans from cache.");
} catch (Exception e) {
logger.log(Level.SEVERE, "DBBeanGarbageCollector thread has crashed", e);
}
}
}
public static boolean contains(DBBean obj){
if (obj == null) if (obj == null)
return false; return false;
return contains(obj.getClass(), obj.getId()); return contains(obj.getClass(), obj.getId());
} }
public static boolean contains(Class<?> c, Long id){
if( cache.containsKey(c) ){ public static boolean contains(Class<?> c, Long id) {
if (cache.containsKey(c)) {
CacheItem cacheItem = cache.get(c).get(id); CacheItem cacheItem = cache.get(c).get(id);
// Check if the cache is valid // Check if the cache is valid
if( cacheItem != null && cacheItem.bean.get() != null ) { if (cacheItem != null && cacheItem.bean.get() != null) {
return true; return true;
} else { } else {
// The bean has been deallocated // The bean has been deallocated
@ -124,19 +64,19 @@ class DBBeanCache {
* @return a cached DBBean object, null if there is a cache miss * @return a cached DBBean object, null if there is a cache miss
*/ */
public static DBBean get(Class<?> c, Long id) { public static DBBean get(Class<?> c, Long id) {
if(contains(c, id)){ if (contains(c, id)) {
CacheItem cacheItem = cache.get(c).get(id); CacheItem cacheItem = cache.get(c).get(id);
return cacheItem.bean.get(); return cacheItem.bean.get();
} }
logger.finer("Bean("+c.getName()+") cache miss for id: "+id); logger.finer("Bean(" + c.getName() + ") cache miss for id: " + id);
return null; return null;
} }
/** /**
* @return true if the bean data is outdated, false if the data is current or if the bean was not found in the cache * @return true if the bean data is outdated, false if the data is current or if the bean was not found in the cache
*/ */
public static boolean isOutDated(DBBean obj){ public static boolean isOutDated(DBBean obj) {
if(contains(obj)) { if (contains(obj)) {
CacheItem cacheItem = cache.get(obj.getClass()).get(obj.getId()); CacheItem cacheItem = cache.get(obj.getClass()).get(obj.getId());
return cacheItem.updateTimestamp + CACHE_DATA_TTL < System.currentTimeMillis(); return cacheItem.updateTimestamp + CACHE_DATA_TTL < System.currentTimeMillis();
} }
@ -152,21 +92,23 @@ class DBBeanCache {
cache.get(obj.getClass()).get(obj.getId()).updateTimestamp = System.currentTimeMillis(); cache.get(obj.getClass()).get(obj.getId()).updateTimestamp = System.currentTimeMillis();
return; return;
} }
CacheItem cacheItem = new CacheItem(); CacheItem cacheItem = new CacheItem();
cacheItem.updateTimestamp = System.currentTimeMillis(); cacheItem.updateTimestamp = System.currentTimeMillis();
cacheItem.bean = new WeakReference<>(obj); cacheItem.bean = new WeakReference<>(obj);
if( cache.containsKey(obj.getClass()) )
if (cache.containsKey(obj.getClass()))
cache.get(obj.getClass()).put(obj.getId(), cacheItem); cache.get(obj.getClass()).put(obj.getId(), cacheItem);
else{ else {
Map<Long, CacheItem> map = new ConcurrentHashMap<>(); Map<Long, CacheItem> map = new ConcurrentHashMap<>();
map.put(obj.getId(), cacheItem); map.put(obj.getId(), cacheItem);
cache.put(obj.getClass(), map); cache.put(obj.getClass(), map);
} }
} }
public static void remove(DBBean obj){ public static void remove(DBBean obj) {
if (obj != null) if (obj != null)
if( cache.containsKey(obj.getClass()) ) if (cache.containsKey(obj.getClass()))
cache.get(obj.getClass()).remove(obj.getId()); cache.get(obj.getClass()).remove(obj.getId());
} }
} }