我正在尝试实现一个缓存,该缓存必须(显然)针对获取和回收项目进行优化。
但存在一个挑战:缓存可能会不时失效。
从架构的角度来看,到目前为止我所做的是实现包含池的缓存。该池本身实际上是一个无锁对象池,经过充分测试并且可以正常工作。
一个问题是允许池本身与更新版本进行交换。我认为我已经进行了交换(参考:两个 unique_ptr<T> 的无锁交换)。
但是如何使用可以在操作期间交换的池(分别是下面的 getPreparedDefaultRule() 和 recyclePreparedDefaultRule())来处理无锁 get 和 set 呢?
我几乎认为这是不可能的。尽管我很高兴被证明是错误的。
template <typename Data, typename Delegate>
class DefaultRulePoolCache {
public:
DefaultRulePoolCache() : _atomicDefaultRulePool(nullptr), _defaultRulePool(nullptr) {
}
std::unique_ptr<detail::PreparedRule<Data, Delegate>> getPreparedDefaultRule() {
auto atomicPool = _atomicDefaultRulePool.load();
if (!atomicPool) {
return nullptr;
}
return atomicPool->getPreparedRule();
}
void recyclePreparedDefaultRule(std::unique_ptr<detail::PreparedRulePool<Data, Delegate>> preparedRule) {
auto atomicPool = _atomicDefaultRulePool.load();
if (!atomicPool) {
return;
}
hdmCheck(preparedRule) << "Cannot recycle null rule.";
// we return the prepared rule only to the pool in case it's the current version of the default rul
if (atomicPool->getTag() == preparedRule->getTag()) {
atomicPool->recyclePreparedRule(std::move(preparedRule));
}
}
void setDefaultRulePool(std::shared_ptr<detail::PreparedRulePool<Data, Delegate>> defaultRulePool) {
std::lock_guard<std::mutex> lock(_defaultRulePoolMutex);
atomicSwapPool(defaultRulePool);
}
void removeDefaultRulePool() {
std::lock_guard<std::mutex> lock(_defaultRulePoolMutex);
atomicSwapPool(nullptr);
}
private:
std::atomic<detail::PreparedRulePool<Data, Delegate>*> _atomicDefaultRulePool;
std::shared_ptr<detail::PreparedRulePool<data::Location, KVOLocationValuesDelegate>> _defaultRulePool;
std::mutex _defaultRulePoolMutex;
void atomicSwapPool(std::shared_ptr<detail::PreparedRulePool<Data, Delegate>> defaultRulePool) {
std::atomic_exchange(&_atomicDefaultRulePool, defaultRulePool.get());
// destroy the old pool
_defaultRulePool = nullptr;
// asign the new pool
_defaultRulePool = defaultRulePool;
}
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
207 次 |
| 最近记录: |