Use CachingDataTreeStore instead of DataTreeStore to avoid opening the same datatree twice in different threads

This commit is contained in:
Sebastian Messmer 2015-04-09 15:40:27 +02:00
parent e4e452ddd2
commit 84401b9abf
12 changed files with 190 additions and 14 deletions

View File

@ -4,6 +4,7 @@
google/gmock: 2
google/gtest: 10
messmer/blockstore: 1
messmer/cachingstore: 0
messmer/cmake: 3
messmer/cpp-utils: 2

View File

@ -1,6 +1,6 @@
#include "BlobOnBlocks.h"
#include "datatreestore/DataTree.h"
#include "cachingdatatreestore/CachedDataTreeRef.h"
#include "datanodestore/DataLeafNode.h"
#include "utils/Math.h"
#include <cmath>
@ -14,9 +14,9 @@ using blockstore::Key;
namespace blobstore {
namespace onblocks {
using datatreestore::DataTree;
using cachingdatatreestore::CachedDataTreeRef;
BlobOnBlocks::BlobOnBlocks(unique_ptr<DataTree> datatree)
BlobOnBlocks::BlobOnBlocks(unique_ptr<CachedDataTreeRef> datatree)
: _datatree(std::move(datatree)) {
}
@ -79,7 +79,7 @@ Key BlobOnBlocks::key() const {
return _datatree->key();
}
unique_ptr<DataTree> BlobOnBlocks::releaseTree() {
unique_ptr<CachedDataTreeRef> BlobOnBlocks::releaseTree() {
return std::move(_datatree);
}

View File

@ -11,13 +11,13 @@ namespace onblocks {
namespace datanodestore {
class DataLeafNode;
}
namespace datatreestore {
class DataTree;
namespace cachingdatatreestore {
class CachedDataTreeRef;
}
class BlobOnBlocks: public Blob {
public:
BlobOnBlocks(std::unique_ptr<datatreestore::DataTree> datatree);
BlobOnBlocks(std::unique_ptr<cachingdatatreestore::CachedDataTreeRef> datatree);
virtual ~BlobOnBlocks();
blockstore::Key key() const override;
@ -29,14 +29,14 @@ public:
uint64_t tryRead(void *target, uint64_t offset, uint64_t size) const override;
void write(const void *source, uint64_t offset, uint64_t size) override;
std::unique_ptr<datatreestore::DataTree> releaseTree();
std::unique_ptr<cachingdatatreestore::CachedDataTreeRef> releaseTree();
private:
void traverseLeaves(uint64_t offsetBytes, uint64_t sizeBytes, std::function<void (uint64_t, datanodestore::DataLeafNode *, uint32_t, uint32_t)>) const;
void resizeIfSmallerThan(uint64_t neededSize);
std::unique_ptr<datatreestore::DataTree> _datatree;
std::unique_ptr<cachingdatatreestore::CachedDataTreeRef> _datatree;
};
}

View File

@ -3,6 +3,8 @@
#include "datanodestore/DataNodeStore.h"
#include "datatreestore/DataTreeStore.h"
#include "datatreestore/DataTree.h"
#include "cachingdatatreestore/CachingDataTreeStore.h"
#include "cachingdatatreestore/CachedDataTreeRef.h"
#include "BlobStoreOnBlocks.h"
#include "BlobOnBlocks.h"
#include <messmer/cpp-utils/pointer.h>
@ -20,9 +22,10 @@ namespace onblocks {
using datanodestore::DataNodeStore;
using datatreestore::DataTreeStore;
using cachingdatatreestore::CachingDataTreeStore;
BlobStoreOnBlocks::BlobStoreOnBlocks(unique_ptr<BlockStore> blockStore, uint32_t blocksizeBytes)
: _dataTreeStore(make_unique<DataTreeStore>(make_unique<DataNodeStore>(make_unique<CachingBlockStore>(std::move(blockStore)), blocksizeBytes))) {
: _dataTreeStore(make_unique<CachingDataTreeStore>(make_unique<DataTreeStore>(make_unique<DataNodeStore>(make_unique<CachingBlockStore>(std::move(blockStore)), blocksizeBytes)))) {
}
BlobStoreOnBlocks::~BlobStoreOnBlocks() {

View File

@ -7,8 +7,8 @@
namespace blobstore {
namespace onblocks {
namespace datatreestore {
class DataTreeStore;
namespace cachingdatatreestore {
class CachingDataTreeStore;
}
class BlobStoreOnBlocks: public BlobStore {
@ -22,7 +22,7 @@ public:
void remove(std::unique_ptr<Blob> blob) override;
private:
std::unique_ptr<datatreestore::DataTreeStore> _dataTreeStore;
std::unique_ptr<cachingdatatreestore::CachingDataTreeStore> _dataTreeStore;
};
}

View File

@ -0,0 +1 @@
#include "CachedDataTreeRef.h"

View File

@ -0,0 +1,47 @@
#pragma once
#ifndef MESSMER_BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_CACHINGDATATREESTORE_DATATREEREF_H_
#define MESSMER_BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_CACHINGDATATREESTORE_DATATREEREF_H_
#include "../datatreestore/DataTree.h"
#include <messmer/cachingstore/CachingStore.h>
namespace blobstore {
namespace onblocks {
namespace cachingdatatreestore {
class CachedDataTreeRef: public cachingstore::CachingStore<datatreestore::DataTree, CachedDataTreeRef, blockstore::Key>::CachedResource {
public:
CachedDataTreeRef(datatreestore::DataTree *baseTree): _baseTree(baseTree) {}
const blockstore::Key &key() const {
return _baseTree->key();
}
uint32_t maxBytesPerLeaf() const {
return _baseTree->maxBytesPerLeaf();
}
void traverseLeaves(uint32_t beginIndex, uint32_t endIndex, std::function<void (const datanodestore::DataLeafNode*, uint32_t)> func) const {
return const_cast<const datatreestore::DataTree*>(_baseTree)->traverseLeaves(beginIndex, endIndex, func);
}
void traverseLeaves(uint32_t beginIndex, uint32_t endIndex, std::function<void (datanodestore::DataLeafNode*, uint32_t)> func) {
return _baseTree->traverseLeaves(beginIndex, endIndex, func);
}
void resizeNumBytes(uint64_t newNumBytes) {
return _baseTree->resizeNumBytes(newNumBytes);
}
uint64_t numStoredBytes() const {
return _baseTree->numStoredBytes();
}
private:
datatreestore::DataTree *_baseTree;
};
}
}
}
#endif

View File

@ -0,0 +1,43 @@
#include "CachingDataTreeStore.h"
#include "../datanodestore/DataNodeStore.h"
#include "../datanodestore/DataLeafNode.h"
#include "CachingDataTreeStoreAdapter.h"
#include "CachedDataTreeRef.h"
using std::unique_ptr;
using std::make_unique;
using blobstore::onblocks::datatreestore::DataTreeStore;
using blockstore::Key;
namespace blobstore {
namespace onblocks {
using datatreestore::DataTreeStore;
using datatreestore::DataTree;
namespace cachingdatatreestore {
CachingDataTreeStore::CachingDataTreeStore(unique_ptr<DataTreeStore> dataTreeStore)
: _dataTreeStore(std::move(dataTreeStore)), _cachingStore(make_unique<CachingDataTreeStoreAdapter>(_dataTreeStore.get())) {
}
CachingDataTreeStore::~CachingDataTreeStore() {
}
unique_ptr<CachedDataTreeRef> CachingDataTreeStore::load(const blockstore::Key &key) {
return _cachingStore.load(key);
}
unique_ptr<CachedDataTreeRef> CachingDataTreeStore::createNewTree() {
auto dataTree = _dataTreeStore->createNewTree();
Key key = dataTree->key();
return _cachingStore.add(key, std::move(dataTree));
}
void CachingDataTreeStore::remove(unique_ptr<CachedDataTreeRef> tree) {
Key key = tree->key();
return _cachingStore.remove(key, std::move(tree));
}
}
}
}

View File

@ -0,0 +1,43 @@
#pragma once
#ifndef BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_CACHINGDATATREESTORE_CACHINGDATATREESTORE_H_
#define BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_CACHINGDATATREESTORE_CACHINGDATATREESTORE_H_
#include <memory>
#include <messmer/cpp-utils/macros.h>
#include <messmer/cachingstore/CachingStore.h>
namespace blockstore{
class Key;
}
namespace blobstore {
namespace onblocks {
namespace datatreestore {
class DataTreeStore;
class DataTree;
}
namespace cachingdatatreestore {
class CachedDataTreeRef;
class CachingDataTreeStore {
public:
CachingDataTreeStore(std::unique_ptr<datatreestore::DataTreeStore> dataTreeStore);
virtual ~CachingDataTreeStore();
std::unique_ptr<CachedDataTreeRef> load(const blockstore::Key &key);
std::unique_ptr<CachedDataTreeRef> createNewTree();
void remove(std::unique_ptr<CachedDataTreeRef> tree);
private:
std::unique_ptr<datatreestore::DataTreeStore> _dataTreeStore;
cachingstore::CachingStore<datatreestore::DataTree, CachedDataTreeRef, blockstore::Key> _cachingStore;
DISALLOW_COPY_AND_ASSIGN(CachingDataTreeStore);
};
}
}
}
#endif

View File

@ -0,0 +1 @@
#include "CachingDataTreeStoreAdapter.h"

View File

@ -0,0 +1,37 @@
#ifndef MESSMER_BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_CACHINGDATATREESTORE_CACHINGDATATREESTOREADAPTER_H_
#define MESSMER_BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_CACHINGDATATREESTORE_CACHINGDATATREESTOREADAPTER_H_
#include <messmer/cpp-utils/macros.h>
#include <messmer/cachingstore/CachingStore.h>
#include "../datatreestore/DataTreeStore.h"
#include "../datatreestore/DataTree.h"
namespace blobstore {
namespace onblocks {
namespace cachingdatatreestore {
class CachingDataTreeStoreAdapter: public cachingstore::CachingBaseStore<datatreestore::DataTree, blockstore::Key> {
public:
CachingDataTreeStoreAdapter(datatreestore::DataTreeStore *baseDataTreeStore)
:_baseDataTreeStore(std::move(baseDataTreeStore)) {
}
std::unique_ptr<datatreestore::DataTree> loadFromBaseStore(const blockstore::Key &key) override {
return _baseDataTreeStore->load(key);
}
void removeFromBaseStore(std::unique_ptr<datatreestore::DataTree> dataTree) override {
return _baseDataTreeStore->remove(std::move(dataTree));
}
private:
datatreestore::DataTreeStore *_baseDataTreeStore;
DISALLOW_COPY_AND_ASSIGN(CachingDataTreeStoreAdapter);
};
}
}
}
#endif

View File

@ -3,7 +3,7 @@
#define BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_DATATREESTORE_DATATREESTORE_H_
#include <memory>
#include "messmer/cpp-utils/macros.h"
#include <messmer/cpp-utils/macros.h>
namespace blockstore{
class Key;