From ff35d72e3438e9dd74f4e05986a671f68f622deb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Me=C3=9Fmer?= Date: Thu, 2 Apr 2015 12:19:05 -0400 Subject: [PATCH] Use new CachingStore --- biicode.conf | 1 + implementations/caching/CachedBlockRef.cpp | 38 +---- implementations/caching/CachedBlockRef.h | 29 +++- implementations/caching/CachingBlockStore.cpp | 18 +-- implementations/caching/CachingBlockStore.h | 9 +- .../caching/CachingBlockStoreAdapter.cpp | 1 + .../caching/CachingBlockStoreAdapter.h | 34 +++++ implementations/caching/CachingStore.h | 144 ------------------ 8 files changed, 67 insertions(+), 207 deletions(-) create mode 100644 implementations/caching/CachingBlockStoreAdapter.cpp create mode 100644 implementations/caching/CachingBlockStoreAdapter.h delete mode 100644 implementations/caching/CachingStore.h diff --git a/biicode.conf b/biicode.conf index d0cf92e1..8c642bd7 100644 --- a/biicode.conf +++ b/biicode.conf @@ -4,6 +4,7 @@ cryptopp/cryptopp: 8 google/gmock: 2 google/gtest: 10 + messmer/cachingstore: -1 messmer/cmake: 3 messmer/cpp-utils: 2 messmer/tempfile: 4 diff --git a/implementations/caching/CachedBlockRef.cpp b/implementations/caching/CachedBlockRef.cpp index faae7066..66964318 100644 --- a/implementations/caching/CachedBlockRef.cpp +++ b/implementations/caching/CachedBlockRef.cpp @@ -1,37 +1 @@ -#include -#include - -using std::shared_ptr; -using std::make_unique; -using std::function; - -namespace blockstore { -namespace caching { - -CachedBlockRef::CachedBlockRef(Block *baseBlock) - :Block(baseBlock->key()), - _baseBlock(baseBlock) { -} - -CachedBlockRef::~CachedBlockRef() { - _baseBlock->flush(); -} - -const void *CachedBlockRef::data() const { - return _baseBlock->data(); -} - -void CachedBlockRef::write(const void *source, uint64_t offset, uint64_t size) { - return _baseBlock->write(source, offset, size); -} - -size_t CachedBlockRef::size() const { - return _baseBlock->size(); -} - -void CachedBlockRef::flush() { - return _baseBlock->flush(); -} - -} -} +#include "CachedBlockRef.h" diff --git a/implementations/caching/CachedBlockRef.h b/implementations/caching/CachedBlockRef.h index 4f713d10..e5b16399 100644 --- a/implementations/caching/CachedBlockRef.h +++ b/implementations/caching/CachedBlockRef.h @@ -3,7 +3,7 @@ #define BLOCKSTORE_IMPLEMENTATIONS_CACHING_CACHEDBLOCKREF_H_ #include "../../interface/Block.h" -#include "CachingStore.h" +#include #include "messmer/cpp-utils/macros.h" #include @@ -12,17 +12,30 @@ namespace blockstore { namespace caching { class CachingBlockStore; -class CachedBlockRef: public Block, public CachingStore::CachedResource { +class CachedBlockRef: public Block, public cachingstore::CachingStore::CachedResource { public: - CachedBlockRef(Block *baseBlock); - virtual ~CachedBlockRef(); + //TODO Unneccessarily storing Key twice here (in parent class and in _baseBlock). + CachedBlockRef(Block *baseBlock): Block(baseBlock->key()), _baseBlock(baseBlock) {} - const void *data() const override; - void write(const void *source, uint64_t offset, uint64_t size) override; + virtual ~CachedBlockRef() { + _baseBlock->flush(); + } - void flush() override; + const void *data() const override { + return _baseBlock->data(); + } - size_t size() const override; + void write(const void *source, uint64_t offset, uint64_t size) override { + return _baseBlock->write(source, offset, size); + } + + void flush() override { + return _baseBlock->flush(); + } + + size_t size() const override { + return _baseBlock->size(); + } private: Block *_baseBlock; diff --git a/implementations/caching/CachingBlockStore.cpp b/implementations/caching/CachingBlockStore.cpp index f3139381..153d3dbd 100644 --- a/implementations/caching/CachingBlockStore.cpp +++ b/implementations/caching/CachingBlockStore.cpp @@ -2,6 +2,8 @@ #include #include +#include "CachingBlockStoreAdapter.h" + using std::unique_ptr; using std::make_unique; using std::string; @@ -13,31 +15,23 @@ namespace blockstore { namespace caching { CachingBlockStore::CachingBlockStore(unique_ptr baseBlockStore) - : _baseBlockStore(std::move(baseBlockStore)) { + : _baseBlockStore(std::move(baseBlockStore)), _cachingStore(make_unique(_baseBlockStore.get())) { } unique_ptr CachingBlockStore::create(size_t size) { auto block = _baseBlockStore->create(size); Key key = block->key(); - return CachingStore::add(key, std::move(block)); + return _cachingStore.add(key, std::move(block)); } unique_ptr CachingBlockStore::load(const Key &key) { - return CachingStore::load(key); + return _cachingStore.load(key); } void CachingBlockStore::remove(unique_ptr block) { Key key = block->key(); - return CachingStore::remove(key, std::move(block)); -} - -unique_ptr CachingBlockStore::loadFromBaseStore(const Key &key) { - return _baseBlockStore->load(key); -} - -void CachingBlockStore::removeFromBaseStore(unique_ptr block) { - return _baseBlockStore->remove(std::move(block)); + return _cachingStore.remove(key, std::move(block)); } uint64_t CachingBlockStore::numBlocks() const { diff --git a/implementations/caching/CachingBlockStore.h b/implementations/caching/CachingBlockStore.h index d48e55e5..45f8741c 100644 --- a/implementations/caching/CachingBlockStore.h +++ b/implementations/caching/CachingBlockStore.h @@ -2,7 +2,7 @@ #ifndef BLOCKSTORE_IMPLEMENTATIONS_CACHING_CACHINGBLOCKSTORE_H_ #define BLOCKSTORE_IMPLEMENTATIONS_CACHIN_CACHINGBLOCKSTORE_H_ -#include "CachingStore.h" +#include #include "../../interface/BlockStore.h" #include "CachedBlockRef.h" @@ -10,7 +10,7 @@ namespace blockstore { namespace caching { -class CachingBlockStore: public BlockStore, private CachingStore { +class CachingBlockStore: public BlockStore { public: CachingBlockStore(std::unique_ptr baseBlockStore); @@ -19,12 +19,9 @@ public: void remove(std::unique_ptr block) override; uint64_t numBlocks() const override; -protected: - std::unique_ptr loadFromBaseStore(const Key &key) override; - void removeFromBaseStore(std::unique_ptr block) override; - private: std::unique_ptr _baseBlockStore; + cachingstore::CachingStore _cachingStore; DISALLOW_COPY_AND_ASSIGN(CachingBlockStore); }; diff --git a/implementations/caching/CachingBlockStoreAdapter.cpp b/implementations/caching/CachingBlockStoreAdapter.cpp new file mode 100644 index 00000000..b299922d --- /dev/null +++ b/implementations/caching/CachingBlockStoreAdapter.cpp @@ -0,0 +1 @@ +#include "CachingBlockStoreAdapter.h" diff --git a/implementations/caching/CachingBlockStoreAdapter.h b/implementations/caching/CachingBlockStoreAdapter.h new file mode 100644 index 00000000..44fd4378 --- /dev/null +++ b/implementations/caching/CachingBlockStoreAdapter.h @@ -0,0 +1,34 @@ +#ifndef MESSMER_BLOCKSTORE_IMPLEMENTATIONS_CACHING_CACHINGBLOCKSTOREADAPTER_H_ +#define MESSMER_BLOCKSTORE_IMPLEMENTATIONS_CACHING_CACHINGBLOCKSTOREADAPTER_H_ + +#include +#include +#include "../../interface/BlockStore.h" + +namespace blockstore { +namespace caching { + +class CachingBlockStoreAdapter: public cachingstore::CachingBaseStore { +public: + CachingBlockStoreAdapter(BlockStore *baseBlockStore) + :_baseBlockStore(std::move(baseBlockStore)) { + } + + std::unique_ptr loadFromBaseStore(const Key &key) override { + return _baseBlockStore->load(key); + } + + void removeFromBaseStore(std::unique_ptr block) override { + return _baseBlockStore->remove(std::move(block)); + } + +private: + BlockStore *_baseBlockStore; + + DISALLOW_COPY_AND_ASSIGN(CachingBlockStoreAdapter); +}; + +} +} + +#endif diff --git a/implementations/caching/CachingStore.h b/implementations/caching/CachingStore.h deleted file mode 100644 index 02b02d47..00000000 --- a/implementations/caching/CachingStore.h +++ /dev/null @@ -1,144 +0,0 @@ -#ifndef MESSMER_BLOCKSTORE_IMPLEMENTATIONS_CACHING_CACHINGSTORE_H_ -#define MESSMER_BLOCKSTORE_IMPLEMENTATIONS_CACHING_CACHINGSTORE_H_ - -#include -#include -#include -#include -#include -#include - -template -class CachingStore { -public: - CachingStore() {} //TODO Init member variables - - //TODO Enforce CachedResourceRef inherits from CachedResource - class CachedResource { - public: - //TODO Better way to initialize - CachedResource(): _cachingStore(nullptr), _key(Key::CreateRandomKey()) {} - void init(CachingStore *cachingStore, const Key &key) { - _cachingStore = cachingStore; - _key = key; - } - virtual ~CachedResource() { - _cachingStore->release(_key); - } - private: - CachingStore *_cachingStore; - //TODO We're storing Key twice (here and in the base resource). Rather use getKey() on the base resource if possible somehow. - Key _key; - }; - - std::unique_ptr add(const Key &key, std::unique_ptr resource); - std::unique_ptr load(const Key &key); - void remove(const Key &key, std::unique_ptr block); - -protected: - virtual std::unique_ptr loadFromBaseStore(const Key &key) = 0; - virtual void removeFromBaseStore(std::unique_ptr resource) = 0; - -private: - class OpenResource { - public: - OpenResource(std::unique_ptr resource): _resource(std::move(resource)), _refCount(0) {} - - Resource *getReference() { - ++_refCount; - return _resource.get(); - } - - void releaseReference() { - --_refCount; - } - - bool refCountIsZero() const { - return 0 == _refCount; - } - - std::unique_ptr moveResourceOut() { - return std::move(_resource); - } - private: - std::unique_ptr _resource; - uint32_t _refCount; - }; - - std::mutex _mutex; - std::map _openResources; - std::map>> _resourcesToRemove; - - std::unique_ptr _add(const Key &key, std::unique_ptr resource); - std::unique_ptr _createCachedResourceRef(Resource *resource, const Key &key); - - void release(const Key &key); - friend class CachedResource; - - DISALLOW_COPY_AND_ASSIGN(CachingStore); -}; - -template -std::unique_ptr CachingStore::add(const Key &key, std::unique_ptr resource) { - std::lock_guard lock(_mutex); - return _add(key, std::move(resource)); -} - -template -std::unique_ptr CachingStore::_add(const Key &key, std::unique_ptr resource) { - auto insertResult = _openResources.emplace(key, std::move(resource)); - assert(true == insertResult.second); - return _createCachedResourceRef(insertResult.first->second.getReference(), key); -} - -template -std::unique_ptr CachingStore::_createCachedResourceRef(Resource *resource, const Key &key) { - auto resourceRef = std::make_unique(resource); - resourceRef->init(this, key); - return std::move(resourceRef); -} - -template -std::unique_ptr CachingStore::load(const Key &key) { - std::lock_guard lock(_mutex); - auto found = _openResources.find(key); - if (found == _openResources.end()) { - auto resource = loadFromBaseStore(key); - if (resource.get() == nullptr) { - return nullptr; - } - return _add(key, std::move(resource)); - } else { - return _createCachedResourceRef(found->second.getReference(), key); - } -} - -template -void CachingStore::remove(const Key &key, std::unique_ptr resource) { - auto insertResult = _resourcesToRemove.emplace(key, std::promise>()); - assert(true == insertResult.second); - resource.reset(); - - //Wait for last resource user to release it - auto resourceToRemove = insertResult.first->second.get_future().get(); - - removeFromBaseStore(std::move(resourceToRemove)); -} - -template -void CachingStore::release(const Key &key) { - std::lock_guard lock(_mutex); - auto found = _openResources.find(key); - assert (found != _openResources.end()); - found->second.releaseReference(); - if (found->second.refCountIsZero()) { - auto foundToRemove = _resourcesToRemove.find(key); - if (foundToRemove != _resourcesToRemove.end()) { - foundToRemove->second.set_value(found->second.moveResourceOut()); - } - _openResources.erase(found); - } -} - - -#endif