缓存Cache:内部提供多种缓存Cache机制,并对不同机制的管理缓存策略不同实现;
ValidArgs.h :ValidArgs有效键参数类,模板参数实现,_key:键,_isValid:是否有效,此外提供key获取键、isValid是否键有效,invalidate使得键值无效;默认情况下键为有效;
KeyValueArgs.h :KeyValueArgs键值参数对类,模板参数实现,_key:键,_value:键值;此外提供key获取键,value获取键值;
EventArgs.h :事件参数类,未提供任何有效操作实现,可能作为某些参数占位或某些模板、不提供发送数据等状态;
AbstractStrategy.h :AbstractStrategy所有缓存策略类的抽象基类,提供了必要的接口实现;onUpdate:更新已存在的条目,内部通过调用onRemove和onAdd实现更新;具体的移除和添加条目操作细节则由子类完成,类似于模板方法;onAdd、onRemove分别为添加和移除条目;onGet当某个可读事件发生时被触发调用的接口,onClear移除所有的缓存中的元素;onIsValid查询是否某个条目有效;onReplace:移除缓冲区中的多余条目,更新缓存容器,以上接口一般是被动调用即由相应的缓存Cache对象内部触发导致以上接口被调用,部分接口中参数pSender为发送者,一般指的是对应触发该调用的缓冲Cache对象;
AbstractCache.h :AbstractCache所有缓存抽象基类,基于模板参数实现,提供外部缓存策略、锁机制;_strategy:缓存策略对象,_data:数据容器,内部采用map保存各个条目元素对应键值;_mutex:锁机制对象;Add、Update、Remove、Get、Clear、IsValid、Replace提供多个针对不同操作的事件对象;构造函数调用initialize,实现各个事件对象注册各个事件委托调用事件接口;uninitialize负责反注册;add添加键值对至缓存,内部调用doAdd(移除当前键对应条目,并通告Add添加事件,此后添加该键值对至_data缓存容器中,此后再调用doReplace实现更新替换元素);update更新键值对,内部调用doUpdate(若未找到该键则直接添加至缓存,否则更新键值;再调用doReplace实现更新替换元素);remove移除指定条目的键值对;内部调用doRemove(若找到键值对,则Remove通告事件并从_data缓存容器中移除该键值对);has查询指定键值对,内部调用doHas(若找到键值对,则IsValid通告事件,并返回键值对是否有效);get获取某键值,内部调用doGet(若找到键值对,则Get通告事件,若该键值对有效,则返回该值否则移除该键值对返回空值);clear移除所有条目元素,内部调用doClear(调用Clear事件通告,并清空_data缓存容器);size返回_data缓存容器中元素条目数,forceReplace强制更新缓存容器;getAllKeys获取缓存容器中所有的键;
LRU缓存,基于近期最少访问策略:
LRUCache.h :最近近期最少使用缓存类,继承于AbstractCache类,构造函数传参cacheSize(1024)条目,即允许最大缓存条目,此外并无其他接口实现,采用的缓存策略为LRUStrategy;
LRUStrategy.h :LRUStrategy近期最少使用策略类,_size:缓存可容纳键数;_keys:键列表容器;_keyIndex:键、_keys迭代器对map容器;
现在我们可以结合缓存策略和缓存类来具体分析如何处理:
缓存类中add接口,以增加新的键值对:
1. 内部调用doAdd,而doAdd内部先对该键值对是否存在当前缓存,若存在则先从当前缓存中doRemove调用以移除该键值对,doRemove内部却是先通告Remove事件对象移除指定键,也即是调用LRUStrategy类的onRemove函数,移除LRUStrategy类的_keys和_keyIndex对应键以及当前缓存中_data缓存容器对应键值对;
2. 调用Add通告事件对象,也即是调用LRUStrategy类的onAdd,onAdd中添加当前新的键至_keys最前端并在_keyIndex插入键、键迭代器map对,
3. _data缓存容器增加当前新的键值对;
4. 调用doReplace,内部调用Replace通告事件对象,也即调用LRUStrategy类的onReplace,其目的是为了更新LRUStrategy类中键值对,保持最新的键值对至多达到cacheSize个条目并将旧的(列表末端的)键返回给缓存容器,使得缓存容器删除旧的键值对;故doReplace中delMe保存将被删除的键集合;
5. 循环调用doRemove,以删除delMe中的所有键,事实上doRemove内部调用Remove事件对象移除LRUStrategy类的多余的键,再移除对应键在_data缓存容器中的键值对;
缓存类中的update接口,以更新键值对:
1. 内部调用doUpdate,而doUpdate内部实现查找_data缓存容器中是否存在该键值对,若不存在,则直接调用Add通告事件对象并在_data中插入当前键值对;若存在,则调用Update通告事件对象(事实上内部采用分别调用onRemove、onAdd实现更新策略类中的键);
2. 调用doReplace,实现更新缓存容器和LRUStrategy类的缓存条目等;
缓存类中remove接口,以移除指定的键值对:
1. 内部调用doRemove,查找当前缓存容器中是否存在该键值对,若存在,则调用Remove通告事件对象,再从_data中移除当前缓存;否则不处理;缓存类中has接口,以查询指定的键值对是否有效:
2. 内部调用doHas,查找当前缓存容器中是否存在该键值对,若存在,则调用IsValid通告事件对象,也即调用LRUStrategy类的onIsValid,以查询_keyIndex中是否存在该键,并返回该键是否有效,有效返回true,否则返回false;
缓存类中get接口,以查询指定的键值对:
3. 内部调用doGet,查找当前缓存容器中是否存在该键值对,若存在,则调用Get通告事件对象,也即调用LRUStrategy类的onGet,onGet内部查询该键,若存在则表示命中,即调整该键至列表首部,此外doGet中也调用了IsValid通告事件对象,对有效键则返回该键所对应值,否则返回空值;此外缓存类中clear、size、forceReplace、getAllKeys等接口也提供查询、清空缓存、强制刷新缓存等操作:故对于缓存类负责维护缓存键值对,此外提供外部操作的接口,至于缓存策略,则由缓存策略类负责维护;
Expire缓存,基于时间戳策略:
ExpireCache.h :基于时间戳到期缓存类,继承于AbstractCache类,构造函数传参expire(600000),即允许最大逾期时间10分钟,此外并无其他接口实现,采用的缓存策略为ExpireStrategy;
ExpireStrategy.h :ExpireStrategy基于时间戳的策略类,_expireTime:逾期时间戳,_keys:键、_keys迭代器对map容器,_keyIndex:底层容器为std::multimap的时间戳、键对;因缓存类和LRUCache缓存类相似,不同点在于缓存策略,故此处着重分析ExpireStrategy类的各种处理策略;
onAdd接口:每当新添加缓存键值对时,构造时间戳索引键对并插入_keyIndex,此外构造键、迭代器对插入_keys,对于插入失败的则直接更新_keyIndex;
onRemove接口:查找_keys中是否存在对应的键,若存在,则从_keyIndex和_keys中移除该对应的键;
onGet接口:命中时,不做任何处理;
onClear接口:直接清空_keyIndex和_keys中所有键值对;
onIsValid接口:查找_keys中是否存在对应的键,若存在则从判断是否已过时间戳,若已过或未存在则设置对应键值有效性为无效;
onReplace接口:直接对所有已超时的_keyIndex键值对移除至elemsToRemove集合中;
ExpireLRU缓存,结合近期最少访问策略和时间戳策略;
ExpireLRUCache.h :ExpireLRUCache结合近期最少访问策略和时间戳策略,继承于AbstractCache类,构造函数传参cacheSize(1024)条目、expire(600000),即允许最大逾期时间10分钟,构造函数内部_strategy增加了这两种策略对象;此外并无其他接口实现,采用的缓存策略为StrategyCollection;
StrategyCollection.h :StrategyCollection基于近期最少访问策略和时间戳策略类,_strategies:策略容器,保存当前策略集合;增加的额外的接口pushBack:增加策略对象;popBack:移除最近加入的策略对象;以下将针对基类接口实现说明;
onAdd、onRemove、onGet、onClear、onIsValid、onReplace接口:遍历策略容器,均依次调用各策略对象的onAdd接口实现;
AccessExpire缓存,采用类似于ExpireStrategy策略,此外不同之处在于接口onGet会更新时间戳;
AccessExpireCache.h : AccessExpireCache可访问更新时间戳策略,继承于AbstractCache类,构造函数传参expire(600000),即允许最大逾期时间10分钟,此外并无其他接口实现,采用的缓存策略为AccessExpireStrategy;
AccessExpireStrategy.h :AccessExpireStrategy继承于ExpireStrategy策略类并重写函数onGet,该函数将更新当前项目时间戳为最新时间戳;
AccessExpireLRU缓存,采用结合近期最少访问策略和更新时间戳策略;
AccessExpireLRUCache.h :AccessExpireLRUCache结合近期最少访问策略和更新时间戳策略,继承于AbstractCache类,构造函数传参cacheSize(1024)条目、expire(600000),即允许最大逾期时间10分钟,构造函数内部_strategy增加了这两种策略对象;此外并无其他接口实现,采用的缓存策略为StrategyCollection;
UniqueExpire缓存,采用UniqueExpireStrategy策略进行缓存管理;
UniqueExpireCache.h :UniqueExpireCache缓存类似于依赖于Expire缓存,不同之处在于TValue需要提供getExpiration实现接口,即由TValue提供时间戳;
UniqueExpireStrategy.h :UniqueExpireStrategy策略类,继承于AbstractStrategy,该策略类不同于ExpireStrategy类中在于onAdd接口实现;该时间戳需要由TValue提供getExpiration实现,以获取该TValue对应的时间戳;
UniqueExpireLRU缓存,采用结合近期最少访问策略和UniqueExpireStrategy策略;
UniqueExpireLRUCache.h :UniqueExpireLRUCache缓存使用StrategyCollection策略集合以管理缓存;
UniqueAccessExpire缓存,采用UniqueAccessExpireStrategy策略进行缓存管理;
UniqueAccessExpireCache.h :UniqueAccessExpireCache缓存继承于AbstractCache,该缓存类要求TValue提供getTimeout获取超时时间戳;也即一个固定的相对超时时间;
UniqueAccessExpireStrategy.h :UniqueAccessExpireStrategy类继承于AbstractStrategy策略类,接口中onAdd接口通过计算相对时间和当前实现作为当前的项的到期时间戳;其他接口实现类似;
UniqueAccessExpireLRU缓存,采用结合近期最少访问策略和UniqueAccessExpireStrategy策略;
UniqueAccessExpireLRUCache.h :UniqueAccessExpireLRUCache类继承于AbstractCache,使用StrategyCollection策略集合以管理缓存;该缓存相对UniqueAccessExpire缓存增加了近期最少访问策略,也即onGet接口中会修正更新当前被访问的缓存项时间戳;