BlobStore handles unique_ref<Blob> instead of unique_ptr<Blob>
This commit is contained in:
parent
c4f55f081a
commit
5039205cd2
@ -12,10 +12,15 @@
|
|||||||
using std::unique_ptr;
|
using std::unique_ptr;
|
||||||
using std::make_unique;
|
using std::make_unique;
|
||||||
|
|
||||||
|
using cpputils::unique_ref;
|
||||||
|
using cpputils::make_unique_ref;
|
||||||
|
|
||||||
using blockstore::BlockStore;
|
using blockstore::BlockStore;
|
||||||
using blockstore::parallelaccess::ParallelAccessBlockStore;
|
using blockstore::parallelaccess::ParallelAccessBlockStore;
|
||||||
using blockstore::Key;
|
using blockstore::Key;
|
||||||
using cpputils::dynamic_pointer_move;
|
using cpputils::dynamic_pointer_move;
|
||||||
|
using boost::optional;
|
||||||
|
using boost::none;
|
||||||
|
|
||||||
namespace blobstore {
|
namespace blobstore {
|
||||||
namespace onblocks {
|
namespace onblocks {
|
||||||
@ -31,19 +36,19 @@ BlobStoreOnBlocks::BlobStoreOnBlocks(unique_ptr<BlockStore> blockStore, uint32_t
|
|||||||
BlobStoreOnBlocks::~BlobStoreOnBlocks() {
|
BlobStoreOnBlocks::~BlobStoreOnBlocks() {
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<Blob> BlobStoreOnBlocks::create() {
|
unique_ref<Blob> BlobStoreOnBlocks::create() {
|
||||||
return make_unique<BlobOnBlocks>(_dataTreeStore->createNewTree());
|
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);
|
auto tree = _dataTreeStore->load(key);
|
||||||
if (tree == nullptr) {
|
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);
|
auto _blob = dynamic_pointer_move<BlobOnBlocks>(blob);
|
||||||
_dataTreeStore->remove(_blob->releaseTree());
|
_dataTreeStore->remove(_blob->releaseTree());
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,10 @@ public:
|
|||||||
BlobStoreOnBlocks(std::unique_ptr<blockstore::BlockStore> blockStore, uint32_t blocksizeBytes);
|
BlobStoreOnBlocks(std::unique_ptr<blockstore::BlockStore> blockStore, uint32_t blocksizeBytes);
|
||||||
virtual ~BlobStoreOnBlocks();
|
virtual ~BlobStoreOnBlocks();
|
||||||
|
|
||||||
std::unique_ptr<Blob> create() override;
|
cpputils::unique_ref<Blob> create() override;
|
||||||
std::unique_ptr<Blob> load(const blockstore::Key &key) 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:
|
private:
|
||||||
std::unique_ptr<parallelaccessdatatreestore::ParallelAccessDataTreeStore> _dataTreeStore;
|
std::unique_ptr<parallelaccessdatatreestore::ParallelAccessDataTreeStore> _dataTreeStore;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "messmer/blockstore/utils/Key.h"
|
#include "messmer/blockstore/utils/Key.h"
|
||||||
|
#include <messmer/cpp-utils/unique_ref.h>
|
||||||
|
|
||||||
namespace blobstore {
|
namespace blobstore {
|
||||||
|
|
||||||
@ -14,11 +15,9 @@ class BlobStore {
|
|||||||
public:
|
public:
|
||||||
virtual ~BlobStore() {}
|
virtual ~BlobStore() {}
|
||||||
|
|
||||||
virtual std::unique_ptr<Blob> create() = 0;
|
virtual cpputils::unique_ref<Blob> create() = 0;
|
||||||
//TODO Use boost::optional (if key doesn't exist)
|
virtual boost::optional<cpputils::unique_ref<Blob>> load(const blockstore::Key &key) = 0;
|
||||||
// Return nullptr if block with this key doesn't exists
|
virtual void remove(cpputils::unique_ref<Blob> blob) = 0;
|
||||||
virtual std::unique_ptr<Blob> load(const blockstore::Key &key) = 0;
|
|
||||||
virtual void remove(std::unique_ptr<Blob> blob) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <messmer/cpp-utils/data/DataFixture.h>
|
#include <messmer/cpp-utils/data/DataFixture.h>
|
||||||
#include "../../../implementations/onblocks/datanodestore/DataNodeView.h"
|
#include "../../../implementations/onblocks/datanodestore/DataNodeView.h"
|
||||||
|
|
||||||
using std::unique_ptr;
|
using cpputils::unique_ref;
|
||||||
using ::testing::WithParamInterface;
|
using ::testing::WithParamInterface;
|
||||||
using ::testing::Values;
|
using ::testing::Values;
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Data randomData;
|
Data randomData;
|
||||||
unique_ptr<Blob> blob;
|
unique_ref<Blob> blob;
|
||||||
};
|
};
|
||||||
constexpr uint32_t BlobReadWriteTest::LARGE_SIZE;
|
constexpr uint32_t BlobReadWriteTest::LARGE_SIZE;
|
||||||
constexpr DataNodeLayout BlobReadWriteTest::LAYOUT;
|
constexpr DataNodeLayout BlobReadWriteTest::LAYOUT;
|
||||||
@ -45,14 +45,14 @@ constexpr DataNodeLayout BlobReadWriteTest::LAYOUT;
|
|||||||
TEST_F(BlobReadWriteTest, WritingImmediatelyFlushes_SmallSize) {
|
TEST_F(BlobReadWriteTest, WritingImmediatelyFlushes_SmallSize) {
|
||||||
blob->resize(5);
|
blob->resize(5);
|
||||||
blob->write(randomData.data(), 0, 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);
|
EXPECT_DATA_READS_AS(randomData, *loaded, 0, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BlobReadWriteTest, WritingImmediatelyFlushes_LargeSize) {
|
TEST_F(BlobReadWriteTest, WritingImmediatelyFlushes_LargeSize) {
|
||||||
blob->resize(LARGE_SIZE);
|
blob->resize(LARGE_SIZE);
|
||||||
blob->write(randomData.data(), 0, 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);
|
EXPECT_DATA_READS_AS(randomData, *loaded, 0, LARGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ TEST_P(BlobReadWriteDataTest, WriteAndReadImmediately) {
|
|||||||
TEST_P(BlobReadWriteDataTest, WriteAndReadAfterLoading) {
|
TEST_P(BlobReadWriteDataTest, WriteAndReadAfterLoading) {
|
||||||
blob->resize(GetParam().blobsize);
|
blob->resize(GetParam().blobsize);
|
||||||
blob->write(this->foregroundData.data(), GetParam().offset, GetParam().count);
|
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_READS_AS(this->foregroundData, *loaded, GetParam().offset, GetParam().count);
|
||||||
EXPECT_DATA_IS_ZEROES_OUTSIDE_OF(*loaded, GetParam().offset, GetParam().count);
|
EXPECT_DATA_IS_ZEROES_OUTSIDE_OF(*loaded, GetParam().offset, GetParam().count);
|
||||||
|
@ -2,12 +2,11 @@
|
|||||||
#include <messmer/cpp-utils/data/Data.h>
|
#include <messmer/cpp-utils/data/Data.h>
|
||||||
#include <messmer/cpp-utils/data/DataFixture.h>
|
#include <messmer/cpp-utils/data/DataFixture.h>
|
||||||
|
|
||||||
using std::unique_ptr;
|
|
||||||
|
|
||||||
using namespace blobstore;
|
using namespace blobstore;
|
||||||
using blockstore::Key;
|
using blockstore::Key;
|
||||||
using cpputils::Data;
|
using cpputils::Data;
|
||||||
using cpputils::DataFixture;
|
using cpputils::DataFixture;
|
||||||
|
using cpputils::unique_ref;
|
||||||
|
|
||||||
class BlobSizeTest: public BlobStoreTest {
|
class BlobSizeTest: public BlobStoreTest {
|
||||||
public:
|
public:
|
||||||
@ -16,7 +15,7 @@ public:
|
|||||||
static constexpr uint32_t MEDIUM_SIZE = 5 * 1024 * 1024;
|
static constexpr uint32_t MEDIUM_SIZE = 5 * 1024 * 1024;
|
||||||
static constexpr uint32_t LARGE_SIZE = 10 * 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::MEDIUM_SIZE;
|
||||||
constexpr uint32_t BlobSizeTest::LARGE_SIZE;
|
constexpr uint32_t BlobSizeTest::LARGE_SIZE;
|
||||||
@ -66,16 +65,16 @@ TEST_F(BlobSizeTest, ResizingToItself_Large) {
|
|||||||
|
|
||||||
TEST_F(BlobSizeTest, EmptyBlobStaysEmptyWhenLoading) {
|
TEST_F(BlobSizeTest, EmptyBlobStaysEmptyWhenLoading) {
|
||||||
Key key = blob->key();
|
Key key = blob->key();
|
||||||
blob.reset();
|
reset(std::move(blob));
|
||||||
auto loaded = blobStore->load(key);
|
auto loaded = loadBlob(key);
|
||||||
EXPECT_EQ(0, loaded->size());
|
EXPECT_EQ(0, loaded->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BlobSizeTest, BlobSizeStaysIntactWhenLoading) {
|
TEST_F(BlobSizeTest, BlobSizeStaysIntactWhenLoading) {
|
||||||
blob->resize(LARGE_SIZE);
|
blob->resize(LARGE_SIZE);
|
||||||
Key key = blob->key();
|
Key key = blob->key();
|
||||||
blob.reset();
|
reset(std::move(blob));
|
||||||
auto loaded = blobStore->load(key);
|
auto loaded = loadBlob(key);
|
||||||
EXPECT_EQ(LARGE_SIZE, loaded->size());
|
EXPECT_EQ(LARGE_SIZE, loaded->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +113,7 @@ TEST_F(BlobSizeTest, WritingAfterEndOfBlobGrowsBlob_NonEmpty) {
|
|||||||
|
|
||||||
TEST_F(BlobSizeTest, ChangingSizeImmediatelyFlushes) {
|
TEST_F(BlobSizeTest, ChangingSizeImmediatelyFlushes) {
|
||||||
blob->resize(LARGE_SIZE);
|
blob->resize(LARGE_SIZE);
|
||||||
auto loaded = blobStore->load(blob->key());
|
auto loaded = loadBlob(blob->key());
|
||||||
EXPECT_EQ(LARGE_SIZE, loaded->size());
|
EXPECT_EQ(LARGE_SIZE, loaded->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +142,7 @@ TEST_F(BlobSizeDataTest, BlobIsZeroedOutAfterGrowing) {
|
|||||||
|
|
||||||
TEST_F(BlobSizeDataTest, BlobIsZeroedOutAfterGrowingAndLoading) {
|
TEST_F(BlobSizeDataTest, BlobIsZeroedOutAfterGrowingAndLoading) {
|
||||||
blob->resize(LARGE_SIZE);
|
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));
|
EXPECT_EQ(0, std::memcmp(readBlob(*loaded).data(), ZEROES.data(), LARGE_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,29 @@
|
|||||||
#include "testutils/BlobStoreTest.h"
|
#include "testutils/BlobStoreTest.h"
|
||||||
|
#include <boost/optional/optional_io.hpp>
|
||||||
|
|
||||||
using blockstore::Key;
|
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) {
|
TEST_F(BlobStoreTest, LoadNonexistingKeyOnEmptyBlobstore) {
|
||||||
const blockstore::Key key = blockstore::Key::FromString("1491BB4932A389EE14BC7090AC772972");
|
const blockstore::Key key = blockstore::Key::FromString("1491BB4932A389EE14BC7090AC772972");
|
||||||
EXPECT_EQ(nullptr, blobStore->load(key));
|
EXPECT_EQ(none, blobStore->load(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BlobStoreTest, LoadNonexistingKeyOnNonEmptyBlobstore) {
|
TEST_F(BlobStoreTest, LoadNonexistingKeyOnNonEmptyBlobstore) {
|
||||||
blobStore->create();
|
blobStore->create();
|
||||||
const blockstore::Key key = blockstore::Key::FromString("1491BB4932A389EE14BC7090AC772972");
|
const blockstore::Key key = blockstore::Key::FromString("1491BB4932A389EE14BC7090AC772972");
|
||||||
EXPECT_EQ(nullptr, blobStore->load(key));
|
EXPECT_EQ(none, blobStore->load(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BlobStoreTest, TwoCreatedBlobsHaveDifferentKeys) {
|
TEST_F(BlobStoreTest, TwoCreatedBlobsHaveDifferentKeys) {
|
||||||
@ -23,13 +36,13 @@ TEST_F(BlobStoreTest, BlobIsNotLoadableAfterDeletion_DeleteDirectly) {
|
|||||||
auto blob = blobStore->create();
|
auto blob = blobStore->create();
|
||||||
Key key = blob->key();
|
Key key = blob->key();
|
||||||
blobStore->remove(std::move(blob));
|
blobStore->remove(std::move(blob));
|
||||||
EXPECT_EQ(nullptr, blobStore->load(key).get());
|
EXPECT_FALSE((bool)blobStore->load(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BlobStoreTest, BlobIsNotLoadableAfterDeletion_DeleteAfterLoading) {
|
TEST_F(BlobStoreTest, BlobIsNotLoadableAfterDeletion_DeleteAfterLoading) {
|
||||||
auto blob = blobStore->create();
|
auto blob = blobStore->create();
|
||||||
Key key = blob->key();
|
Key key = blob->key();
|
||||||
blob.reset();
|
reset(std::move(blob));
|
||||||
blobStore->remove(blobStore->load(key));
|
blobStore->remove(loadBlob(key));
|
||||||
EXPECT_EQ(nullptr, blobStore->load(key).get());
|
EXPECT_FALSE((bool)blobStore->load(key));
|
||||||
}
|
}
|
||||||
|
@ -9,4 +9,15 @@ public:
|
|||||||
static constexpr uint32_t BLOCKSIZE_BYTES = 4096;
|
static constexpr uint32_t BLOCKSIZE_BYTES = 4096;
|
||||||
|
|
||||||
std::unique_ptr<blobstore::BlobStore> blobStore;
|
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
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user