Changed DBBean from timestamp to WeakReference GBC
This commit is contained in:
parent
3da5abab98
commit
08b9da1d69
2 changed files with 35 additions and 44 deletions
|
|
@ -447,14 +447,6 @@ public abstract class DBBean {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This function cancels the internal cache garbage collector in DBBean
|
|
||||||
*/
|
|
||||||
public static void enableBeanGBC(boolean enable){
|
|
||||||
DBBeanSQLResultHandler.enableBeanGBC(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////// EXTENDABLE METHODS /////////////////////////
|
////////////////// EXTENDABLE METHODS /////////////////////////
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import zutil.db.SQLResultHandler;
|
||||||
import zutil.db.bean.DBBean.DBLinkTable;
|
import zutil.db.bean.DBBean.DBLinkTable;
|
||||||
import zutil.log.LogUtil;
|
import zutil.log.LogUtil;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
|
@ -41,7 +42,7 @@ import java.util.logging.Logger;
|
||||||
public class DBBeanSQLResultHandler<T> implements SQLResultHandler<T>{
|
public class DBBeanSQLResultHandler<T> implements SQLResultHandler<T>{
|
||||||
private static final Logger logger = LogUtil.getLogger();
|
private static final Logger logger = LogUtil.getLogger();
|
||||||
/** This is the time to live for the cached items **/
|
/** This is the time to live for the cached items **/
|
||||||
public static final long CACHE_TTL = 1000*60*5; // 5 min in ms
|
public static final long CACHE_DATA_TTL = 1000*60*5; // 5 min in ms
|
||||||
/** A cache for detecting recursion **/
|
/** A cache for detecting recursion **/
|
||||||
protected static Map<Class<?>, Map<Long,DBBeanCache>> cache =
|
protected static Map<Class<?>, Map<Long,DBBeanCache>> cache =
|
||||||
new ConcurrentHashMap<Class<?>, Map<Long,DBBeanCache>>();
|
new ConcurrentHashMap<Class<?>, Map<Long,DBBeanCache>>();
|
||||||
|
|
@ -54,9 +55,9 @@ public class DBBeanSQLResultHandler<T> implements SQLResultHandler<T>{
|
||||||
/**
|
/**
|
||||||
* A cache container that contains a object and last read time
|
* A cache container that contains a object and last read time
|
||||||
*/
|
*/
|
||||||
protected static class DBBeanCache{
|
private static class DBBeanCache{
|
||||||
public long timestamp;
|
public long updateTimestamp;
|
||||||
public DBBean bean;
|
public WeakReference<DBBean> bean;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Class<? extends DBBean> bean_class;
|
private Class<? extends DBBean> bean_class;
|
||||||
|
|
@ -124,11 +125,11 @@ public class DBBeanSQLResultHandler<T> implements SQLResultHandler<T>{
|
||||||
* This function cancels the internal cache garbage collector in DBBean.
|
* This function cancels the internal cache garbage collector in DBBean.
|
||||||
* GBC is enabled by default
|
* GBC is enabled by default
|
||||||
*/
|
*/
|
||||||
public static void enableBeanGBC(boolean enable){
|
private static void enableBeanGBC(boolean enable){
|
||||||
if(enable){
|
if(enable){
|
||||||
if( timer == null ){
|
if( timer == null ){
|
||||||
timer = new Timer( true ); // Run as daemon
|
timer = new Timer( true ); // Run as daemon
|
||||||
timer.schedule( new DBBeanGarbageCollector(), 10000, CACHE_TTL*2 );
|
timer.schedule( new DBBeanGarbageCollector(), CACHE_DATA_TTL, CACHE_DATA_TTL *2 );
|
||||||
logger.info("Bean garbage collection daemon enabled");
|
logger.info("Bean garbage collection daemon enabled");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -165,11 +166,9 @@ public class DBBeanSQLResultHandler<T> implements SQLResultHandler<T>{
|
||||||
|
|
||||||
DBBeanCache beanCache = class_cache.get(objKey);
|
DBBeanCache beanCache = class_cache.get(objKey);
|
||||||
// Check if session is still valid
|
// Check if session is still valid
|
||||||
if( beanCache.timestamp + CACHE_TTL < time ){
|
if( beanCache.bean.get() == null ){
|
||||||
class_cache.remove(objKey);
|
class_cache.remove(objKey);
|
||||||
removed++;
|
removed++;
|
||||||
logger.finer("Removing old Bean("+beanCache.bean.getClass().getName()+")" +
|
|
||||||
" from cache with id: "+beanCache.bean.getId());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -218,10 +217,8 @@ public class DBBeanSQLResultHandler<T> implements SQLResultHandler<T>{
|
||||||
return obj;
|
return obj;
|
||||||
logger.fine("Creating new Bean("+bean_class.getName()+") with id: "+id);
|
logger.fine("Creating new Bean("+bean_class.getName()+") with id: "+id);
|
||||||
obj = bean_class.newInstance();
|
obj = bean_class.newInstance();
|
||||||
cacheDBBean(obj, id);
|
obj.id = id; // Set id field
|
||||||
|
cacheDBBean(obj);
|
||||||
// Set id field
|
|
||||||
obj.id = id;
|
|
||||||
|
|
||||||
// Update fields
|
// Update fields
|
||||||
updateBean( result, obj );
|
updateBean( result, obj );
|
||||||
|
|
@ -229,7 +226,7 @@ public class DBBeanSQLResultHandler<T> implements SQLResultHandler<T>{
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new SQLException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -315,21 +312,24 @@ public class DBBeanSQLResultHandler<T> implements SQLResultHandler<T>{
|
||||||
*/
|
*/
|
||||||
protected DBBean getCachedDBBean(Class<?> c, Long id, ResultSet result) throws SQLException{
|
protected DBBean getCachedDBBean(Class<?> c, Long id, ResultSet result) throws SQLException{
|
||||||
if( cache.containsKey(c) ){
|
if( cache.containsKey(c) ){
|
||||||
DBBeanCache item = cache.get(c).get(id);
|
DBBeanCache cacheItem = cache.get(c).get(id);
|
||||||
// Check if the cache is valid
|
// Check if the cache is valid
|
||||||
if( item != null ){
|
if( cacheItem != null){
|
||||||
|
DBBean bean = cacheItem.bean.get();
|
||||||
|
if( bean != null) {
|
||||||
// The cache is old, update and return it
|
// The cache is old, update and return it
|
||||||
if( item.timestamp+CACHE_TTL < System.currentTimeMillis() ){
|
if (cacheItem.updateTimestamp + CACHE_DATA_TTL < System.currentTimeMillis()) {
|
||||||
// There is no ResultSet to update from
|
// There is no ResultSet to update from
|
||||||
if (result == null)
|
if (result == null)
|
||||||
return null;
|
return null;
|
||||||
// Only update object if there is no update running now
|
// Only update object if there is no update running now
|
||||||
if( !item.bean.processing_update ){
|
if (!bean.processing_update) {
|
||||||
logger.finer("Bean(" + c.getName() + ") cache to old for id: " + id);
|
logger.finer("Bean(" + c.getName() + ") cache to old for id: " + id);
|
||||||
updateBean( result, item.bean );
|
updateBean(result, bean);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return item.bean;
|
return bean;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// The cache is null
|
// The cache is null
|
||||||
cache.get(c).remove(id);
|
cache.get(c).remove(id);
|
||||||
|
|
@ -342,17 +342,16 @@ public class DBBeanSQLResultHandler<T> implements SQLResultHandler<T>{
|
||||||
* Adds the given object to the cache
|
* Adds the given object to the cache
|
||||||
*
|
*
|
||||||
* @param obj is the object to cache
|
* @param obj is the object to cache
|
||||||
* @param id is the id object of the bean
|
|
||||||
*/
|
*/
|
||||||
protected static synchronized void cacheDBBean(DBBean obj, Long id) {
|
protected static synchronized void cacheDBBean(DBBean obj) {
|
||||||
DBBeanCache item = new DBBeanCache();
|
DBBeanCache cacheItem = new DBBeanCache();
|
||||||
item.timestamp = System.currentTimeMillis();
|
cacheItem.updateTimestamp = System.currentTimeMillis();
|
||||||
item.bean = obj;
|
cacheItem.bean = new WeakReference<DBBean>(obj);
|
||||||
if( cache.containsKey(obj.getClass()) )
|
if( cache.containsKey(obj.getClass()) )
|
||||||
cache.get(obj.getClass()).put(id, item);
|
cache.get(obj.getClass()).put(obj.getId(), cacheItem);
|
||||||
else{
|
else{
|
||||||
Map<Long, DBBeanCache> map = new ConcurrentHashMap<Long, DBBeanCache>();
|
Map<Long, DBBeanCache> map = new ConcurrentHashMap<Long, DBBeanCache>();
|
||||||
map.put(id, item);
|
map.put(obj.getId(), cacheItem);
|
||||||
cache.put(obj.getClass(), map);
|
cache.put(obj.getClass(), map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue