Since blocks now store their keys, we don't need to store it somewhere else.
This commit is contained in:
parent
03e10cabf5
commit
dd2c96e363
@ -11,8 +11,8 @@ namespace blobstore {
|
|||||||
namespace onblocks {
|
namespace onblocks {
|
||||||
namespace datanodestore {
|
namespace datanodestore {
|
||||||
|
|
||||||
DataInnerNode::DataInnerNode(DataNodeView view, const Key &key)
|
DataInnerNode::DataInnerNode(DataNodeView view)
|
||||||
: DataNode(std::move(view), key) {
|
: DataNode(std::move(view)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DataInnerNode::~DataInnerNode() {
|
DataInnerNode::~DataInnerNode() {
|
||||||
|
@ -10,7 +10,7 @@ namespace datanodestore {
|
|||||||
|
|
||||||
class DataInnerNode: public DataNode {
|
class DataInnerNode: public DataNode {
|
||||||
public:
|
public:
|
||||||
DataInnerNode(DataNodeView block, const blockstore::Key &key);
|
DataInnerNode(DataNodeView block);
|
||||||
virtual ~DataInnerNode();
|
virtual ~DataInnerNode();
|
||||||
|
|
||||||
struct ChildEntry {
|
struct ChildEntry {
|
||||||
|
@ -11,8 +11,8 @@ namespace blobstore {
|
|||||||
namespace onblocks {
|
namespace onblocks {
|
||||||
namespace datanodestore {
|
namespace datanodestore {
|
||||||
|
|
||||||
DataLeafNode::DataLeafNode(DataNodeView view, const Key &key)
|
DataLeafNode::DataLeafNode(DataNodeView view)
|
||||||
: DataNode(std::move(view), key) {
|
: DataNode(std::move(view)) {
|
||||||
assert(numBytes() <= MAX_STORED_BYTES);
|
assert(numBytes() <= MAX_STORED_BYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ class DataInnerNode;
|
|||||||
|
|
||||||
class DataLeafNode: public DataNode {
|
class DataLeafNode: public DataNode {
|
||||||
public:
|
public:
|
||||||
DataLeafNode(DataNodeView block, const blockstore::Key &key);
|
DataLeafNode(DataNodeView block);
|
||||||
virtual ~DataLeafNode();
|
virtual ~DataLeafNode();
|
||||||
|
|
||||||
static constexpr uint32_t MAX_STORED_BYTES = DataNodeView::DATASIZE_BYTES;
|
static constexpr uint32_t MAX_STORED_BYTES = DataNodeView::DATASIZE_BYTES;
|
||||||
|
@ -14,8 +14,8 @@ namespace blobstore {
|
|||||||
namespace onblocks {
|
namespace onblocks {
|
||||||
namespace datanodestore {
|
namespace datanodestore {
|
||||||
|
|
||||||
DataNode::DataNode(DataNodeView node, const Key &key)
|
DataNode::DataNode(DataNodeView node)
|
||||||
: _key(key), _node(std::move(node)) {
|
: _node(std::move(node)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DataNode::~DataNode() {
|
DataNode::~DataNode() {
|
||||||
@ -30,7 +30,7 @@ const DataNodeView &DataNode::node() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Key &DataNode::key() const {
|
const Key &DataNode::key() const {
|
||||||
return _key;
|
return _node.key();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t DataNode::depth() const {
|
uint8_t DataNode::depth() const {
|
||||||
@ -42,7 +42,7 @@ unique_ptr<DataInnerNode> DataNode::convertToNewInnerNode(unique_ptr<DataNode> n
|
|||||||
auto block = node->_node.releaseBlock();
|
auto block = node->_node.releaseBlock();
|
||||||
std::memset(block->data(), 0, block->size());
|
std::memset(block->data(), 0, block->size());
|
||||||
|
|
||||||
auto innerNode = make_unique<DataInnerNode>(DataNodeView(std::move(block)), key);
|
auto innerNode = make_unique<DataInnerNode>(DataNodeView(std::move(block)));
|
||||||
innerNode->InitializeNewNode(first_child);
|
innerNode->InitializeNewNode(first_child);
|
||||||
return innerNode;
|
return innerNode;
|
||||||
}
|
}
|
||||||
|
@ -22,14 +22,13 @@ public:
|
|||||||
static std::unique_ptr<DataInnerNode> convertToNewInnerNode(std::unique_ptr<DataNode> node, const DataNode &first_child);
|
static std::unique_ptr<DataInnerNode> convertToNewInnerNode(std::unique_ptr<DataNode> node, const DataNode &first_child);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DataNode(DataNodeView block, const blockstore::Key &key);
|
DataNode(DataNodeView block);
|
||||||
|
|
||||||
DataNodeView &node();
|
DataNodeView &node();
|
||||||
const DataNodeView &node() const;
|
const DataNodeView &node() const;
|
||||||
friend class DataNodeStore;
|
friend class DataNodeStore;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
blockstore::Key _key; //TODO Remove this and make blockstore::Block store the key
|
|
||||||
DataNodeView _node;
|
DataNodeView _node;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(DataNode);
|
DISALLOW_COPY_AND_ASSIGN(DataNode);
|
||||||
|
@ -24,13 +24,13 @@ DataNodeStore::DataNodeStore(unique_ptr<BlockStore> blockstore)
|
|||||||
DataNodeStore::~DataNodeStore() {
|
DataNodeStore::~DataNodeStore() {
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataNode> DataNodeStore::load(unique_ptr<Block> block, const Key &key) {
|
unique_ptr<DataNode> DataNodeStore::load(unique_ptr<Block> block) {
|
||||||
DataNodeView node(std::move(block));
|
DataNodeView node(std::move(block));
|
||||||
|
|
||||||
if (*node.Depth() == 0) {
|
if (*node.Depth() == 0) {
|
||||||
return unique_ptr<DataLeafNode>(new DataLeafNode(std::move(node), key));
|
return unique_ptr<DataLeafNode>(new DataLeafNode(std::move(node)));
|
||||||
} else if (*node.Depth() <= MAX_DEPTH) {
|
} else if (*node.Depth() <= MAX_DEPTH) {
|
||||||
return unique_ptr<DataInnerNode>(new DataInnerNode(std::move(node), key));
|
return unique_ptr<DataInnerNode>(new DataInnerNode(std::move(node)));
|
||||||
} else {
|
} else {
|
||||||
throw runtime_error("Tree is to deep. Data corruption?");
|
throw runtime_error("Tree is to deep. Data corruption?");
|
||||||
}
|
}
|
||||||
@ -38,25 +38,25 @@ unique_ptr<DataNode> DataNodeStore::load(unique_ptr<Block> block, const Key &key
|
|||||||
|
|
||||||
unique_ptr<DataInnerNode> DataNodeStore::createNewInnerNode(const DataNode &first_child) {
|
unique_ptr<DataInnerNode> DataNodeStore::createNewInnerNode(const DataNode &first_child) {
|
||||||
auto block = _blockstore->create(DataNodeView::BLOCKSIZE_BYTES);
|
auto block = _blockstore->create(DataNodeView::BLOCKSIZE_BYTES);
|
||||||
auto newNode = make_unique<DataInnerNode>(std::move(block.block), block.key);
|
auto newNode = make_unique<DataInnerNode>(std::move(block));
|
||||||
newNode->InitializeNewNode(first_child);
|
newNode->InitializeNewNode(first_child);
|
||||||
return std::move(newNode);
|
return std::move(newNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataLeafNode> DataNodeStore::createNewLeafNode() {
|
unique_ptr<DataLeafNode> DataNodeStore::createNewLeafNode() {
|
||||||
auto block = _blockstore->create(DataNodeView::BLOCKSIZE_BYTES);
|
auto block = _blockstore->create(DataNodeView::BLOCKSIZE_BYTES);
|
||||||
auto newNode = make_unique<DataLeafNode>(std::move(block.block), block.key);
|
auto newNode = make_unique<DataLeafNode>(std::move(block));
|
||||||
newNode->InitializeNewNode();
|
newNode->InitializeNewNode();
|
||||||
return std::move(newNode);
|
return std::move(newNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataNode> DataNodeStore::load(const Key &key) {
|
unique_ptr<DataNode> DataNodeStore::load(const Key &key) {
|
||||||
return load(_blockstore->load(key), key);
|
return load(_blockstore->load(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataNode> DataNodeStore::createNewNodeAsCopyFrom(const DataNode &source) {
|
unique_ptr<DataNode> DataNodeStore::createNewNodeAsCopyFrom(const DataNode &source) {
|
||||||
auto newBlock = blockstore::utils::copyToNewBlock(_blockstore.get(), source.node().block());
|
auto newBlock = blockstore::utils::copyToNewBlock(_blockstore.get(), source.node().block());
|
||||||
return load(std::move(newBlock.block), newBlock.key);
|
return load(std::move(newBlock));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
std::unique_ptr<DataNode> createNewNodeAsCopyFrom(const DataNode &source);
|
std::unique_ptr<DataNode> createNewNodeAsCopyFrom(const DataNode &source);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<DataNode> load(std::unique_ptr<blockstore::Block> block, const blockstore::Key &key);
|
std::unique_ptr<DataNode> load(std::unique_ptr<blockstore::Block> block);
|
||||||
|
|
||||||
std::unique_ptr<blockstore::BlockStore> _blockstore;
|
std::unique_ptr<blockstore::BlockStore> _blockstore;
|
||||||
|
|
||||||
|
@ -80,6 +80,10 @@ public:
|
|||||||
return *_block;
|
return *_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const blockstore::Key &key() const {
|
||||||
|
return _block->key();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<int offset, class Type>
|
template<int offset, class Type>
|
||||||
const Type *GetOffset() const {
|
const Type *GetOffset() const {
|
||||||
|
@ -21,7 +21,6 @@ using std::string;
|
|||||||
using fspp::dynamic_pointer_move;
|
using fspp::dynamic_pointer_move;
|
||||||
|
|
||||||
using blockstore::BlockStore;
|
using blockstore::BlockStore;
|
||||||
using blockstore::BlockWithKey;
|
|
||||||
using blockstore::Data;
|
using blockstore::Data;
|
||||||
using blockstore::Key;
|
using blockstore::Key;
|
||||||
using blockstore::testfake::FakeBlockStore;
|
using blockstore::testfake::FakeBlockStore;
|
||||||
|
@ -70,9 +70,9 @@ TEST_F(DataNodeStoreTest, InnerNodeWithDepth2IsRecognizedAfterStoreAndLoad) {
|
|||||||
|
|
||||||
TEST_F(DataNodeStoreTest, DataNodeCrashesOnLoadIfDepthIsTooHigh) {
|
TEST_F(DataNodeStoreTest, DataNodeCrashesOnLoadIfDepthIsTooHigh) {
|
||||||
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
||||||
Key key = block.key;
|
Key key = block->key();
|
||||||
{
|
{
|
||||||
DataNodeView view(std::move(block.block));
|
DataNodeView view(std::move(block));
|
||||||
*view.Depth() = DataNodeStore::MAX_DEPTH + 1;
|
*view.Depth() = DataNodeStore::MAX_DEPTH + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,11 +30,12 @@ INSTANTIATE_TEST_CASE_P(DataNodeViewDepthTest, DataNodeViewDepthTest, Values(0,
|
|||||||
|
|
||||||
TEST_P(DataNodeViewDepthTest, DepthIsStored) {
|
TEST_P(DataNodeViewDepthTest, DepthIsStored) {
|
||||||
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
||||||
|
auto key = block->key();
|
||||||
{
|
{
|
||||||
DataNodeView view(std::move(block.block));
|
DataNodeView view(std::move(block));
|
||||||
*view.Depth() = GetParam();
|
*view.Depth() = GetParam();
|
||||||
}
|
}
|
||||||
DataNodeView view(blockStore->load(block.key));
|
DataNodeView view(blockStore->load(key));
|
||||||
EXPECT_EQ(GetParam(), *view.Depth());
|
EXPECT_EQ(GetParam(), *view.Depth());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,35 +45,38 @@ INSTANTIATE_TEST_CASE_P(DataNodeViewSizeTest, DataNodeViewSizeTest, Values(0, 50
|
|||||||
|
|
||||||
TEST_P(DataNodeViewSizeTest, SizeIsStored) {
|
TEST_P(DataNodeViewSizeTest, SizeIsStored) {
|
||||||
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
||||||
|
auto key = block->key();
|
||||||
{
|
{
|
||||||
DataNodeView view(std::move(block.block));
|
DataNodeView view(std::move(block));
|
||||||
*view.Size() = GetParam();
|
*view.Size() = GetParam();
|
||||||
}
|
}
|
||||||
DataNodeView view(blockStore->load(block.key));
|
DataNodeView view(blockStore->load(key));
|
||||||
EXPECT_EQ(GetParam(), *view.Size());
|
EXPECT_EQ(GetParam(), *view.Size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DataNodeViewTest, DataIsStored) {
|
TEST_F(DataNodeViewTest, DataIsStored) {
|
||||||
DataBlockFixture randomData(DataNodeView::DATASIZE_BYTES);
|
DataBlockFixture randomData(DataNodeView::DATASIZE_BYTES);
|
||||||
auto block = blockStore->create(DataNodeView::BLOCKSIZE_BYTES);
|
auto block = blockStore->create(DataNodeView::BLOCKSIZE_BYTES);
|
||||||
|
auto key = block->key();
|
||||||
{
|
{
|
||||||
DataNodeView view(std::move(block.block));
|
DataNodeView view(std::move(block));
|
||||||
std::memcpy(view.DataBegin<uint8_t>(), randomData.data(), randomData.size());
|
std::memcpy(view.DataBegin<uint8_t>(), randomData.data(), randomData.size());
|
||||||
}
|
}
|
||||||
DataNodeView view(blockStore->load(block.key));
|
DataNodeView view(blockStore->load(key));
|
||||||
EXPECT_EQ(0, std::memcmp(view.DataBegin<uint8_t>(), randomData.data(), randomData.size()));
|
EXPECT_EQ(0, std::memcmp(view.DataBegin<uint8_t>(), randomData.data(), randomData.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DataNodeViewTest, HeaderAndBodyDontOverlap) {
|
TEST_F(DataNodeViewTest, HeaderAndBodyDontOverlap) {
|
||||||
DataBlockFixture randomData(DataNodeView::DATASIZE_BYTES);
|
DataBlockFixture randomData(DataNodeView::DATASIZE_BYTES);
|
||||||
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
||||||
|
auto key = block->key();
|
||||||
{
|
{
|
||||||
DataNodeView view(std::move(block.block));
|
DataNodeView view(std::move(block));
|
||||||
*view.Depth() = 3;
|
*view.Depth() = 3;
|
||||||
*view.Size() = 1000000000u;
|
*view.Size() = 1000000000u;
|
||||||
std::memcpy(view.DataBegin<uint8_t>(), randomData.data(), DataNodeView::DATASIZE_BYTES);
|
std::memcpy(view.DataBegin<uint8_t>(), randomData.data(), DataNodeView::DATASIZE_BYTES);
|
||||||
}
|
}
|
||||||
DataNodeView view(blockStore->load(block.key));
|
DataNodeView view(blockStore->load(key));
|
||||||
EXPECT_EQ(3, *view.Depth());
|
EXPECT_EQ(3, *view.Depth());
|
||||||
EXPECT_EQ(1000000000u, *view.Size());
|
EXPECT_EQ(1000000000u, *view.Size());
|
||||||
EXPECT_EQ(0, std::memcmp(view.DataBegin<uint8_t>(), randomData.data(), DataNodeView::DATASIZE_BYTES));
|
EXPECT_EQ(0, std::memcmp(view.DataBegin<uint8_t>(), randomData.data(), DataNodeView::DATASIZE_BYTES));
|
||||||
@ -80,32 +84,32 @@ TEST_F(DataNodeViewTest, HeaderAndBodyDontOverlap) {
|
|||||||
|
|
||||||
TEST_F(DataNodeViewTest, DataBeginWorksWithOneByteEntries) {
|
TEST_F(DataNodeViewTest, DataBeginWorksWithOneByteEntries) {
|
||||||
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
||||||
uint8_t *blockBegin = (uint8_t*)block.block->data();
|
uint8_t *blockBegin = (uint8_t*)block->data();
|
||||||
DataNodeView view(std::move(block.block));
|
DataNodeView view(std::move(block));
|
||||||
|
|
||||||
EXPECT_EQ(blockBegin+view.HEADERSIZE_BYTES, view.DataBegin<uint8_t>());
|
EXPECT_EQ(blockBegin+view.HEADERSIZE_BYTES, view.DataBegin<uint8_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DataNodeViewTest, DataBeginWorksWithEightByteEntries) {
|
TEST_F(DataNodeViewTest, DataBeginWorksWithEightByteEntries) {
|
||||||
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
||||||
uint8_t *blockBegin = (uint8_t*)block.block->data();
|
uint8_t *blockBegin = (uint8_t*)block->data();
|
||||||
DataNodeView view(std::move(block.block));
|
DataNodeView view(std::move(block));
|
||||||
|
|
||||||
EXPECT_EQ(blockBegin+view.HEADERSIZE_BYTES, (uint8_t*)view.DataBegin<uint64_t>());
|
EXPECT_EQ(blockBegin+view.HEADERSIZE_BYTES, (uint8_t*)view.DataBegin<uint64_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DataNodeViewTest, DataEndWorksWithOneByteEntries) {
|
TEST_F(DataNodeViewTest, DataEndWorksWithOneByteEntries) {
|
||||||
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
||||||
uint8_t *blockBegin = (uint8_t*)block.block->data();
|
uint8_t *blockBegin = (uint8_t*)block->data();
|
||||||
DataNodeView view(std::move(block.block));
|
DataNodeView view(std::move(block));
|
||||||
|
|
||||||
EXPECT_EQ(blockBegin+view.BLOCKSIZE_BYTES, view.DataEnd<uint8_t>());
|
EXPECT_EQ(blockBegin+view.BLOCKSIZE_BYTES, view.DataEnd<uint8_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DataNodeViewTest, DataEndWorksWithEightByteEntries) {
|
TEST_F(DataNodeViewTest, DataEndWorksWithEightByteEntries) {
|
||||||
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
||||||
uint8_t *blockBegin = (uint8_t*)block.block->data();
|
uint8_t *blockBegin = (uint8_t*)block->data();
|
||||||
DataNodeView view(std::move(block.block));
|
DataNodeView view(std::move(block));
|
||||||
|
|
||||||
EXPECT_EQ(blockBegin+view.BLOCKSIZE_BYTES, (uint8_t*)view.DataEnd<uint64_t>());
|
EXPECT_EQ(blockBegin+view.BLOCKSIZE_BYTES, (uint8_t*)view.DataEnd<uint64_t>());
|
||||||
}
|
}
|
||||||
@ -120,16 +124,16 @@ BOOST_STATIC_ASSERT_MSG(DataNodeView::DATASIZE_BYTES % sizeof(SizedDataEntry) !=
|
|||||||
|
|
||||||
TEST_F(DataNodeViewTest, DataBeginWorksWithStructEntries) {
|
TEST_F(DataNodeViewTest, DataBeginWorksWithStructEntries) {
|
||||||
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
||||||
uint8_t *blockBegin = (uint8_t*)block.block->data();
|
uint8_t *blockBegin = (uint8_t*)block->data();
|
||||||
DataNodeView view(std::move(block.block));
|
DataNodeView view(std::move(block));
|
||||||
|
|
||||||
EXPECT_EQ(blockBegin+view.HEADERSIZE_BYTES, (uint8_t*)view.DataBegin<SizedDataEntry>());
|
EXPECT_EQ(blockBegin+view.HEADERSIZE_BYTES, (uint8_t*)view.DataBegin<SizedDataEntry>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DataNodeViewTest, DataEndWorksWithStructByteEntries) {
|
TEST_F(DataNodeViewTest, DataEndWorksWithStructByteEntries) {
|
||||||
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
|
||||||
uint8_t *blockBegin = (uint8_t*)block.block->data();
|
uint8_t *blockBegin = (uint8_t*)block->data();
|
||||||
DataNodeView view(std::move(block.block));
|
DataNodeView view(std::move(block));
|
||||||
|
|
||||||
unsigned int numFittingEntries = view.DATASIZE_BYTES / sizeof(SizedDataEntry);
|
unsigned int numFittingEntries = view.DATASIZE_BYTES / sizeof(SizedDataEntry);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user