设为首页 加入收藏

TOP

POCO C++库学习和分析 -- Cache(三)
2014-11-24 03:30:38 】 浏览:4267
Tags:POCO 学习 分析 Cache
;
}
else
{
result = it->second;
}
}
return result;
}
void doClear()
{
static EventArgs _emptyArgs;
Clear.notify(this, _emptyArgs);
_data.clear();
}
void doReplace()
{
std::set delMe;
Replace.notify(this, delMe);
// delMe contains the to be removed elements
typename std::set::const_iterator it = delMe.begin();
typename std::set::const_iterator endIt = delMe.end();
for (; it != endIt; ++it)
{
Iterator itH = _data.find(*it);
doRemove(itH);
}
}
TStrategy _strategy;
mutable DataHolder _data;
mutable TMutex _mutex;
private:
// ....
};
从上面的定义中,可以看到AbstractCache是一个value的容器,采用map保存数据,
[cpp]
mutable std::map > _data;
另外AbstractCache中还定义了一个TStrategy对象,
[cpp]
TStrategy _strategy;
并且在AbstractCache的initialize()函数中,把Cache的一些函数操作委托给TStrategy对象。其函数操作接口为:
1. Add : 向容器中添加元素
2. Update : 更新容器中元素
3. Remove : 删除容器中元素
4. Get : 获取容器中元素
5. Clear : 清除容器中所有元素
6. IsValid: 容器中是否某元素
7. Replace: 按照策略从strategy中获取过期元素,并从Cache和Strategy中同时删除。将触发一系列的Remove函数。
这几个操作中最复杂的是Add操作,其中包括了Remove、Insert和Replace操作。
[cpp]
void doAdd(const TKey& key, SharedPtr& val)
/// Adds the key value pair to the cache.
/// If for the key already an entry exists, it will be overwritten.
{
Iterator it = _data.find(key);
doRemove(it);
KeyValueArgs args(key, *val);
Add.notify(this, args);
_data.insert(std::make_pair(key, val));
doReplace();
}
而Replace操作可被Add、Update、Get操作触发。这是因为Cache并不是一个主动对象(POCO C++库学习和分析 -- 线程 (四)),不会自动的把元素标志为失效,需要外界也就是调用方触发进行。
在Cache类中另外一个值得注意的地方是,保存的是TValue的SharedPtr。之所以这么设计,是为了线程安全,由于replace操作可能被多个线程调用,所以解决的方法,要么是返回TValue的SharedPtr,要么是返回TValue的拷贝。同拷贝方法相比,SharedPtr的方法要更加廉价。
2.2 Strategy类
Strategy类完成了对_data中保存的pair中key的排序工作。每个Strategy中都存在一个key的容器,其中LRUStrategy中是std::list,ExpireStrategy、UniqueAccessExpireStrategy、UniqueExpireStrategy中是std::multimap。这说明在std::list和multimap中存储了key的信息,以及不同策略下的key的权重信息。对于LRU策略,每次访问都会使key被重置于list的最前端,key的权重相当于位置信息。而在Time Expire策略下,权重的额外信息为Timestamp,所以采用了multimap。在multimap和lis容器中,key的权重信息是pair的key,而key是value。因此为了实现对multimap和list快速访问,所有的strategy类中配套了multimap和list的pair的索引,在pair被插入multimap和lis容器时,保存pair在容器的iterator。保存索引的类在strategy中被称为Index,实际上它是一个std::map
让我们来看一下Strategy类中的replace操作。
[cpp]
ExpireStrategy类的Replace操作定义如下:
void onReplace(const void*, std::set& elemsToRemove)
{
// Note: replace only informs the cache which elements
// it would like to remove!
// it does not remove them on its own!
IndexIterator it = _keyIndex.begin();
while (it != _keyIndex.end() && it->first.isElapsed(_expireTime))
{
elemsToRemove.insert(it->second);
++it;
}
}
可以看出ExpireStrategy的replace操作对Index容器做了遍历,来找出失效元素。效率是不高的。
LRUStrategy类的Replace操作定义如下:
[cpp]
void onReplace(const void*, std::set
首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇查看Objective-C函数与参数 下一篇刨根问底系列之C++ 类型转换挖掘

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目