BlobStore handles unique_ref<Blob> instead of unique_ptr<Blob>

This commit is contained in:
Sebastian Meßmer 2015-06-18 12:45:37 +02:00
parent c4f55f081a
commit 5039205cd2
7 changed files with 61 additions and 34 deletions

View File

@ -12,10 +12,15 @@
using std::unique_ptr;
using std::make_unique;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
using blockstore::BlockStore;
using blockstore::parallelaccess::ParallelAccessBlockStore;
using blockstore::Key;
using cpputils::dynamic_pointer_move;
using boost::optional;
using boost::none;
namespace blobstore {
namespace onblocks {
@ -31,19 +36,19 @@ BlobStoreOnBlocks::BlobStoreOnBlocks(unique_ptr<BlockStore> blockStore, uint32_t
BlobStoreOnBlocks::~BlobStoreOnBlocks() {
}
unique_ptr<Blob> BlobStoreOnBlocks::create() {
return make_unique<BlobOnBlocks>(_dataTreeStore->createNewTree());
unique_ref<Blob> BlobStoreOnBlocks::create() {
return make_unique_ref<BlobOnBlocks>(_dataTreeStore->createNewTree());
}
unique_ptr<Blob> BlobStoreOnBlocks::load(const Key &key) {
optional<unique_ref<Blob>> BlobStoreOnBlocks::load(const Key &key) {
auto tree = _dataTreeStore->load(key);
if (tree == nullptr) {
return nullptr;
return none;
}
return make_unique<BlobOnBlocks>(std::move(tree));
return optional<unique_ref<Blob>>(make_unique_ref<BlobOnBlocks>(std::move(tree)));
}
void BlobStoreOnBlocks::remove(unique_ptr<Blob> blob) {
void BlobStoreOnBlocks::remove(unique_ref<Blob> blob) {
auto _blob = dynamic_pointer_move<BlobOnBlocks>(blob);
_dataTreeStore->remove(_blob->releaseTree());
}

View File

@ -18,10 +18,10 @@ public:
BlobStoreOnBlocks(std::unique_ptr<blockstore::BlockStore> blockStore, uint32_t blocksizeBytes);
virtual ~BlobStoreOnBlocks();
std::unique_ptr<Blob> create() override;
std::unique_ptr<Blob> load(const blockstore::Key &key) override;
cpputils::unique_ref<Blob> create() override;
boost::optional<cpputils::unique_ref<Blob>> load(const blockstore::Key &key) override;
void remove(std::unique_ptr<Blob> blob) override;
void remove(cpputils::unique_ref<Blob> blob) override;
private:
std::unique_ptr<parallelaccessdatatreestore::ParallelAccessDataTreeStore> _dataTreeStore;

View File

@ -7,6 +7,7 @@
#include <memory>
#include "messmer/blockstore/utils/Key.h"
#include <messmer/cpp-utils/unique_ref.h>
namespace blobstore {
@ -14,11 +15,9 @@ class BlobStore {
public:
virtual ~BlobStore() {}
virtual std::unique_ptr<Blob> create() = 0;
//TODO Use boost::optional (if key doesn't exist)
// Return nullptr if block with this key doesn't exists
virtual std::unique_ptr<Blob> load(const blockstore::Key &key) = 0;
virtual void remove(std::unique_ptr<Blob> blob) = 0;
virtual cpputils::unique_ref<Blob> create() = 0;
virtual boost::optional<cpputils::unique_ref<Blob>> load(const blockstore::Key &key) = 0;
virtual void remove(cpputils::unique_ref<Blob> blob) = 0;
};
}

View File

@ -3,7 +3,7 @@
#include <messmer/cpp-utils/data/DataFixture.h>
#include "../../../implementations/onblocks/datanodestore/DataNodeView.h"
using std::unique_ptr;
using cpputils::unique_ref;
using ::testing::WithParamInterface;
using ::testing::Values;
@ -37,7 +37,7 @@ public:
}
Data randomData;
unique_ptr<Blob> blob;
unique_ref<Blob> blob;
};
constexpr uint32_t BlobReadWriteTest::LARGE_SIZE;
constexpr DataNodeLayout BlobReadWriteTest::LAYOUT;
@ -45,14 +45,14 @@ constexpr DataNodeLayout BlobReadWriteTest::LAYOUT;
TEST_F(BlobReadWriteTest, WritingImmediatelyFlushes_SmallSize) {
blob->resize(5);
blob->write(randomData.data(), 0, 5);
auto loaded = blobStore->load(blob->key());
auto loaded = loadBlob(blob->key());
EXPECT_DATA_READS_AS(randomData, *loaded, 0, 5);
}
TEST_F(BlobReadWriteTest, WritingImmediatelyFlushes_LargeSize) {
blob->resize(LARGE_SIZE);
blob->write(randomData.data(), 0, LARGE_SIZE);
auto loaded = blobStore->load(blob->key());
auto loaded = loadBlob(blob->key());
EXPECT_DATA_READS_AS(randomData, *loaded, 0, LARGE_SIZE);
}
@ -127,7 +127,7 @@ TEST_P(BlobReadWriteDataTest, WriteAndReadImmediately) {
TEST_P(BlobReadWriteDataTest, WriteAndReadAfterLoading) {
blob->resize(GetParam().blobsize);
blob->write(this->foregroundData.data(), GetParam().offset, GetParam().count);
auto loaded = blobStore->load(blob->key());
auto loaded = loadBlob(blob->key());
EXPECT_DATA_READS_AS(this->foregroundData, *loaded, GetParam().offset, GetParam().count);
EXPECT_DATA_IS_ZEROES_OUTSIDE_OF(*loaded, GetParam().offset, GetParam().count);

View File

@ -2,12 +2,11 @@
#include <messmer/cpp-utils/data/Data.h>
#include <messmer/cpp-utils/data/DataFixture.h>
using std::unique_ptr;
using namespace blobstore;
using blockstore::Key;
using cpputils::Data;
using cpputils::DataFixture;
using cpputils::unique_ref;
class BlobSizeTest: public BlobStoreTest {
public:
@ -16,7 +15,7 @@ public:
static constexpr uint32_t MEDIUM_SIZE = 5 * 1024 * 1024;
static constexpr uint32_t LARGE_SIZE = 10 * 1024 * 1024;
unique_ptr<Blob> blob;
unique_ref<Blob> blob;
};
constexpr uint32_t BlobSizeTest::MEDIUM_SIZE;
constexpr uint32_t BlobSizeTest::LARGE_SIZE;
@ -66,16 +65,16 @@ TEST_F(BlobSizeTest, ResizingToItself_Large) {
TEST_F(BlobSizeTest, EmptyBlobStaysEmptyWhenLoading) {
Key key = blob->key();
blob.reset();
auto loaded = blobStore->load(key);
reset(std::move(blob));
auto loaded = loadBlob(key);
EXPECT_EQ(0, loaded->size());
}
TEST_F(BlobSizeTest, BlobSizeStaysIntactWhenLoading) {
blob->resize(LARGE_SIZE);
Key key = blob->key();
blob.reset();
auto loaded = blobStore->load(key);
reset(std::move(blob));
auto loaded = loadBlob(key);
EXPECT_EQ(LARGE_SIZE, loaded->size());
}
@ -114,7 +113,7 @@ TEST_F(BlobSizeTest, WritingAfterEndOfBlobGrowsBlob_NonEmpty) {
TEST_F(BlobSizeTest, ChangingSizeImmediatelyFlushes) {
blob->resize(LARGE_SIZE);
auto loaded = blobStore->load(blob->key());
auto loaded = loadBlob(blob->key());
EXPECT_EQ(LARGE_SIZE, loaded->size());
}
@ -143,7 +142,7 @@ TEST_F(BlobSizeDataTest, BlobIsZeroedOutAfterGrowing) {
TEST_F(BlobSizeDataTest, BlobIsZeroedOutAfterGrowingAndLoading) {
blob->resize(LARGE_SIZE);
auto loaded = blobStore->load(blob->key());
auto loaded = loadBlob(blob->key());
EXPECT_EQ(0, std::memcmp(readBlob(*loaded).data(), ZEROES.data(), LARGE_SIZE));
}

View File

@ -1,16 +1,29 @@
#include "testutils/BlobStoreTest.h"
#include <boost/optional/optional_io.hpp>
using blockstore::Key;
using cpputils::unique_ref;
using blobstore::Blob;
using boost::none;
//gtest/boost::optional workaround for working with optional<unique_ref<T>>
namespace boost {
std::ostream& operator<<(std::ostream& out, const unique_ref<Blob> &ref) {
out << "[" << ref->key().ToString() << "]" << ref.get();
return out;
}
}
TEST_F(BlobStoreTest, LoadNonexistingKeyOnEmptyBlobstore) {
const blockstore::Key key = blockstore::Key::FromString("1491BB4932A389EE14BC7090AC772972");
EXPECT_EQ(nullptr, blobStore->load(key));
EXPECT_EQ(none, blobStore->load(key));
}
TEST_F(BlobStoreTest, LoadNonexistingKeyOnNonEmptyBlobstore) {
blobStore->create();
const blockstore::Key key = blockstore::Key::FromString("1491BB4932A389EE14BC7090AC772972");
EXPECT_EQ(nullptr, blobStore->load(key));
EXPECT_EQ(none, blobStore->load(key));
}
TEST_F(BlobStoreTest, TwoCreatedBlobsHaveDifferentKeys) {
@ -23,13 +36,13 @@ TEST_F(BlobStoreTest, BlobIsNotLoadableAfterDeletion_DeleteDirectly) {
auto blob = blobStore->create();
Key key = blob->key();
blobStore->remove(std::move(blob));
EXPECT_EQ(nullptr, blobStore->load(key).get());
EXPECT_FALSE((bool)blobStore->load(key));
}
TEST_F(BlobStoreTest, BlobIsNotLoadableAfterDeletion_DeleteAfterLoading) {
auto blob = blobStore->create();
Key key = blob->key();
blob.reset();
blobStore->remove(blobStore->load(key));
EXPECT_EQ(nullptr, blobStore->load(key).get());
reset(std::move(blob));
blobStore->remove(loadBlob(key));
EXPECT_FALSE((bool)blobStore->load(key));
}

View File

@ -9,4 +9,15 @@ public:
static constexpr uint32_t BLOCKSIZE_BYTES = 4096;
std::unique_ptr<blobstore::BlobStore> blobStore;
cpputils::unique_ref<blobstore::Blob> loadBlob(const blockstore::Key &key) {
auto loaded = blobStore->load(key);
EXPECT_TRUE((bool)loaded);
return std::move(*loaded);
}
void reset(cpputils::unique_ref<blobstore::Blob> ref) {
UNUSED(ref);
//ref is moved into here and then destructed
}
};