/* ==================================================================
* Created [2009-4-27 下午11:32:55] by Jon.King
* ==================================================================
* TSS
* ==================================================================
* mailTo:jinpujun@hotmail.com
* Copyright (c) Jon.King, 2009-2012
* ==================================================================
*/
package com.jinhe.tss.core.cachepool.strategy;
import com.jinhe.tss.core.cachepool.DefaultArithmetic;
import com.jinhe.tss.core.cachepool.DefaultCacheLoader;
import com.jinhe.tss.core.cachepool.IArithmetic;
import com.jinhe.tss.core.cachepool.ICacheLoader;
import com.jinhe.tss.core.cachepool.IPool;
import com.jinhe.tss.core.cachepool.ObjectPoolEvent;
import com.jinhe.tss.core.cachepool.container.IPoolContainer;
import com.jinhe.tss.core.cachepool.container.MapContainer;
import com.jinhe.tss.core.cachepool.proxy.Disabler;
import com.jinhe.tss.core.util.BeanUtil;
/**
* <p> CacheStrategy.java </p>
* <p></p>
* 缓存策略
* <p></p>不变区
* <p></p> code
* <p></p> name
* <p></p>可变区
* <p></p> 普通,不触发池事件
* <p></p> accessMethod
* <p></p> disabled
* <p></p> interruptTime
* <p></p> remark
* <p></p> 触发池事件STRATEGY_CHANGED_NORMAL
* <p></p> arithmeticClass
* <p></p> cacheLoaderClass
* <p></p> cyclelife
* <p></p> 如果变大了则触发池事件STRATEGY_CHANGED_INITNUM_RISE,执行ObjectPool.startInitThread();变小了不管。
* <p></p> initNum
* <p></p> 如果变小了则触发池事件STRATEGY_CHANGED_SIZE_REDUCE,处理同PUT_IN事件;大了不管
* <p></p> poolSize
* <p></p> 严重,触发池事件STRATEGY_CHANGED_RESET,重新初始化池
* <p></p> poolClass
* <p></p> poolCollectionClass
*
* @author Jon.King 2006-12-29
*/
public class CacheStrategy{
//缓存模块提供的对象池类型
static final String SIMPLE_POOL_CLASS = "com.jinhe.tss.core.cachepool.SimplePool";
static final String BASE_POOL_CLASS = "com.jinhe.tss.core.cachepool.ObjectPool";
final static String DEFAULT_POOLCOLLECTION = MapContainer.class.getName();
final static String DEFAULT_ARITHMETIC = DefaultArithmetic.class.getName();
final static String DEFAULT_LOADER = DefaultCacheLoader.class.getName();
private String name; //缓存策略的名称
private String code; //缓存策略的code
private String remark; //缓存策略说明
private Integer poolSize = 0; //缓存池的容量(注: size 为零则表示不限定池大小)
private Integer initNum = 0; //初始化缓存池时初始缓存项的个数
private Long cyclelife = 0L; //池中元素的有效期(生命周期)
private Long interruptTime = 0L; //中断时间(取不到缓存项时执行其他操作的等待时间)
private String disabled = CacheConstants.FALSE; //1:停用, 0:启用(用以检测缓存启用和停用时的执行效率)
private String visible = CacheConstants.TRUE; //1:显示, 0:隐藏 是否展示,用以隐藏运行时创建过来的缓存池,像没有名字只有code的那些
/**
* 池的访问方式
* 1: FIFO (first-in, first-out: a queue).
* 2: LIFO (last-in, first-out: a stack).
* 3: RANDOM (a random connection is selected for check-out).
* 4:ACCESS_LRU (最近使用)
* 5:ACCESS_LFU (最不常使用)
*/
private Integer accessMethod = IPoolContainer.ACCESS_RANDOM;
private String poolClass = SIMPLE_POOL_CLASS; //缓存池实现类
private String poolCollectionClass = DEFAULT_POOLCOLLECTION; //池容器类,默认为:MapPool.class。在特定情形下用特定的集合类或许可以提高性能
private String arithmeticClass = DEFAULT_ARITHMETIC; //执行缓存算法的类
private String cacheLoaderClass = DEFAULT_LOADER; //重新载入缓存项的类
private IPool pool; //缓存策略里定义的缓存池
public IPool getPoolInstance(){
if(pool != null && pool.getCacheStrategy().equals(this))
return pool;
pool = (IPool)BeanUtil.newInstanceByName(poolClass);
pool.setCacheStrategy(this);
pool = (IPool) Disabler.disableWrapper(pool);
pool.setArithmetic((IArithmetic) BeanUtil.newInstanceByName(arithmeticClass));
pool.setLoader((ICacheLoader) BeanUtil.newInstanceByName(cacheLoaderClass));
//需要放到最后一句,因为初始化需要用到IArithmetic.create()
pool.init();
return pool;
}
public boolean equals(Object o){
if(o instanceof CacheStrategy){
CacheStrategy strategy = (CacheStrategy) o;
return this.code.equals(strategy.getCode());
}
return false;
}
/**
* 缓存策略修改时重新设置各个策略项的值,同时触发相应的事件。
* @param c
*/
public void fireEventIfChanged(CacheStrategy c){
// 缓存项生命周期、载入器、缓存池执行算法发生了改变时:
if(!this.cyclelife.equals(c.getCyclelife())
|| !this.cacheLoaderClass.equals(c.getCacheLoaderClass())
|| !this.arithmeticClass.equals(c.getArithmeticClass())){
this.cyclelife = c.getCyclelife();
this.cacheLoaderClass = c.getCacheLoaderClass();
this.arithmeticClass = c.getArithmeticClass();
pool.firePoolEvent(ObjectPoolEvent.STRATEGY_CHANGED_NORMAL);
}
if(this.initNum.compareTo(c.getInitNum()) < 0){ // 初始化个数变少
this.initNum = c.getInitNum();
pool.firePoolEvent(ObjectPoolEvent.STRATEGY_CHANGED_INITNUM_RISE);
}
if(this.poolSize.compareTo(c.getPoolSize()) > 0){ // 池变小
this.poolSize = c.getPoolSize();
pool.firePoolEvent(ObjectPoolEvent.STRATEGY_CHANGED_SIZE_REDUCE);
}
if(!this.poolClass.equals(c.getPoolClass()) || !this.poolCollectionClass.equals(c.getPoolCollectionClass())){
this.poolClass = c.getPoolClass();
this.poolCollectionClass = c.getPoolCollectionClass();
pool.firePoolEvent(ObjectPoolEvent.STRATEGY_CHANGED_RESET);
}
this.initNum = c.getInitNum();
this.poolSize = c.getPoolSize();
this.accessMethod = c.getAccessMethod();
this.disabled = c.getDisabled();
this.interruptTime = c.getInterruptTime();
this.remark = c.getRemark();
}
/**
* 设置缓存策略的arithmeticClass。同时改变池的arithmetic对象,如果池已经存在的话。
*/
public void setArithmeticClass(String arithmeticClass) {
this.arithmeticClass = arithmeticClass == null || arithmeticClass.equals("")? DEFAULT_ARITHMETIC : arithmeticClass;
}
/**
* 设置缓存策略的cacheLoaderClass。同时改变池的cacheLoader对象,如果池已经存在的话。
*/
public void setCacheLoaderClass(String cacheLoaderClass) {
this.cacheLoaderClass = cacheLoaderClass == null || cacheLoaderClass.equals("")? DEFAULT_LOADER : cacheLoaderClass;
}
/**
* 设置缓存池类型
*/
public void setPoolClass(String poolClass) {
this.poolClass = poolClass == null || poolClass.equals("")? SIMPLE_POOL_CLASS : poolClass;
}
/**
* 设置缓存池的容器类
*/
public void setPoolCollectionClass(String poolCollectionClass) {
this.poolCollectionClass = poolCollectionClass == null || poolCollectionClass.equals("")? DEFAULT_POOLCOLLECTION : poolCollectionClass;
}
public void setCyclelife(Long cyclelife) { this.cyclelife = cyclelife == null ? 0 : cyclelife; }
public String getArithmeticClass() { return arithmeticClass; }
public String getCacheLoaderClass() { return cacheLoaderClass; }
public String getCode() { return code; }
public Long getCyclelife() { return cyclelife; }
public String getDisabled() { return disabled; }
public Long getInterruptTime() { return interruptTime ; }
public String getName() { return name; }
public Integer getPoolSize() { return poolSize; }
public void setCode(String code) { this.code = code; }
public void setDisabled(String disabled) { this.disabled = disabled; }
public void setInterruptTime(Long interruptTime) { this.interruptTime = interruptTime == null ? 0 : interruptTime; }
public void setName(String name) { this.name = name == null ? code : name; }
public void setPoolSize(Integer poolSize) {
if(poolSize != null){
int size = Math.max(0, poolSize); //确保 size 不小于 0
this.poolSize = new Integer(size);
}
}
public String getPoolClass() { return poolClass; }
public String getPoolCollectionClass() { return poolCollectionClass; }
public Integer getInitNum() { return initNum; }
public void setInitNum(Integer initNum) { this.initNum = (initNum == null ? 0 : initNum) ;}
public Integer getAccessMethod() { return accessMethod; }
public void setAccessMethod(Integer method) { this.accessMethod = method;}
public String getRemark() { return remark; }
public void setRemark(String remark) { this.remark = remark; }
public String getVisible() { return visible; }
public void setVisible(String visible) { this.visible = visible; }
}