2015-04-15 19:05:58 +02:00
|
|
|
#include "CachedBlock.h"
|
2015-04-18 14:47:12 +02:00
|
|
|
#include "NewBlock.h"
|
2015-04-16 14:10:44 +02:00
|
|
|
#include "CachingBlockStore.h"
|
2015-04-15 15:46:35 +02:00
|
|
|
#include "../../interface/Block.h"
|
|
|
|
|
2015-04-15 19:05:58 +02:00
|
|
|
#include <algorithm>
|
2015-04-15 20:39:58 +02:00
|
|
|
#include <messmer/cpp-utils/pointer.h>
|
2015-04-15 19:05:58 +02:00
|
|
|
|
2015-04-15 15:46:35 +02:00
|
|
|
using std::unique_ptr;
|
2015-04-15 19:05:58 +02:00
|
|
|
using std::make_unique;
|
2015-04-15 20:39:58 +02:00
|
|
|
using cpputils::dynamic_pointer_move;
|
2015-04-25 02:48:41 +02:00
|
|
|
using cpputils::Data;
|
2015-04-15 15:46:35 +02:00
|
|
|
|
|
|
|
namespace blockstore {
|
2015-04-16 14:10:44 +02:00
|
|
|
namespace caching {
|
2015-04-15 15:46:35 +02:00
|
|
|
|
2015-04-16 14:10:44 +02:00
|
|
|
CachingBlockStore::CachingBlockStore(std::unique_ptr<BlockStore> baseBlockStore)
|
2015-04-18 14:47:12 +02:00
|
|
|
:_baseBlockStore(std::move(baseBlockStore)), _cache(), _numNewBlocks(0) {
|
2015-04-15 15:46:35 +02:00
|
|
|
}
|
|
|
|
|
2015-04-18 14:47:12 +02:00
|
|
|
Key CachingBlockStore::createKey() {
|
|
|
|
return _baseBlockStore->createKey();
|
|
|
|
}
|
|
|
|
|
|
|
|
unique_ptr<Block> CachingBlockStore::tryCreate(const Key &key, Data data) {
|
|
|
|
++_numNewBlocks;
|
|
|
|
return make_unique<CachedBlock>(make_unique<NewBlock>(key, std::move(data), this), this);
|
2015-04-15 15:46:35 +02:00
|
|
|
}
|
|
|
|
|
2015-04-16 14:10:44 +02:00
|
|
|
unique_ptr<Block> CachingBlockStore::load(const Key &key) {
|
2015-04-15 19:05:58 +02:00
|
|
|
auto block = _cache.pop(key);
|
|
|
|
if (block.get() != nullptr) {
|
|
|
|
return make_unique<CachedBlock>(std::move(block), this);
|
|
|
|
}
|
2015-04-15 20:39:58 +02:00
|
|
|
block = _baseBlockStore->load(key);
|
|
|
|
if (block.get() == nullptr) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return make_unique<CachedBlock>(std::move(block), this);
|
2015-04-15 15:46:35 +02:00
|
|
|
}
|
|
|
|
|
2015-04-16 14:10:44 +02:00
|
|
|
void CachingBlockStore::remove(std::unique_ptr<Block> block) {
|
2015-04-18 14:47:12 +02:00
|
|
|
auto baseBlock = dynamic_pointer_move<CachedBlock>(block)->releaseBlock();
|
|
|
|
auto baseNewBlock = dynamic_pointer_move<NewBlock>(baseBlock);
|
|
|
|
if (baseNewBlock.get() != nullptr) {
|
|
|
|
if(!baseNewBlock->alreadyExistsInBaseStore()) {
|
|
|
|
--_numNewBlocks;
|
|
|
|
}
|
|
|
|
baseNewBlock->remove();
|
|
|
|
} else {
|
|
|
|
_baseBlockStore->remove(std::move(baseBlock));
|
|
|
|
}
|
2015-04-15 15:46:35 +02:00
|
|
|
}
|
|
|
|
|
2015-04-16 14:10:44 +02:00
|
|
|
uint64_t CachingBlockStore::numBlocks() const {
|
2015-04-18 14:47:12 +02:00
|
|
|
return _baseBlockStore->numBlocks() + _numNewBlocks;
|
2015-04-15 15:46:35 +02:00
|
|
|
}
|
|
|
|
|
2015-04-16 14:10:44 +02:00
|
|
|
void CachingBlockStore::release(unique_ptr<Block> block) {
|
2015-04-15 19:05:58 +02:00
|
|
|
_cache.push(std::move(block));
|
|
|
|
}
|
|
|
|
|
2015-04-18 14:47:12 +02:00
|
|
|
std::unique_ptr<Block> CachingBlockStore::tryCreateInBaseStore(const Key &key, Data data) {
|
|
|
|
auto block = _baseBlockStore->tryCreate(key, std::move(data));
|
|
|
|
if (block.get() != nullptr) {
|
|
|
|
--_numNewBlocks;
|
|
|
|
}
|
|
|
|
return block;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CachingBlockStore::removeFromBaseStore(std::unique_ptr<Block> block) {
|
|
|
|
_baseBlockStore->remove(std::move(block));
|
|
|
|
}
|
|
|
|
|
2015-04-15 15:46:35 +02:00
|
|
|
}
|
|
|
|
}
|