Add DataNode/DataInnerNode/DataLeafNode to blobstore and write testcases for their magic numbers
This commit is contained in:
parent
5fee5e862a
commit
ec65b31c8e
@ -6,8 +6,8 @@ using blockstore::Block;
|
|||||||
namespace blobstore {
|
namespace blobstore {
|
||||||
namespace onblocks {
|
namespace onblocks {
|
||||||
|
|
||||||
BlobOnBlocks::BlobOnBlocks(unique_ptr<Block> block)
|
BlobOnBlocks::BlobOnBlocks(unique_ptr<Block> rootblock)
|
||||||
: _block(std::move(block)) {
|
: _rootblock(std::move(rootblock)) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,15 +19,15 @@ void *BlobOnBlocks::data() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const void *BlobOnBlocks::data() const {
|
const void *BlobOnBlocks::data() const {
|
||||||
return _block->data();
|
return _rootblock->data();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlobOnBlocks::flush() {
|
void BlobOnBlocks::flush() {
|
||||||
_block->flush();
|
_rootblock->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t BlobOnBlocks::size() const {
|
size_t BlobOnBlocks::size() const {
|
||||||
return _block->size();
|
return _rootblock->size();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ namespace onblocks {
|
|||||||
|
|
||||||
class BlobOnBlocks: public Blob {
|
class BlobOnBlocks: public Blob {
|
||||||
public:
|
public:
|
||||||
BlobOnBlocks(std::unique_ptr<blockstore::Block> block);
|
BlobOnBlocks(std::unique_ptr<blockstore::Block> rootblock);
|
||||||
virtual ~BlobOnBlocks();
|
virtual ~BlobOnBlocks();
|
||||||
|
|
||||||
void *data() override;
|
void *data() override;
|
||||||
@ -23,7 +23,7 @@ public:
|
|||||||
size_t size() const override;
|
size_t size() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<blockstore::Block> _block;
|
std::unique_ptr<blockstore::Block> _rootblock;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ namespace onblocks {
|
|||||||
|
|
||||||
class BlobStoreOnBlocks: public BlobStore {
|
class BlobStoreOnBlocks: public BlobStore {
|
||||||
public:
|
public:
|
||||||
|
static constexpr size_t BLOCKSIZE = 4096;
|
||||||
|
|
||||||
BlobStoreOnBlocks(std::unique_ptr<blockstore::BlockStore> blockStore);
|
BlobStoreOnBlocks(std::unique_ptr<blockstore::BlockStore> blockStore);
|
||||||
virtual ~BlobStoreOnBlocks();
|
virtual ~BlobStoreOnBlocks();
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
add_library(blobstore_onblocks BlobOnBlocks.cpp BlobStoreOnBlocks)
|
add_library(blobstore_onblocks BlobOnBlocks.cpp BlobStoreOnBlocks.cpp impl/DataNode.cpp impl/DataLeafNode.cpp impl/DataInnerNode.cpp)
|
||||||
|
|
||||||
target_link_libraries(blobstore_onblocks blockstore_interface)
|
target_link_libraries(blobstore_onblocks blockstore_interface)
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
#include "DataInnerNode.h"
|
||||||
|
|
||||||
|
using std::unique_ptr;
|
||||||
|
using blockstore::Block;
|
||||||
|
|
||||||
|
namespace blobstore {
|
||||||
|
namespace onblocks {
|
||||||
|
|
||||||
|
DataInnerNode::DataInnerNode(unique_ptr<Block> block)
|
||||||
|
: DataNode(std::move(block)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
DataInnerNode::~DataInnerNode() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataInnerNode::InitializeEmptyInnerNode() {
|
||||||
|
InnerNodeHeader* header = (InnerNodeHeader*)_block->data();
|
||||||
|
header->nodeHeader.magicNumber = DataNode::magicNumberInnerNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
25
src/blobstore/implementations/onblocks/impl/DataInnerNode.h
Normal file
25
src/blobstore/implementations/onblocks/impl/DataInnerNode.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_IMPL_DATAINNERNODE_H_
|
||||||
|
#define BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_IMPL_DATAINNERNODE_H_
|
||||||
|
|
||||||
|
#include "DataNode.h"
|
||||||
|
|
||||||
|
namespace blobstore {
|
||||||
|
namespace onblocks {
|
||||||
|
|
||||||
|
class DataInnerNode: public DataNode {
|
||||||
|
public:
|
||||||
|
DataInnerNode(std::unique_ptr<blockstore::Block> block);
|
||||||
|
virtual ~DataInnerNode();
|
||||||
|
|
||||||
|
struct InnerNodeHeader {
|
||||||
|
NodeHeader nodeHeader;
|
||||||
|
};
|
||||||
|
|
||||||
|
void InitializeEmptyInnerNode();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
22
src/blobstore/implementations/onblocks/impl/DataLeafNode.cpp
Normal file
22
src/blobstore/implementations/onblocks/impl/DataLeafNode.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include "DataLeafNode.h"
|
||||||
|
|
||||||
|
using std::unique_ptr;
|
||||||
|
using blockstore::Block;
|
||||||
|
|
||||||
|
namespace blobstore {
|
||||||
|
namespace onblocks {
|
||||||
|
|
||||||
|
DataLeafNode::DataLeafNode(unique_ptr<Block> block)
|
||||||
|
: DataNode(std::move(block)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
DataLeafNode::~DataLeafNode() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataLeafNode::InitializeEmptyLeaf() {
|
||||||
|
LeafHeader *header = (LeafHeader*)_block->data();
|
||||||
|
header->nodeHeader.magicNumber = DataNode::magicNumberLeaf;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
25
src/blobstore/implementations/onblocks/impl/DataLeafNode.h
Normal file
25
src/blobstore/implementations/onblocks/impl/DataLeafNode.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_IMPL_DATALEAFNODE_H_
|
||||||
|
#define BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_IMPL_DATALEAFNODE_H_
|
||||||
|
|
||||||
|
#include "DataNode.h"
|
||||||
|
|
||||||
|
namespace blobstore {
|
||||||
|
namespace onblocks {
|
||||||
|
|
||||||
|
class DataLeafNode: public DataNode {
|
||||||
|
public:
|
||||||
|
DataLeafNode(std::unique_ptr<blockstore::Block> block);
|
||||||
|
virtual ~DataLeafNode();
|
||||||
|
|
||||||
|
struct LeafHeader {
|
||||||
|
NodeHeader nodeHeader;
|
||||||
|
};
|
||||||
|
|
||||||
|
void InitializeEmptyLeaf();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
51
src/blobstore/implementations/onblocks/impl/DataNode.cpp
Normal file
51
src/blobstore/implementations/onblocks/impl/DataNode.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include "DataNode.h"
|
||||||
|
|
||||||
|
#include "DataInnerNode.h"
|
||||||
|
#include "DataLeafNode.h"
|
||||||
|
|
||||||
|
using blockstore::Block;
|
||||||
|
|
||||||
|
using std::unique_ptr;
|
||||||
|
using std::make_unique;
|
||||||
|
using std::runtime_error;
|
||||||
|
|
||||||
|
namespace blobstore {
|
||||||
|
namespace onblocks {
|
||||||
|
|
||||||
|
DataNode::DataNode(unique_ptr<Block> block)
|
||||||
|
: _block(std::move(block)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
DataNode::~DataNode() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataNode::flush() {
|
||||||
|
_block->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_ptr<DataNode> DataNode::load(unique_ptr<Block> block) {
|
||||||
|
NodeHeader *header = (NodeHeader*)block->data();
|
||||||
|
if (header->magicNumber == magicNumberInnerNode) {
|
||||||
|
return make_unique<DataInnerNode>(std::move(block));
|
||||||
|
} else if (header->magicNumber == magicNumberLeaf) {
|
||||||
|
return make_unique<DataLeafNode>(std::move(block));
|
||||||
|
} else {
|
||||||
|
//TODO Better exception
|
||||||
|
throw runtime_error("Invalid node magic number");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_ptr<DataInnerNode> DataNode::initializeNewInnerNode(unique_ptr<Block> block) {
|
||||||
|
auto newNode = make_unique<DataInnerNode>(std::move(block));
|
||||||
|
newNode->InitializeEmptyInnerNode();
|
||||||
|
return newNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_ptr<DataLeafNode> DataNode::initializeNewLeafNode(unique_ptr<Block> block) {
|
||||||
|
auto newNode = make_unique<DataLeafNode>(std::move(block));
|
||||||
|
newNode->InitializeEmptyLeaf();
|
||||||
|
return newNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
41
src/blobstore/implementations/onblocks/impl/DataNode.h
Normal file
41
src/blobstore/implementations/onblocks/impl/DataNode.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_IMPL_DATANODE_H_
|
||||||
|
#define BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_IMPL_DATANODE_H_
|
||||||
|
|
||||||
|
#include "blockstore/interface/Block.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace blobstore {
|
||||||
|
namespace onblocks {
|
||||||
|
class DataInnerNode;
|
||||||
|
class DataLeafNode;
|
||||||
|
|
||||||
|
class DataNode {
|
||||||
|
public:
|
||||||
|
virtual ~DataNode();
|
||||||
|
|
||||||
|
static constexpr unsigned char magicNumberInnerNode = 0x01;
|
||||||
|
static constexpr unsigned char magicNumberLeaf = 0x02;
|
||||||
|
struct NodeHeader {
|
||||||
|
unsigned char magicNumber;
|
||||||
|
};
|
||||||
|
|
||||||
|
void flush();
|
||||||
|
|
||||||
|
static std::unique_ptr<DataNode> load(std::unique_ptr<blockstore::Block> block);
|
||||||
|
|
||||||
|
static std::unique_ptr<DataInnerNode> initializeNewInnerNode(std::unique_ptr<blockstore::Block> block);
|
||||||
|
static std::unique_ptr<DataLeafNode> initializeNewLeafNode(std::unique_ptr<blockstore::Block> block);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DataNode(std::unique_ptr<blockstore::Block> block);
|
||||||
|
|
||||||
|
std::unique_ptr<blockstore::Block> _block;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,63 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "blockstore/implementations/inmemory/InMemoryBlockStore.h"
|
||||||
|
#include "blockstore/implementations/inmemory/InMemoryBlock.h"
|
||||||
|
#include "blobstore/implementations/onblocks/BlobStoreOnBlocks.h"
|
||||||
|
#include "blobstore/implementations/onblocks/impl/DataNode.h"
|
||||||
|
#include "blobstore/implementations/onblocks/impl/DataLeafNode.h"
|
||||||
|
#include "blobstore/implementations/onblocks/impl/DataInnerNode.h"
|
||||||
|
|
||||||
|
using ::testing::Test;
|
||||||
|
using std::unique_ptr;
|
||||||
|
using std::make_unique;
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
using blockstore::BlockStore;
|
||||||
|
using blockstore::inmemory::InMemoryBlockStore;
|
||||||
|
using namespace blobstore;
|
||||||
|
using namespace blobstore::onblocks;
|
||||||
|
|
||||||
|
class DataNodeTest: public Test {
|
||||||
|
public:
|
||||||
|
unique_ptr<BlockStore> blockStore = make_unique<InMemoryBlockStore>();
|
||||||
|
};
|
||||||
|
|
||||||
|
#define EXPECT_IS_PTR_TYPE(Type, ptr) EXPECT_NE(nullptr, dynamic_cast<Type*>(ptr)) << "Given pointer cannot be cast to the given type"
|
||||||
|
|
||||||
|
TEST_F(DataNodeTest, InitializeNewLeafNodeCreatesLeafNodeObject) {
|
||||||
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
||||||
|
string key = block.key;
|
||||||
|
auto leafNode = DataNode::initializeNewLeafNode(std::move(block.block));
|
||||||
|
|
||||||
|
EXPECT_IS_PTR_TYPE(DataLeafNode, leafNode.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DataNodeTest, InitializeNewInnerNodeCreatesInnerNodeObject) {
|
||||||
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
||||||
|
string key = block.key;
|
||||||
|
auto innerNode = DataNode::initializeNewInnerNode(std::move(block.block));
|
||||||
|
|
||||||
|
EXPECT_IS_PTR_TYPE(DataInnerNode, innerNode.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DataNodeTest, LeafNodeIsRecognizedAfterStoreAndLoad) {
|
||||||
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
||||||
|
string key = block.key;
|
||||||
|
auto node = DataNode::initializeNewLeafNode(std::move(block.block));
|
||||||
|
node->flush();
|
||||||
|
|
||||||
|
auto loaded_node = DataNode::load(blockStore->load(key));
|
||||||
|
|
||||||
|
EXPECT_IS_PTR_TYPE(DataLeafNode, loaded_node.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DataNodeTest, InnerNodeIsRecognizedAfterStoreAndLoad) {
|
||||||
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
||||||
|
string key = block.key;
|
||||||
|
auto node = DataNode::initializeNewInnerNode(std::move(block.block));
|
||||||
|
node->flush();
|
||||||
|
|
||||||
|
auto loaded_node = DataNode::load(blockStore->load(key));
|
||||||
|
|
||||||
|
EXPECT_IS_PTR_TYPE(DataInnerNode, loaded_node.get());
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user