package org.quickbundle.project.cache;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.quickbundle.itf.cache.IRmCacheListener;
import org.quickbundle.tools.support.log.RmLogHelper;
import org.slf4j.Logger;
public class RmSqlCountCache implements IRmCacheListener {
/**
* 分布式缓存的log入口类
*/
public final static Logger logCache = RmLogHelper.getLogger("rmcache");
//每个tableName对应的缓存的最大queryCondition数量,防止溢出
private static final int MAX_CACHE_COUNT = 1000;
private RmSqlCountCache() {
}
/**
* 缓存查询条件对应的count(*)记录数
*/
private volatile Map<String, Map<String, Integer>> mCount = new ConcurrentHashMap<String, Map<String, Integer>>();
/**
* 得到缓存中查询条件对应的count(*)记录数,如缓存无返回-1,抛异常返回-2
*
* @param tableName
* @param queryCondition
* @return 大于等于0表示记录数。-1表示当前表的缓存未初始化。-2表示抛异常
*/
private int getCountInner(String tableName, String queryCondition) {
int result = -1;
try {
if(mCount.get(tableName) != null && mCount.get(tableName).get(queryCondition) != null) {
result = mCount.get(tableName).get(queryCondition);
}
} catch(Exception e) {
result = -2;
logCache.error(RmSqlCountCache.class.getName() + ".getCount(" + tableName + ", " + queryCondition + "): " + e.toString());
}
return result;
}
/**
* 得到缓存中查询条件对应的count(*)记录数,如缓存无返回-1,抛异常返回-2
*
* @param tableName
* @param queryCondition
* @return 大于等于0表示记录数。-1表示当前表的缓存未初始化。-2表示抛异常
*/
public static int getCount(String tableName, String queryCondition) {
return singleton.getCountInner(tableName, queryCondition);
}
/**
* 向缓存中放入查询条件对应的count(*)记录数
*
* @param tableName
* @param queryCondition
* @param count
*/
public void putCountInner(String tableName, String queryCondition, int count) {
try {
if(mCount.get(tableName) == null) {
synchronized (mCount) {
if(mCount.get(tableName) == null) {
Map<String, Integer> mCountTableName = new ConcurrentHashMap<String, Integer>();
mCount.put(tableName, mCountTableName);
}
}
}
//如果达到最大缓存数,清空原有数据,缓存重新开始
if(mCount.get(tableName).size() >= MAX_CACHE_COUNT) {
mCount.get(tableName).clear();
}
mCount.get(tableName).put(queryCondition, count);
} catch (Exception e) {
logCache.error(RmSqlCountCache.class.getName() + ".putCount(" + tableName + ", " + queryCondition + ", " + count + "): " + e.toString());
}
}
/**
* 向缓存中放入查询条件对应的count(*)记录数
*
* @param tableName
* @param queryCondition
* @param count
*/
public static void putCount(String tableName, String queryCondition, int count) {
singleton.putCountInner(tableName, queryCondition, count);
}
/**
* 清除tableName表对应的count记录数缓存
*
* @param tableName
*/
private void clearCountInner(String tableName) {
try {
mCount.remove(tableName);
} catch (Exception e) {
logCache.error(RmSqlCountCache.class.getName() + ".clearCount(" + tableName + "): " + e.toString());
}
}
/**
* 清除tableName表对应的count记录数缓存
*
* @param tableName
*/
public static void clearCount(String tableName) {
singleton.clearCountInner(tableName);
//不会被flushCache调用的方法,才能安全执行flushOtherNodes
RmCacheHandler.getSingleton().flushOtherNodes(RmSqlCountCache.class, IRmCacheListener.RefreshType.DELETE.value(), tableName);
}
private static RmSqlCountCache singleton = new RmSqlCountCache();
public static RmSqlCountCache getSingleton() {
return singleton;
}
/**
* 刷新缓存的值,将keys对应的数据设置为已过期(或未初始化)状态
*
* @param refreshType 缓存的刷新类型
* @param keys 缓存的key值
* @return 返回执行结果: -1表示错误, 0表示没找到删除的对象, 大于0的值表示影响的行数
*/
public String flushCache(String flushType, Object... keys) {
String result = null;
if(IRmCacheListener.RefreshType.DELETE.value().equals(flushType)) {
if(keys.length > 0) {
clearCountInner(keys[0].toString());
result = "1";
}
} else {
result = "0";
}
logCache.info(this.getClass().getName() + ".flushCache(" + flushType + ", " + Arrays.deepToString(keys) + "): result=" + result);
return result;
}
}