Use unique_ref instead of unique_ptr
This commit is contained in:
parent
7fae2d1e59
commit
3d1341114b
@ -5,8 +5,8 @@
|
|||||||
#include "utils/Math.h"
|
#include "utils/Math.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
using std::unique_ptr;
|
|
||||||
using std::function;
|
using std::function;
|
||||||
|
using cpputils::unique_ref;
|
||||||
using blobstore::onblocks::datanodestore::DataLeafNode;
|
using blobstore::onblocks::datanodestore::DataLeafNode;
|
||||||
using blobstore::onblocks::datanodestore::DataNodeLayout;
|
using blobstore::onblocks::datanodestore::DataNodeLayout;
|
||||||
using blockstore::Key;
|
using blockstore::Key;
|
||||||
@ -16,7 +16,7 @@ namespace onblocks {
|
|||||||
|
|
||||||
using parallelaccessdatatreestore::DataTreeRef;
|
using parallelaccessdatatreestore::DataTreeRef;
|
||||||
|
|
||||||
BlobOnBlocks::BlobOnBlocks(unique_ptr<DataTreeRef> datatree)
|
BlobOnBlocks::BlobOnBlocks(unique_ref<DataTreeRef> datatree)
|
||||||
: _datatree(std::move(datatree)) {
|
: _datatree(std::move(datatree)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ Key BlobOnBlocks::key() const {
|
|||||||
return _datatree->key();
|
return _datatree->key();
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTreeRef> BlobOnBlocks::releaseTree() {
|
unique_ref<DataTreeRef> BlobOnBlocks::releaseTree() {
|
||||||
return std::move(_datatree);
|
return std::move(_datatree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ class DataTreeRef;
|
|||||||
|
|
||||||
class BlobOnBlocks: public Blob {
|
class BlobOnBlocks: public Blob {
|
||||||
public:
|
public:
|
||||||
BlobOnBlocks(std::unique_ptr<parallelaccessdatatreestore::DataTreeRef> datatree);
|
BlobOnBlocks(cpputils::unique_ref<parallelaccessdatatreestore::DataTreeRef> datatree);
|
||||||
virtual ~BlobOnBlocks();
|
virtual ~BlobOnBlocks();
|
||||||
|
|
||||||
blockstore::Key key() const override;
|
blockstore::Key key() const override;
|
||||||
@ -31,14 +31,14 @@ public:
|
|||||||
|
|
||||||
void flush() override;
|
void flush() override;
|
||||||
|
|
||||||
std::unique_ptr<parallelaccessdatatreestore::DataTreeRef> releaseTree();
|
cpputils::unique_ref<parallelaccessdatatreestore::DataTreeRef> releaseTree();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void traverseLeaves(uint64_t offsetBytes, uint64_t sizeBytes, std::function<void (uint64_t, datanodestore::DataLeafNode *, uint32_t, uint32_t)>) const;
|
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);
|
void resizeIfSmallerThan(uint64_t neededSize);
|
||||||
|
|
||||||
std::unique_ptr<parallelaccessdatatreestore::DataTreeRef> _datatree;
|
cpputils::unique_ref<parallelaccessdatatreestore::DataTreeRef> _datatree;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,6 @@
|
|||||||
#include "BlobOnBlocks.h"
|
#include "BlobOnBlocks.h"
|
||||||
#include <messmer/cpp-utils/pointer/cast.h>
|
#include <messmer/cpp-utils/pointer/cast.h>
|
||||||
|
|
||||||
using std::unique_ptr;
|
|
||||||
using std::make_unique;
|
|
||||||
|
|
||||||
using cpputils::unique_ref;
|
using cpputils::unique_ref;
|
||||||
using cpputils::make_unique_ref;
|
using cpputils::make_unique_ref;
|
||||||
|
|
||||||
@ -29,8 +26,8 @@ using datanodestore::DataNodeStore;
|
|||||||
using datatreestore::DataTreeStore;
|
using datatreestore::DataTreeStore;
|
||||||
using parallelaccessdatatreestore::ParallelAccessDataTreeStore;
|
using parallelaccessdatatreestore::ParallelAccessDataTreeStore;
|
||||||
|
|
||||||
BlobStoreOnBlocks::BlobStoreOnBlocks(unique_ptr<BlockStore> blockStore, uint32_t blocksizeBytes)
|
BlobStoreOnBlocks::BlobStoreOnBlocks(unique_ref<BlockStore> blockStore, uint32_t blocksizeBytes)
|
||||||
: _dataTreeStore(make_unique<ParallelAccessDataTreeStore>(make_unique<DataTreeStore>(make_unique<DataNodeStore>(make_unique<ParallelAccessBlockStore>(std::move(blockStore)), blocksizeBytes)))) {
|
: _dataTreeStore(make_unique_ref<ParallelAccessDataTreeStore>(make_unique_ref<DataTreeStore>(make_unique_ref<DataNodeStore>(make_unique_ref<ParallelAccessBlockStore>(std::move(blockStore)), blocksizeBytes)))) {
|
||||||
}
|
}
|
||||||
|
|
||||||
BlobStoreOnBlocks::~BlobStoreOnBlocks() {
|
BlobStoreOnBlocks::~BlobStoreOnBlocks() {
|
||||||
@ -42,10 +39,10 @@ unique_ref<Blob> BlobStoreOnBlocks::create() {
|
|||||||
|
|
||||||
optional<unique_ref<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 == none) {
|
||||||
return none;
|
return none;
|
||||||
}
|
}
|
||||||
return optional<unique_ref<Blob>>(make_unique_ref<BlobOnBlocks>(std::move(tree)));
|
return optional<unique_ref<Blob>>(make_unique_ref<BlobOnBlocks>(std::move(*tree)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlobStoreOnBlocks::remove(unique_ref<Blob> blob) {
|
void BlobStoreOnBlocks::remove(unique_ref<Blob> blob) {
|
||||||
|
@ -15,7 +15,7 @@ class ParallelAccessDataTreeStore;
|
|||||||
|
|
||||||
class BlobStoreOnBlocks: public BlobStore {
|
class BlobStoreOnBlocks: public BlobStore {
|
||||||
public:
|
public:
|
||||||
BlobStoreOnBlocks(std::unique_ptr<blockstore::BlockStore> blockStore, uint32_t blocksizeBytes);
|
BlobStoreOnBlocks(cpputils::unique_ref<blockstore::BlockStore> blockStore, uint32_t blocksizeBytes);
|
||||||
virtual ~BlobStoreOnBlocks();
|
virtual ~BlobStoreOnBlocks();
|
||||||
|
|
||||||
cpputils::unique_ref<Blob> create() override;
|
cpputils::unique_ref<Blob> create() override;
|
||||||
@ -24,7 +24,7 @@ public:
|
|||||||
void remove(cpputils::unique_ref<Blob> blob) override;
|
void remove(cpputils::unique_ref<Blob> blob) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<parallelaccessdatatreestore::ParallelAccessDataTreeStore> _dataTreeStore;
|
cpputils::unique_ref<parallelaccessdatatreestore::ParallelAccessDataTreeStore> _dataTreeStore;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,10 @@
|
|||||||
#include "DataNodeStore.h"
|
#include "DataNodeStore.h"
|
||||||
|
|
||||||
using std::unique_ptr;
|
using std::unique_ptr;
|
||||||
using std::make_unique;
|
|
||||||
using blockstore::Block;
|
using blockstore::Block;
|
||||||
using cpputils::Data;
|
using cpputils::Data;
|
||||||
|
using cpputils::unique_ref;
|
||||||
|
using cpputils::make_unique_ref;
|
||||||
using blockstore::Key;
|
using blockstore::Key;
|
||||||
|
|
||||||
namespace blobstore {
|
namespace blobstore {
|
||||||
@ -19,11 +20,11 @@ DataInnerNode::DataInnerNode(DataNodeView view)
|
|||||||
DataInnerNode::~DataInnerNode() {
|
DataInnerNode::~DataInnerNode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataInnerNode::InitializeNewNode(unique_ptr<Block> block, const DataNode &first_child) {
|
unique_ref<DataInnerNode> DataInnerNode::InitializeNewNode(unique_ptr<Block> block, const DataNode &first_child) {
|
||||||
DataNodeView node(std::move(block));
|
DataNodeView node(std::move(block));
|
||||||
node.setDepth(first_child.depth() + 1);
|
node.setDepth(first_child.depth() + 1);
|
||||||
node.setSize(1);
|
node.setSize(1);
|
||||||
auto result = make_unique<DataInnerNode>(std::move(node));
|
auto result = make_unique_ref<DataInnerNode>(std::move(node));
|
||||||
result->ChildrenBegin()->setKey(first_child.key());
|
result->ChildrenBegin()->setKey(first_child.key());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ namespace datanodestore {
|
|||||||
|
|
||||||
class DataInnerNode: public DataNode {
|
class DataInnerNode: public DataNode {
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<DataInnerNode> InitializeNewNode(std::unique_ptr<blockstore::Block> block, const DataNode &first_child_key);
|
static cpputils::unique_ref<DataInnerNode> InitializeNewNode(std::unique_ptr<blockstore::Block> block, const DataNode &first_child_key);
|
||||||
|
|
||||||
DataInnerNode(DataNodeView block);
|
DataInnerNode(DataNodeView block);
|
||||||
virtual ~DataInnerNode();
|
virtual ~DataInnerNode();
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
#include "DataInnerNode.h"
|
#include "DataInnerNode.h"
|
||||||
|
|
||||||
using std::unique_ptr;
|
using std::unique_ptr;
|
||||||
using std::make_unique;
|
|
||||||
using blockstore::Block;
|
using blockstore::Block;
|
||||||
using cpputils::Data;
|
using cpputils::Data;
|
||||||
using blockstore::Key;
|
using blockstore::Key;
|
||||||
|
using cpputils::unique_ref;
|
||||||
|
using cpputils::make_unique_ref;
|
||||||
|
|
||||||
namespace blobstore {
|
namespace blobstore {
|
||||||
namespace onblocks {
|
namespace onblocks {
|
||||||
@ -20,12 +21,12 @@ DataLeafNode::DataLeafNode(DataNodeView view)
|
|||||||
DataLeafNode::~DataLeafNode() {
|
DataLeafNode::~DataLeafNode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataLeafNode> DataLeafNode::InitializeNewNode(unique_ptr<Block> block) {
|
unique_ref<DataLeafNode> DataLeafNode::InitializeNewNode(unique_ptr<Block> block) {
|
||||||
DataNodeView node(std::move(block));
|
DataNodeView node(std::move(block));
|
||||||
node.setDepth(0);
|
node.setDepth(0);
|
||||||
node.setSize(0);
|
node.setSize(0);
|
||||||
//fillDataWithZeroes(); not needed, because a newly created block will be zeroed out. DataLeafNodeTest.SpaceIsZeroFilledWhenGrowing ensures this.
|
//fillDataWithZeroes(); not needed, because a newly created block will be zeroed out. DataLeafNodeTest.SpaceIsZeroFilledWhenGrowing ensures this.
|
||||||
return make_unique<DataLeafNode>(std::move(node));
|
return make_unique_ref<DataLeafNode>(std::move(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataLeafNode::read(void *target, uint64_t offset, uint64_t size) const {
|
void DataLeafNode::read(void *target, uint64_t offset, uint64_t size) const {
|
||||||
|
@ -11,7 +11,7 @@ class DataInnerNode;
|
|||||||
|
|
||||||
class DataLeafNode: public DataNode {
|
class DataLeafNode: public DataNode {
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<DataLeafNode> InitializeNewNode(std::unique_ptr<blockstore::Block> block);
|
static cpputils::unique_ref<DataLeafNode> InitializeNewNode(std::unique_ptr<blockstore::Block> block);
|
||||||
|
|
||||||
DataLeafNode(DataNodeView block);
|
DataLeafNode(DataNodeView block);
|
||||||
virtual ~DataLeafNode();
|
virtual ~DataLeafNode();
|
||||||
|
@ -7,9 +7,8 @@
|
|||||||
using blockstore::Block;
|
using blockstore::Block;
|
||||||
using blockstore::Key;
|
using blockstore::Key;
|
||||||
|
|
||||||
using std::unique_ptr;
|
|
||||||
using std::make_unique;
|
|
||||||
using std::runtime_error;
|
using std::runtime_error;
|
||||||
|
using cpputils::unique_ref;
|
||||||
|
|
||||||
namespace blobstore {
|
namespace blobstore {
|
||||||
namespace onblocks {
|
namespace onblocks {
|
||||||
@ -38,7 +37,7 @@ uint8_t DataNode::depth() const {
|
|||||||
return _node.Depth();
|
return _node.Depth();
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataNode::convertToNewInnerNode(unique_ptr<DataNode> node, const DataNode &first_child) {
|
unique_ref<DataInnerNode> DataNode::convertToNewInnerNode(unique_ref<DataNode> node, const DataNode &first_child) {
|
||||||
Key key = node->key();
|
Key key = node->key();
|
||||||
auto block = node->_node.releaseBlock();
|
auto block = node->_node.releaseBlock();
|
||||||
blockstore::utils::fillWithZeroes(block.get());
|
blockstore::utils::fillWithZeroes(block.get());
|
||||||
|
@ -19,7 +19,7 @@ public:
|
|||||||
|
|
||||||
uint8_t depth() const;
|
uint8_t depth() const;
|
||||||
|
|
||||||
static std::unique_ptr<DataInnerNode> convertToNewInnerNode(std::unique_ptr<DataNode> node, const DataNode &first_child);
|
static cpputils::unique_ref<DataInnerNode> convertToNewInnerNode(cpputils::unique_ref<DataNode> node, const DataNode &first_child);
|
||||||
|
|
||||||
void flush() const;
|
void flush() const;
|
||||||
|
|
||||||
|
@ -10,76 +10,81 @@ using blockstore::BlockStore;
|
|||||||
using blockstore::Block;
|
using blockstore::Block;
|
||||||
using blockstore::Key;
|
using blockstore::Key;
|
||||||
using cpputils::Data;
|
using cpputils::Data;
|
||||||
|
using cpputils::unique_ref;
|
||||||
|
using cpputils::make_unique_ref;
|
||||||
using std::unique_ptr;
|
using std::unique_ptr;
|
||||||
using std::make_unique;
|
|
||||||
using std::runtime_error;
|
using std::runtime_error;
|
||||||
|
using boost::optional;
|
||||||
|
using boost::none;
|
||||||
|
|
||||||
namespace blobstore {
|
namespace blobstore {
|
||||||
namespace onblocks {
|
namespace onblocks {
|
||||||
namespace datanodestore {
|
namespace datanodestore {
|
||||||
|
|
||||||
DataNodeStore::DataNodeStore(unique_ptr<BlockStore> blockstore, uint32_t blocksizeBytes)
|
DataNodeStore::DataNodeStore(unique_ref<BlockStore> blockstore, uint32_t blocksizeBytes)
|
||||||
: _blockstore(std::move(blockstore)), _layout(blocksizeBytes) {
|
: _blockstore(std::move(blockstore)), _layout(blocksizeBytes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DataNodeStore::~DataNodeStore() {
|
DataNodeStore::~DataNodeStore() {
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataNode> DataNodeStore::load(unique_ptr<Block> block) {
|
unique_ref<DataNode> DataNodeStore::load(unique_ptr<Block> block) {
|
||||||
assert(block->size() == _layout.blocksizeBytes());
|
assert(block->size() == _layout.blocksizeBytes());
|
||||||
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)));
|
return make_unique_ref<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)));
|
return make_unique_ref<DataInnerNode>(std::move(node));
|
||||||
} else {
|
} else {
|
||||||
throw runtime_error("Tree is to deep. Data corruption?");
|
throw runtime_error("Tree is to deep. Data corruption?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataNodeStore::createNewInnerNode(const DataNode &first_child) {
|
unique_ref<DataInnerNode> DataNodeStore::createNewInnerNode(const DataNode &first_child) {
|
||||||
assert(first_child.node().layout().blocksizeBytes() == _layout.blocksizeBytes()); // This might be violated if source is from a different DataNodeStore
|
assert(first_child.node().layout().blocksizeBytes() == _layout.blocksizeBytes()); // This might be violated if source is from a different DataNodeStore
|
||||||
//TODO Initialize block and then create it in the blockstore - this is more efficient than creating it and then writing to it
|
//TODO Initialize block and then create it in the blockstore - this is more efficient than creating it and then writing to it
|
||||||
auto block = _blockstore->create(Data(_layout.blocksizeBytes()).FillWithZeroes());
|
auto block = _blockstore->create(Data(_layout.blocksizeBytes()).FillWithZeroes());
|
||||||
return DataInnerNode::InitializeNewNode(std::move(block), first_child);
|
return DataInnerNode::InitializeNewNode(std::move(block), first_child);
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataLeafNode> DataNodeStore::createNewLeafNode() {
|
unique_ref<DataLeafNode> DataNodeStore::createNewLeafNode() {
|
||||||
//TODO Initialize block and then create it in the blockstore - this is more efficient than creating it and then writing to it
|
//TODO Initialize block and then create it in the blockstore - this is more efficient than creating it and then writing to it
|
||||||
auto block = _blockstore->create(Data(_layout.blocksizeBytes()).FillWithZeroes());
|
auto block = _blockstore->create(Data(_layout.blocksizeBytes()).FillWithZeroes());
|
||||||
return DataLeafNode::InitializeNewNode(std::move(block));
|
return DataLeafNode::InitializeNewNode(std::move(block));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataNode> DataNodeStore::load(const Key &key) {
|
optional<unique_ref<DataNode>> DataNodeStore::load(const Key &key) {
|
||||||
auto block = _blockstore->load(key);
|
auto block = _blockstore->load(key);
|
||||||
if (block == nullptr) {
|
if (block == nullptr) {
|
||||||
return nullptr;
|
return none;
|
||||||
}
|
}
|
||||||
return load(std::move(block));
|
return load(std::move(block));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataNode> DataNodeStore::createNewNodeAsCopyFrom(const DataNode &source) {
|
unique_ref<DataNode> DataNodeStore::createNewNodeAsCopyFrom(const DataNode &source) {
|
||||||
assert(source.node().layout().blocksizeBytes() == _layout.blocksizeBytes()); // This might be violated if source is from a different DataNodeStore
|
assert(source.node().layout().blocksizeBytes() == _layout.blocksizeBytes()); // This might be violated if source is from a different DataNodeStore
|
||||||
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));
|
return load(std::move(newBlock));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataNode> DataNodeStore::overwriteNodeWith(unique_ptr<DataNode> target, const DataNode &source) {
|
unique_ref<DataNode> DataNodeStore::overwriteNodeWith(unique_ref<DataNode> target, const DataNode &source) {
|
||||||
assert(target->node().layout().blocksizeBytes() == _layout.blocksizeBytes());
|
assert(target->node().layout().blocksizeBytes() == _layout.blocksizeBytes());
|
||||||
assert(source.node().layout().blocksizeBytes() == _layout.blocksizeBytes());
|
assert(source.node().layout().blocksizeBytes() == _layout.blocksizeBytes());
|
||||||
Key key = target->key();
|
Key key = target->key();
|
||||||
{
|
{
|
||||||
auto targetBlock = target->node().releaseBlock();
|
auto targetBlock = target->node().releaseBlock();
|
||||||
target.reset();
|
cpputils::to_unique_ptr(std::move(target)).reset(); // Call destructor
|
||||||
blockstore::utils::copyTo(targetBlock.get(), source.node().block());
|
blockstore::utils::copyTo(targetBlock.get(), source.node().block());
|
||||||
}
|
}
|
||||||
return load(key);
|
auto loaded = load(key);
|
||||||
|
assert(loaded != none);
|
||||||
|
return std::move(*loaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataNodeStore::remove(unique_ptr<DataNode> node) {
|
void DataNodeStore::remove(unique_ref<DataNode> node) {
|
||||||
auto block = node->node().releaseBlock();
|
auto block = node->node().releaseBlock();
|
||||||
node.reset();
|
cpputils::to_unique_ptr(std::move(node)).reset(); // Call destructor
|
||||||
_blockstore->remove(std::move(block));
|
_blockstore->remove(std::move(block));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,12 +92,13 @@ uint64_t DataNodeStore::numNodes() const {
|
|||||||
return _blockstore->numBlocks();
|
return _blockstore->numBlocks();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataNodeStore::removeSubtree(unique_ptr<DataNode> node) {
|
void DataNodeStore::removeSubtree(unique_ref<DataNode> node) {
|
||||||
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(node.get());
|
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(node.get());
|
||||||
if (inner != nullptr) {
|
if (inner != nullptr) {
|
||||||
for (uint32_t i = 0; i < inner->numChildren(); ++i) {
|
for (uint32_t i = 0; i < inner->numChildren(); ++i) {
|
||||||
auto child = load(inner->getChild(i)->key());
|
auto child = load(inner->getChild(i)->key());
|
||||||
removeSubtree(std::move(child));
|
assert(child != none);
|
||||||
|
removeSubtree(std::move(*child));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
remove(std::move(node));
|
remove(std::move(node));
|
||||||
|
@ -21,33 +21,33 @@ class DataInnerNode;
|
|||||||
|
|
||||||
class DataNodeStore {
|
class DataNodeStore {
|
||||||
public:
|
public:
|
||||||
DataNodeStore(std::unique_ptr<blockstore::BlockStore> blockstore, uint32_t blocksizeBytes);
|
DataNodeStore(cpputils::unique_ref<blockstore::BlockStore> blockstore, uint32_t blocksizeBytes);
|
||||||
virtual ~DataNodeStore();
|
virtual ~DataNodeStore();
|
||||||
|
|
||||||
static constexpr uint8_t MAX_DEPTH = 10;
|
static constexpr uint8_t MAX_DEPTH = 10;
|
||||||
|
|
||||||
DataNodeLayout layout() const;
|
DataNodeLayout layout() const;
|
||||||
|
|
||||||
std::unique_ptr<DataNode> load(const blockstore::Key &key);
|
boost::optional<cpputils::unique_ref<DataNode>> load(const blockstore::Key &key);
|
||||||
|
|
||||||
std::unique_ptr<DataLeafNode> createNewLeafNode();
|
cpputils::unique_ref<DataLeafNode> createNewLeafNode();
|
||||||
std::unique_ptr<DataInnerNode> createNewInnerNode(const DataNode &first_child);
|
cpputils::unique_ref<DataInnerNode> createNewInnerNode(const DataNode &first_child);
|
||||||
|
|
||||||
std::unique_ptr<DataNode> createNewNodeAsCopyFrom(const DataNode &source);
|
cpputils::unique_ref<DataNode> createNewNodeAsCopyFrom(const DataNode &source);
|
||||||
|
|
||||||
std::unique_ptr<DataNode> overwriteNodeWith(std::unique_ptr<DataNode> target, const DataNode &source);
|
cpputils::unique_ref<DataNode> overwriteNodeWith(cpputils::unique_ref<DataNode> target, const DataNode &source);
|
||||||
|
|
||||||
void remove(std::unique_ptr<DataNode> node);
|
void remove(cpputils::unique_ref<DataNode> node);
|
||||||
|
|
||||||
void removeSubtree(std::unique_ptr<DataNode> node);
|
void removeSubtree(cpputils::unique_ref<DataNode> node);
|
||||||
|
|
||||||
uint64_t numNodes() const;
|
uint64_t numNodes() const;
|
||||||
//TODO Test overwriteNodeWith(), createNodeAsCopyFrom(), removeSubtree()
|
//TODO Test overwriteNodeWith(), createNodeAsCopyFrom(), removeSubtree()
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<DataNode> load(std::unique_ptr<blockstore::Block> block);
|
cpputils::unique_ref<DataNode> load(std::unique_ptr<blockstore::Block> block);
|
||||||
|
|
||||||
std::unique_ptr<blockstore::BlockStore> _blockstore;
|
cpputils::unique_ref<blockstore::BlockStore> _blockstore;
|
||||||
const DataNodeLayout _layout;
|
const DataNodeLayout _layout;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(DataNodeStore);
|
DISALLOW_COPY_AND_ASSIGN(DataNodeStore);
|
||||||
|
@ -18,24 +18,25 @@ using blobstore::onblocks::datanodestore::DataInnerNode;
|
|||||||
using blobstore::onblocks::datanodestore::DataLeafNode;
|
using blobstore::onblocks::datanodestore::DataLeafNode;
|
||||||
using blobstore::onblocks::datanodestore::DataNodeLayout;
|
using blobstore::onblocks::datanodestore::DataNodeLayout;
|
||||||
|
|
||||||
using std::unique_ptr;
|
|
||||||
using std::dynamic_pointer_cast;
|
using std::dynamic_pointer_cast;
|
||||||
using std::function;
|
using std::function;
|
||||||
using boost::shared_mutex;
|
using boost::shared_mutex;
|
||||||
using boost::shared_lock;
|
using boost::shared_lock;
|
||||||
using boost::unique_lock;
|
using boost::unique_lock;
|
||||||
|
using boost::none;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
||||||
using cpputils::dynamic_pointer_move;
|
using cpputils::dynamic_pointer_move;
|
||||||
using cpputils::optional_ownership_ptr;
|
using cpputils::optional_ownership_ptr;
|
||||||
using cpputils::WithOwnership;
|
using cpputils::WithOwnership;
|
||||||
using cpputils::WithoutOwnership;
|
using cpputils::WithoutOwnership;
|
||||||
|
using cpputils::unique_ref;
|
||||||
|
|
||||||
namespace blobstore {
|
namespace blobstore {
|
||||||
namespace onblocks {
|
namespace onblocks {
|
||||||
namespace datatreestore {
|
namespace datatreestore {
|
||||||
|
|
||||||
DataTree::DataTree(DataNodeStore *nodeStore, unique_ptr<DataNode> rootNode)
|
DataTree::DataTree(DataNodeStore *nodeStore, unique_ref<DataNode> rootNode)
|
||||||
: _mutex(), _nodeStore(nodeStore), _rootNode(std::move(rootNode)) {
|
: _mutex(), _nodeStore(nodeStore), _rootNode(std::move(rootNode)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,18 +57,20 @@ void DataTree::ifRootHasOnlyOneChildReplaceRootWithItsChild() {
|
|||||||
assert(rootNode != nullptr);
|
assert(rootNode != nullptr);
|
||||||
if (rootNode->numChildren() == 1) {
|
if (rootNode->numChildren() == 1) {
|
||||||
auto child = _nodeStore->load(rootNode->getChild(0)->key());
|
auto child = _nodeStore->load(rootNode->getChild(0)->key());
|
||||||
_rootNode = _nodeStore->overwriteNodeWith(std::move(_rootNode), *child);
|
assert(child != none);
|
||||||
_nodeStore->remove(std::move(child));
|
_rootNode = _nodeStore->overwriteNodeWith(std::move(_rootNode), **child);
|
||||||
|
_nodeStore->remove(std::move(*child));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataTree::deleteLastChildSubtree(DataInnerNode *node) {
|
void DataTree::deleteLastChildSubtree(DataInnerNode *node) {
|
||||||
auto lastChild = _nodeStore->load(node->LastChild()->key());
|
auto lastChild = _nodeStore->load(node->LastChild()->key());
|
||||||
_nodeStore->removeSubtree(std::move(lastChild));
|
assert(lastChild != none);
|
||||||
|
_nodeStore->removeSubtree(std::move(*lastChild));
|
||||||
node->removeLastChild();
|
node->removeLastChild();
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataLeafNode> DataTree::addDataLeaf() {
|
unique_ref<DataLeafNode> DataTree::addDataLeaf() {
|
||||||
auto insertPosOrNull = algorithms::GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(_nodeStore, _rootNode.get());
|
auto insertPosOrNull = algorithms::GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(_nodeStore, _rootNode.get());
|
||||||
if (insertPosOrNull) {
|
if (insertPosOrNull) {
|
||||||
return addDataLeafAt(insertPosOrNull.get());
|
return addDataLeafAt(insertPosOrNull.get());
|
||||||
@ -76,7 +79,7 @@ unique_ptr<DataLeafNode> DataTree::addDataLeaf() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataLeafNode> DataTree::addDataLeafAt(DataInnerNode *insertPos) {
|
unique_ref<DataLeafNode> DataTree::addDataLeafAt(DataInnerNode *insertPos) {
|
||||||
auto new_leaf = _nodeStore->createNewLeafNode();
|
auto new_leaf = _nodeStore->createNewLeafNode();
|
||||||
auto chain = createChainOfInnerNodes(insertPos->depth()-1, new_leaf.get());
|
auto chain = createChainOfInnerNodes(insertPos->depth()-1, new_leaf.get());
|
||||||
insertPos->addChild(*chain);
|
insertPos->addChild(*chain);
|
||||||
@ -84,17 +87,18 @@ unique_ptr<DataLeafNode> DataTree::addDataLeafAt(DataInnerNode *insertPos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
optional_ownership_ptr<DataNode> DataTree::createChainOfInnerNodes(unsigned int num, DataNode *child) {
|
optional_ownership_ptr<DataNode> DataTree::createChainOfInnerNodes(unsigned int num, DataNode *child) {
|
||||||
//TODO This function is implemented twice, once with optional_ownership_ptr, once with unique_ptr. Redundancy!
|
//TODO This function is implemented twice, once with optional_ownership_ptr, once with unique_ref. Redundancy!
|
||||||
optional_ownership_ptr<DataNode> chain = cpputils::WithoutOwnership<DataNode>(child);
|
optional_ownership_ptr<DataNode> chain = cpputils::WithoutOwnership<DataNode>(child);
|
||||||
for(unsigned int i=0; i<num; ++i) {
|
for(unsigned int i=0; i<num; ++i) {
|
||||||
auto newnode = _nodeStore->createNewInnerNode(*chain);
|
auto newnode = _nodeStore->createNewInnerNode(*chain);
|
||||||
chain = cpputils::WithOwnership<DataNode>(std::move(newnode));
|
//TODO Don't use to_unique_ptr, but make optional_ownership_ptr work with unique_ref
|
||||||
|
chain = cpputils::WithOwnership<DataNode>(cpputils::to_unique_ptr(std::move(newnode)));
|
||||||
}
|
}
|
||||||
return chain;
|
return chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataNode> DataTree::createChainOfInnerNodes(unsigned int num, unique_ptr<DataNode> child) {
|
unique_ref<DataNode> DataTree::createChainOfInnerNodes(unsigned int num, unique_ref<DataNode> child) {
|
||||||
unique_ptr<DataNode> chain = std::move(child);
|
unique_ref<DataNode> chain = std::move(child);
|
||||||
for(unsigned int i=0; i<num; ++i) {
|
for(unsigned int i=0; i<num; ++i) {
|
||||||
chain = _nodeStore->createNewInnerNode(*chain);
|
chain = _nodeStore->createNewInnerNode(*chain);
|
||||||
}
|
}
|
||||||
@ -111,7 +115,7 @@ DataInnerNode* DataTree::increaseTreeDepth(unsigned int levels) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataLeafNode> DataTree::addDataLeafToFullTree() {
|
unique_ref<DataLeafNode> DataTree::addDataLeafToFullTree() {
|
||||||
DataInnerNode *rootNode = increaseTreeDepth(1);
|
DataInnerNode *rootNode = increaseTreeDepth(1);
|
||||||
auto newLeaf = addDataLeafAt(rootNode);
|
auto newLeaf = addDataLeafAt(rootNode);
|
||||||
return newLeaf;
|
return newLeaf;
|
||||||
@ -125,7 +129,7 @@ void DataTree::flush() const {
|
|||||||
_rootNode->flush();
|
_rootNode->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataNode> DataTree::releaseRootNode() {
|
unique_ref<DataNode> DataTree::releaseRootNode() {
|
||||||
return std::move(_rootNode);
|
return std::move(_rootNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +147,8 @@ uint32_t DataTree::_numLeaves(const DataNode &node) const {
|
|||||||
const DataInnerNode &inner = dynamic_cast<const DataInnerNode&>(node);
|
const DataInnerNode &inner = dynamic_cast<const DataInnerNode&>(node);
|
||||||
uint64_t numLeavesInLeftChildren = (inner.numChildren()-1) * leavesPerFullChild(inner);
|
uint64_t numLeavesInLeftChildren = (inner.numChildren()-1) * leavesPerFullChild(inner);
|
||||||
auto lastChild = _nodeStore->load(inner.LastChild()->key());
|
auto lastChild = _nodeStore->load(inner.LastChild()->key());
|
||||||
uint64_t numLeavesInRightChild = _numLeaves(*lastChild);
|
assert(lastChild != none);
|
||||||
|
uint64_t numLeavesInRightChild = _numLeaves(**lastChild);
|
||||||
|
|
||||||
return numLeavesInLeftChildren + numLeavesInRightChild;
|
return numLeavesInLeftChildren + numLeavesInRightChild;
|
||||||
}
|
}
|
||||||
@ -199,7 +204,7 @@ void DataTree::_traverseLeaves(DataNode *root, uint32_t leafOffset, uint32_t beg
|
|||||||
uint32_t leavesPerChild = leavesPerFullChild(*inner);
|
uint32_t leavesPerChild = leavesPerFullChild(*inner);
|
||||||
uint32_t beginChild = beginIndex/leavesPerChild;
|
uint32_t beginChild = beginIndex/leavesPerChild;
|
||||||
uint32_t endChild = utils::ceilDivision(endIndex, leavesPerChild);
|
uint32_t endChild = utils::ceilDivision(endIndex, leavesPerChild);
|
||||||
vector<unique_ptr<DataNode>> children = getOrCreateChildren(inner, beginChild, endChild);
|
vector<unique_ref<DataNode>> children = getOrCreateChildren(inner, beginChild, endChild);
|
||||||
|
|
||||||
for (uint32_t childIndex = beginChild; childIndex < endChild; ++childIndex) {
|
for (uint32_t childIndex = beginChild; childIndex < endChild; ++childIndex) {
|
||||||
uint32_t childOffset = childIndex * leavesPerChild;
|
uint32_t childOffset = childIndex * leavesPerChild;
|
||||||
@ -210,11 +215,13 @@ void DataTree::_traverseLeaves(DataNode *root, uint32_t leafOffset, uint32_t beg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<unique_ptr<DataNode>> DataTree::getOrCreateChildren(DataInnerNode *node, uint32_t begin, uint32_t end) {
|
vector<unique_ref<DataNode>> DataTree::getOrCreateChildren(DataInnerNode *node, uint32_t begin, uint32_t end) {
|
||||||
vector<unique_ptr<DataNode>> children;
|
vector<unique_ref<DataNode>> children;
|
||||||
children.reserve(end-begin);
|
children.reserve(end-begin);
|
||||||
for (uint32_t childIndex = begin; childIndex < std::min(node->numChildren(), end); ++childIndex) {
|
for (uint32_t childIndex = begin; childIndex < std::min(node->numChildren(), end); ++childIndex) {
|
||||||
children.emplace_back(_nodeStore->load(node->getChild(childIndex)->key()));
|
auto child = _nodeStore->load(node->getChild(childIndex)->key());
|
||||||
|
assert(child != none);
|
||||||
|
children.emplace_back(std::move(*child));
|
||||||
}
|
}
|
||||||
for (uint32_t childIndex = node->numChildren(); childIndex < end; ++childIndex) {
|
for (uint32_t childIndex = node->numChildren(); childIndex < end; ++childIndex) {
|
||||||
children.emplace_back(addChildTo(node));
|
children.emplace_back(addChildTo(node));
|
||||||
@ -223,7 +230,7 @@ vector<unique_ptr<DataNode>> DataTree::getOrCreateChildren(DataInnerNode *node,
|
|||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataNode> DataTree::addChildTo(DataInnerNode *node) {
|
unique_ref<DataNode> DataTree::addChildTo(DataInnerNode *node) {
|
||||||
auto new_leaf = _nodeStore->createNewLeafNode();
|
auto new_leaf = _nodeStore->createNewLeafNode();
|
||||||
new_leaf->resize(_nodeStore->layout().maxBytesPerLeaf());
|
new_leaf->resize(_nodeStore->layout().maxBytesPerLeaf());
|
||||||
auto chain = createChainOfInnerNodes(node->depth()-1, std::move(new_leaf));
|
auto chain = createChainOfInnerNodes(node->depth()-1, std::move(new_leaf));
|
||||||
@ -253,7 +260,8 @@ uint64_t DataTree::_numStoredBytes(const DataNode &root) const {
|
|||||||
const DataInnerNode &inner = dynamic_cast<const DataInnerNode&>(root);
|
const DataInnerNode &inner = dynamic_cast<const DataInnerNode&>(root);
|
||||||
uint64_t numBytesInLeftChildren = (inner.numChildren()-1) * leavesPerFullChild(inner) * _nodeStore->layout().maxBytesPerLeaf();
|
uint64_t numBytesInLeftChildren = (inner.numChildren()-1) * leavesPerFullChild(inner) * _nodeStore->layout().maxBytesPerLeaf();
|
||||||
auto lastChild = _nodeStore->load(inner.LastChild()->key());
|
auto lastChild = _nodeStore->load(inner.LastChild()->key());
|
||||||
uint64_t numBytesInRightChild = _numStoredBytes(*lastChild);
|
assert(lastChild != none);
|
||||||
|
uint64_t numBytesInRightChild = _numStoredBytes(**lastChild);
|
||||||
|
|
||||||
return numBytesInLeftChildren + numBytesInRightChild;
|
return numBytesInLeftChildren + numBytesInRightChild;
|
||||||
}
|
}
|
||||||
@ -288,16 +296,22 @@ optional_ownership_ptr<DataLeafNode> DataTree::LastLeaf(DataNode *root) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root);
|
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root);
|
||||||
return WithOwnership(LastLeaf(_nodeStore->load(inner->LastChild()->key())));
|
auto lastChild = _nodeStore->load(inner->LastChild()->key());
|
||||||
|
assert(lastChild != none);
|
||||||
|
//TODO Don't use to_unique_ptr but make optional_ownership_ptr work with unique_ref
|
||||||
|
return WithOwnership(cpputils::to_unique_ptr(LastLeaf(std::move(*lastChild))));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataLeafNode> DataTree::LastLeaf(unique_ptr<DataNode> root) {
|
unique_ref<DataLeafNode> DataTree::LastLeaf(unique_ref<DataNode> root) {
|
||||||
auto leaf = dynamic_pointer_move<DataLeafNode>(root);
|
auto leaf = dynamic_pointer_move<DataLeafNode>(root);
|
||||||
if (leaf.get() != nullptr) {
|
if (leaf != none) {
|
||||||
return leaf;
|
return std::move(*leaf);
|
||||||
}
|
}
|
||||||
auto inner = dynamic_pointer_move<DataInnerNode>(root);
|
auto inner = dynamic_pointer_move<DataInnerNode>(root);
|
||||||
return LastLeaf(_nodeStore->load(inner->LastChild()->key()));
|
assert(inner != none);
|
||||||
|
auto child = _nodeStore->load((*inner)->LastChild()->key());
|
||||||
|
assert(child != none);
|
||||||
|
return LastLeaf(std::move(*child));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t DataTree::maxBytesPerLeaf() const {
|
uint32_t DataTree::maxBytesPerLeaf() const {
|
||||||
|
@ -23,7 +23,7 @@ namespace datatreestore {
|
|||||||
//TODO It is strange that DataLeafNode is still part in the public interface of DataTree. This should be separated somehow.
|
//TODO It is strange that DataLeafNode is still part in the public interface of DataTree. This should be separated somehow.
|
||||||
class DataTree {
|
class DataTree {
|
||||||
public:
|
public:
|
||||||
DataTree(datanodestore::DataNodeStore *nodeStore, std::unique_ptr<datanodestore::DataNode> rootNode);
|
DataTree(datanodestore::DataNodeStore *nodeStore, cpputils::unique_ref<datanodestore::DataNode> rootNode);
|
||||||
virtual ~DataTree();
|
virtual ~DataTree();
|
||||||
|
|
||||||
const blockstore::Key &key() const;
|
const blockstore::Key &key() const;
|
||||||
@ -40,18 +40,18 @@ public:
|
|||||||
private:
|
private:
|
||||||
mutable boost::shared_mutex _mutex;
|
mutable boost::shared_mutex _mutex;
|
||||||
datanodestore::DataNodeStore *_nodeStore;
|
datanodestore::DataNodeStore *_nodeStore;
|
||||||
std::unique_ptr<datanodestore::DataNode> _rootNode;
|
cpputils::unique_ref<datanodestore::DataNode> _rootNode;
|
||||||
|
|
||||||
std::unique_ptr<datanodestore::DataLeafNode> addDataLeaf();
|
cpputils::unique_ref<datanodestore::DataLeafNode> addDataLeaf();
|
||||||
void removeLastDataLeaf();
|
void removeLastDataLeaf();
|
||||||
|
|
||||||
std::unique_ptr<datanodestore::DataNode> releaseRootNode();
|
cpputils::unique_ref<datanodestore::DataNode> releaseRootNode();
|
||||||
friend class DataTreeStore;
|
friend class DataTreeStore;
|
||||||
|
|
||||||
std::unique_ptr<datanodestore::DataLeafNode> addDataLeafAt(datanodestore::DataInnerNode *insertPos);
|
cpputils::unique_ref<datanodestore::DataLeafNode> addDataLeafAt(datanodestore::DataInnerNode *insertPos);
|
||||||
cpputils::optional_ownership_ptr<datanodestore::DataNode> createChainOfInnerNodes(unsigned int num, datanodestore::DataNode *child);
|
cpputils::optional_ownership_ptr<datanodestore::DataNode> createChainOfInnerNodes(unsigned int num, datanodestore::DataNode *child);
|
||||||
std::unique_ptr<datanodestore::DataNode> createChainOfInnerNodes(unsigned int num, std::unique_ptr<datanodestore::DataNode> child);
|
cpputils::unique_ref<datanodestore::DataNode> createChainOfInnerNodes(unsigned int num, cpputils::unique_ref<datanodestore::DataNode> child);
|
||||||
std::unique_ptr<datanodestore::DataLeafNode> addDataLeafToFullTree();
|
cpputils::unique_ref<datanodestore::DataLeafNode> addDataLeafToFullTree();
|
||||||
|
|
||||||
void deleteLastChildSubtree(datanodestore::DataInnerNode *node);
|
void deleteLastChildSubtree(datanodestore::DataInnerNode *node);
|
||||||
void ifRootHasOnlyOneChildReplaceRootWithItsChild();
|
void ifRootHasOnlyOneChildReplaceRootWithItsChild();
|
||||||
@ -63,10 +63,10 @@ private:
|
|||||||
uint64_t _numStoredBytes(const datanodestore::DataNode &root) const;
|
uint64_t _numStoredBytes(const datanodestore::DataNode &root) const;
|
||||||
uint32_t _numLeaves(const datanodestore::DataNode &node) const;
|
uint32_t _numLeaves(const datanodestore::DataNode &node) const;
|
||||||
cpputils::optional_ownership_ptr<datanodestore::DataLeafNode> LastLeaf(datanodestore::DataNode *root);
|
cpputils::optional_ownership_ptr<datanodestore::DataLeafNode> LastLeaf(datanodestore::DataNode *root);
|
||||||
std::unique_ptr<datanodestore::DataLeafNode> LastLeaf(std::unique_ptr<datanodestore::DataNode> root);
|
cpputils::unique_ref<datanodestore::DataLeafNode> LastLeaf(cpputils::unique_ref<datanodestore::DataNode> root);
|
||||||
datanodestore::DataInnerNode* increaseTreeDepth(unsigned int levels);
|
datanodestore::DataInnerNode* increaseTreeDepth(unsigned int levels);
|
||||||
std::vector<std::unique_ptr<datanodestore::DataNode>> getOrCreateChildren(datanodestore::DataInnerNode *node, uint32_t begin, uint32_t end);
|
std::vector<cpputils::unique_ref<datanodestore::DataNode>> getOrCreateChildren(datanodestore::DataInnerNode *node, uint32_t begin, uint32_t end);
|
||||||
std::unique_ptr<datanodestore::DataNode> addChildTo(datanodestore::DataInnerNode *node);
|
cpputils::unique_ref<datanodestore::DataNode> addChildTo(datanodestore::DataInnerNode *node);
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(DataTree);
|
DISALLOW_COPY_AND_ASSIGN(DataTree);
|
||||||
};
|
};
|
||||||
|
@ -4,7 +4,10 @@
|
|||||||
#include "DataTree.h"
|
#include "DataTree.h"
|
||||||
|
|
||||||
using std::unique_ptr;
|
using std::unique_ptr;
|
||||||
using std::make_unique;
|
using cpputils::unique_ref;
|
||||||
|
using cpputils::make_unique_ref;
|
||||||
|
using boost::optional;
|
||||||
|
using boost::none;
|
||||||
|
|
||||||
using blobstore::onblocks::datanodestore::DataNodeStore;
|
using blobstore::onblocks::datanodestore::DataNodeStore;
|
||||||
using blobstore::onblocks::datanodestore::DataNode;
|
using blobstore::onblocks::datanodestore::DataNode;
|
||||||
@ -13,30 +16,29 @@ namespace blobstore {
|
|||||||
namespace onblocks {
|
namespace onblocks {
|
||||||
namespace datatreestore {
|
namespace datatreestore {
|
||||||
|
|
||||||
DataTreeStore::DataTreeStore(unique_ptr<DataNodeStore> nodeStore)
|
DataTreeStore::DataTreeStore(unique_ref<DataNodeStore> nodeStore)
|
||||||
: _nodeStore(std::move(nodeStore)) {
|
: _nodeStore(std::move(nodeStore)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DataTreeStore::~DataTreeStore() {
|
DataTreeStore::~DataTreeStore() {
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTree> DataTreeStore::load(const blockstore::Key &key) {
|
optional<unique_ref<DataTree>> DataTreeStore::load(const blockstore::Key &key) {
|
||||||
auto node = _nodeStore->load(key);
|
auto node = _nodeStore->load(key);
|
||||||
if (node.get() == nullptr) {
|
if (node == none) {
|
||||||
return nullptr;
|
return none;
|
||||||
} else {
|
|
||||||
return make_unique<DataTree>(_nodeStore.get(), std::move(node));
|
|
||||||
}
|
}
|
||||||
|
return make_unique_ref<DataTree>(_nodeStore.get(), std::move(*node));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTree> DataTreeStore::createNewTree() {
|
unique_ref<DataTree> DataTreeStore::createNewTree() {
|
||||||
unique_ptr<DataNode> newleaf = _nodeStore->createNewLeafNode();
|
auto newleaf = _nodeStore->createNewLeafNode();
|
||||||
return make_unique<DataTree>(_nodeStore.get(), std::move(newleaf));
|
return make_unique_ref<DataTree>(_nodeStore.get(), std::move(newleaf));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataTreeStore::remove(unique_ptr<DataTree> tree) {
|
void DataTreeStore::remove(unique_ref<DataTree> tree) {
|
||||||
auto root = tree->releaseRootNode();
|
auto root = tree->releaseRootNode();
|
||||||
tree.reset();
|
to_unique_ptr(std::move(tree)).reset(); // Destruct tree
|
||||||
_nodeStore->removeSubtree(std::move(root));
|
_nodeStore->removeSubtree(std::move(root));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <messmer/cpp-utils/macros.h>
|
#include <messmer/cpp-utils/macros.h>
|
||||||
|
#include <messmer/cpp-utils/pointer/unique_ref.h>
|
||||||
#include <messmer/blockstore/utils/Key.h>
|
#include <messmer/blockstore/utils/Key.h>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
namespace blobstore {
|
namespace blobstore {
|
||||||
namespace onblocks {
|
namespace onblocks {
|
||||||
@ -16,17 +18,17 @@ class DataTree;
|
|||||||
|
|
||||||
class DataTreeStore {
|
class DataTreeStore {
|
||||||
public:
|
public:
|
||||||
DataTreeStore(std::unique_ptr<datanodestore::DataNodeStore> nodeStore);
|
DataTreeStore(cpputils::unique_ref<datanodestore::DataNodeStore> nodeStore);
|
||||||
virtual ~DataTreeStore();
|
virtual ~DataTreeStore();
|
||||||
|
|
||||||
std::unique_ptr<DataTree> load(const blockstore::Key &key);
|
boost::optional<cpputils::unique_ref<DataTree>> load(const blockstore::Key &key);
|
||||||
|
|
||||||
std::unique_ptr<DataTree> createNewTree();
|
cpputils::unique_ref<DataTree> createNewTree();
|
||||||
|
|
||||||
void remove(std::unique_ptr<DataTree> tree);
|
void remove(cpputils::unique_ref<DataTree> tree);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<datanodestore::DataNodeStore> _nodeStore;
|
cpputils::unique_ref<datanodestore::DataNodeStore> _nodeStore;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(DataTreeStore);
|
DISALLOW_COPY_AND_ASSIGN(DataTreeStore);
|
||||||
};
|
};
|
||||||
|
@ -6,23 +6,26 @@
|
|||||||
#include "../../datanodestore/DataNodeStore.h"
|
#include "../../datanodestore/DataNodeStore.h"
|
||||||
|
|
||||||
using std::function;
|
using std::function;
|
||||||
using std::unique_ptr;
|
|
||||||
using cpputils::optional_ownership_ptr;
|
using cpputils::optional_ownership_ptr;
|
||||||
using cpputils::dynamic_pointer_move;
|
using cpputils::dynamic_pointer_move;
|
||||||
|
using cpputils::unique_ref;
|
||||||
using blobstore::onblocks::datanodestore::DataInnerNode;
|
using blobstore::onblocks::datanodestore::DataInnerNode;
|
||||||
using blobstore::onblocks::datanodestore::DataNode;
|
using blobstore::onblocks::datanodestore::DataNode;
|
||||||
using blobstore::onblocks::datanodestore::DataNodeStore;
|
using blobstore::onblocks::datanodestore::DataNodeStore;
|
||||||
using blockstore::Key;
|
using blockstore::Key;
|
||||||
|
using boost::optional;
|
||||||
|
using boost::none;
|
||||||
|
|
||||||
namespace blobstore {
|
namespace blobstore {
|
||||||
namespace onblocks {
|
namespace onblocks {
|
||||||
namespace datatreestore {
|
namespace datatreestore {
|
||||||
namespace algorithms {
|
namespace algorithms {
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> getLastChildAsInnerNode(DataNodeStore *nodeStore, const DataInnerNode &node) {
|
optional<unique_ref<DataInnerNode>> getLastChildAsInnerNode(DataNodeStore *nodeStore, const DataInnerNode &node) {
|
||||||
Key key = node.LastChild()->key();
|
Key key = node.LastChild()->key();
|
||||||
auto lastChild = nodeStore->load(key);
|
auto lastChild = nodeStore->load(key);
|
||||||
return dynamic_pointer_move<DataInnerNode>(lastChild);
|
assert(lastChild != none);
|
||||||
|
return dynamic_pointer_move<DataInnerNode>(*lastChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Returns the lowest right border node meeting the condition specified (exclusive the leaf).
|
//Returns the lowest right border node meeting the condition specified (exclusive the leaf).
|
||||||
@ -31,11 +34,16 @@ optional_ownership_ptr<DataInnerNode> GetLowestInnerRightBorderNodeWithCondition
|
|||||||
optional_ownership_ptr<DataInnerNode> currentNode = cpputils::WithoutOwnership(dynamic_cast<DataInnerNode*>(rootNode));
|
optional_ownership_ptr<DataInnerNode> currentNode = cpputils::WithoutOwnership(dynamic_cast<DataInnerNode*>(rootNode));
|
||||||
optional_ownership_ptr<DataInnerNode> result = cpputils::null<DataInnerNode>();
|
optional_ownership_ptr<DataInnerNode> result = cpputils::null<DataInnerNode>();
|
||||||
for (unsigned int i=0; i < rootNode->depth(); ++i) {
|
for (unsigned int i=0; i < rootNode->depth(); ++i) {
|
||||||
|
//TODO Don't use to_unique_ptr, but make optional_ownership_ptr work with unique_ref
|
||||||
|
//TODO This unnecessarily loads the leaf node in the last loop run
|
||||||
auto lastChild = getLastChildAsInnerNode(nodeStore, *currentNode);
|
auto lastChild = getLastChildAsInnerNode(nodeStore, *currentNode);
|
||||||
if (condition(*currentNode)) {
|
if (condition(*currentNode)) {
|
||||||
result = std::move(currentNode);
|
result = std::move(currentNode);
|
||||||
}
|
}
|
||||||
currentNode = std::move(lastChild);
|
assert(lastChild != none || static_cast<int>(i) == rootNode->depth()-1);
|
||||||
|
if (lastChild != none) {
|
||||||
|
currentNode = cpputils::to_unique_ptr(std::move(*lastChild));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -4,8 +4,9 @@
|
|||||||
#include "../datanodestore/DataNodeStore.h"
|
#include "../datanodestore/DataNodeStore.h"
|
||||||
#include "../datanodestore/DataLeafNode.h"
|
#include "../datanodestore/DataLeafNode.h"
|
||||||
|
|
||||||
using std::unique_ptr;
|
using cpputils::unique_ref;
|
||||||
using std::make_unique;
|
using cpputils::make_unique_ref;
|
||||||
|
using boost::optional;
|
||||||
|
|
||||||
using blobstore::onblocks::datatreestore::DataTreeStore;
|
using blobstore::onblocks::datatreestore::DataTreeStore;
|
||||||
using blockstore::Key;
|
using blockstore::Key;
|
||||||
@ -16,24 +17,24 @@ using datatreestore::DataTreeStore;
|
|||||||
using datatreestore::DataTree;
|
using datatreestore::DataTree;
|
||||||
namespace parallelaccessdatatreestore {
|
namespace parallelaccessdatatreestore {
|
||||||
|
|
||||||
ParallelAccessDataTreeStore::ParallelAccessDataTreeStore(unique_ptr<DataTreeStore> dataTreeStore)
|
ParallelAccessDataTreeStore::ParallelAccessDataTreeStore(unique_ref<DataTreeStore> dataTreeStore)
|
||||||
: _dataTreeStore(std::move(dataTreeStore)), _parallelAccessStore(make_unique<ParallelAccessDataTreeStoreAdapter>(_dataTreeStore.get())) {
|
: _dataTreeStore(std::move(dataTreeStore)), _parallelAccessStore(make_unique_ref<ParallelAccessDataTreeStoreAdapter>(_dataTreeStore.get())) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ParallelAccessDataTreeStore::~ParallelAccessDataTreeStore() {
|
ParallelAccessDataTreeStore::~ParallelAccessDataTreeStore() {
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTreeRef> ParallelAccessDataTreeStore::load(const blockstore::Key &key) {
|
optional<unique_ref<DataTreeRef>> ParallelAccessDataTreeStore::load(const blockstore::Key &key) {
|
||||||
return _parallelAccessStore.load(key);
|
return _parallelAccessStore.load(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTreeRef> ParallelAccessDataTreeStore::createNewTree() {
|
unique_ref<DataTreeRef> ParallelAccessDataTreeStore::createNewTree() {
|
||||||
auto dataTree = _dataTreeStore->createNewTree();
|
auto dataTree = _dataTreeStore->createNewTree();
|
||||||
Key key = dataTree->key();
|
Key key = dataTree->key();
|
||||||
return _parallelAccessStore.add(key, std::move(dataTree));
|
return _parallelAccessStore.add(key, std::move(dataTree));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParallelAccessDataTreeStore::remove(unique_ptr<DataTreeRef> tree) {
|
void ParallelAccessDataTreeStore::remove(unique_ref<DataTreeRef> tree) {
|
||||||
Key key = tree->key();
|
Key key = tree->key();
|
||||||
return _parallelAccessStore.remove(key, std::move(tree));
|
return _parallelAccessStore.remove(key, std::move(tree));
|
||||||
}
|
}
|
||||||
|
@ -20,17 +20,17 @@ class DataTreeRef;
|
|||||||
|
|
||||||
class ParallelAccessDataTreeStore {
|
class ParallelAccessDataTreeStore {
|
||||||
public:
|
public:
|
||||||
ParallelAccessDataTreeStore(std::unique_ptr<datatreestore::DataTreeStore> dataTreeStore);
|
ParallelAccessDataTreeStore(cpputils::unique_ref<datatreestore::DataTreeStore> dataTreeStore);
|
||||||
virtual ~ParallelAccessDataTreeStore();
|
virtual ~ParallelAccessDataTreeStore();
|
||||||
|
|
||||||
std::unique_ptr<DataTreeRef> load(const blockstore::Key &key);
|
boost::optional<cpputils::unique_ref<DataTreeRef>> load(const blockstore::Key &key);
|
||||||
|
|
||||||
std::unique_ptr<DataTreeRef> createNewTree();
|
cpputils::unique_ref<DataTreeRef> createNewTree();
|
||||||
|
|
||||||
void remove(std::unique_ptr<DataTreeRef> tree);
|
void remove(cpputils::unique_ref<DataTreeRef> tree);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<datatreestore::DataTreeStore> _dataTreeStore;
|
cpputils::unique_ref<datatreestore::DataTreeStore> _dataTreeStore;
|
||||||
parallelaccessstore::ParallelAccessStore<datatreestore::DataTree, DataTreeRef, blockstore::Key> _parallelAccessStore;
|
parallelaccessstore::ParallelAccessStore<datatreestore::DataTree, DataTreeRef, blockstore::Key> _parallelAccessStore;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(ParallelAccessDataTreeStore);
|
DISALLOW_COPY_AND_ASSIGN(ParallelAccessDataTreeStore);
|
||||||
|
@ -16,11 +16,11 @@ public:
|
|||||||
:_baseDataTreeStore(std::move(baseDataTreeStore)) {
|
:_baseDataTreeStore(std::move(baseDataTreeStore)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<datatreestore::DataTree> loadFromBaseStore(const blockstore::Key &key) override {
|
boost::optional<cpputils::unique_ref<datatreestore::DataTree>> loadFromBaseStore(const blockstore::Key &key) override {
|
||||||
return _baseDataTreeStore->load(key);
|
return _baseDataTreeStore->load(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeFromBaseStore(std::unique_ptr<datatreestore::DataTree> dataTree) override {
|
void removeFromBaseStore(cpputils::unique_ref<datatreestore::DataTree> dataTree) override {
|
||||||
return _baseDataTreeStore->remove(std::move(dataTree));
|
return _baseDataTreeStore->remove(std::move(dataTree));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,17 +22,17 @@ using namespace blobstore;
|
|||||||
using namespace blobstore::onblocks;
|
using namespace blobstore::onblocks;
|
||||||
using namespace blobstore::onblocks::datanodestore;
|
using namespace blobstore::onblocks::datanodestore;
|
||||||
|
|
||||||
using std::unique_ptr;
|
using cpputils::unique_ref;
|
||||||
using std::make_unique;
|
using cpputils::make_unique_ref;
|
||||||
|
|
||||||
class DataInnerNodeTest: public Test {
|
class DataInnerNodeTest: public Test {
|
||||||
public:
|
public:
|
||||||
static constexpr uint32_t BLOCKSIZE_BYTES = 1024;
|
static constexpr uint32_t BLOCKSIZE_BYTES = 1024;
|
||||||
|
|
||||||
DataInnerNodeTest() :
|
DataInnerNodeTest() :
|
||||||
_blockStore(make_unique<FakeBlockStore>()),
|
_blockStore(make_unique_ref<FakeBlockStore>()),
|
||||||
blockStore(_blockStore.get()),
|
blockStore(_blockStore.get()),
|
||||||
nodeStore(make_unique<DataNodeStore>(std::move(_blockStore), BLOCKSIZE_BYTES)),
|
nodeStore(make_unique_ref<DataNodeStore>(std::move(_blockStore), BLOCKSIZE_BYTES)),
|
||||||
ZEROES(nodeStore->layout().maxBytesPerLeaf()),
|
ZEROES(nodeStore->layout().maxBytesPerLeaf()),
|
||||||
leaf(nodeStore->createNewLeafNode()),
|
leaf(nodeStore->createNewLeafNode()),
|
||||||
node(nodeStore->createNewInnerNode(*leaf)) {
|
node(nodeStore->createNewInnerNode(*leaf)) {
|
||||||
@ -40,26 +40,26 @@ public:
|
|||||||
ZEROES.FillWithZeroes();
|
ZEROES.FillWithZeroes();
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> LoadInnerNode(const Key &key) {
|
unique_ref<DataInnerNode> LoadInnerNode(const Key &key) {
|
||||||
auto node = nodeStore->load(key);
|
auto node = std::move(nodeStore->load(key).get());
|
||||||
return dynamic_pointer_move<DataInnerNode>(node);
|
return std::move(dynamic_pointer_move<DataInnerNode>(node).get());
|
||||||
}
|
}
|
||||||
|
|
||||||
Key CreateNewInnerNodeReturnKey(const DataNode &firstChild) {
|
Key CreateNewInnerNodeReturnKey(const DataNode &firstChild) {
|
||||||
return nodeStore->createNewInnerNode(firstChild)->key();
|
return nodeStore->createNewInnerNode(firstChild)->key();
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> CreateNewInnerNode() {
|
unique_ref<DataInnerNode> CreateNewInnerNode() {
|
||||||
auto new_leaf = nodeStore->createNewLeafNode();
|
auto new_leaf = nodeStore->createNewLeafNode();
|
||||||
return nodeStore->createNewInnerNode(*new_leaf);
|
return nodeStore->createNewInnerNode(*new_leaf);
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> CreateAndLoadNewInnerNode(const DataNode &firstChild) {
|
unique_ref<DataInnerNode> CreateAndLoadNewInnerNode(const DataNode &firstChild) {
|
||||||
auto key = CreateNewInnerNodeReturnKey(firstChild);
|
auto key = CreateNewInnerNodeReturnKey(firstChild);
|
||||||
return LoadInnerNode(key);
|
return LoadInnerNode(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> CreateNewInnerNode(const DataNode &firstChild, const DataNode &secondChild) {
|
unique_ref<DataInnerNode> CreateNewInnerNode(const DataNode &firstChild, const DataNode &secondChild) {
|
||||||
auto node = nodeStore->createNewInnerNode(firstChild);
|
auto node = nodeStore->createNewInnerNode(firstChild);
|
||||||
node->addChild(secondChild);
|
node->addChild(secondChild);
|
||||||
return node;
|
return node;
|
||||||
@ -69,7 +69,7 @@ public:
|
|||||||
return CreateNewInnerNode(firstChild, secondChild)->key();
|
return CreateNewInnerNode(firstChild, secondChild)->key();
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> CreateAndLoadNewInnerNode(const DataNode &firstChild, const DataNode &secondChild) {
|
unique_ref<DataInnerNode> CreateAndLoadNewInnerNode(const DataNode &firstChild, const DataNode &secondChild) {
|
||||||
auto key = CreateNewInnerNodeReturnKey(firstChild, secondChild);
|
auto key = CreateNewInnerNodeReturnKey(firstChild, secondChild);
|
||||||
return LoadInnerNode(key);
|
return LoadInnerNode(key);
|
||||||
}
|
}
|
||||||
@ -85,13 +85,13 @@ public:
|
|||||||
AddALeafTo(node.get());
|
AddALeafTo(node.get());
|
||||||
AddALeafTo(node.get());
|
AddALeafTo(node.get());
|
||||||
auto child = nodeStore->createNewLeafNode();
|
auto child = nodeStore->createNewLeafNode();
|
||||||
unique_ptr<DataInnerNode> converted = DataNode::convertToNewInnerNode(std::move(node), *child);
|
unique_ref<DataInnerNode> converted = DataNode::convertToNewInnerNode(std::move(node), *child);
|
||||||
return converted->key();
|
return converted->key();
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> CopyInnerNode(const DataInnerNode &node) {
|
unique_ref<DataInnerNode> CopyInnerNode(const DataInnerNode &node) {
|
||||||
auto copied = nodeStore->createNewNodeAsCopyFrom(node);
|
auto copied = nodeStore->createNewNodeAsCopyFrom(node);
|
||||||
return dynamic_pointer_move<DataInnerNode>(copied);
|
return std::move(dynamic_pointer_move<DataInnerNode>(copied).get());
|
||||||
}
|
}
|
||||||
|
|
||||||
Key InitializeInnerNodeAddLeafReturnKey() {
|
Key InitializeInnerNodeAddLeafReturnKey() {
|
||||||
@ -100,12 +100,12 @@ public:
|
|||||||
return node->key();
|
return node->key();
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<BlockStore> _blockStore;
|
unique_ref<BlockStore> _blockStore;
|
||||||
BlockStore *blockStore;
|
BlockStore *blockStore;
|
||||||
unique_ptr<DataNodeStore> nodeStore;
|
unique_ref<DataNodeStore> nodeStore;
|
||||||
Data ZEROES;
|
Data ZEROES;
|
||||||
unique_ptr<DataLeafNode> leaf;
|
unique_ref<DataLeafNode> leaf;
|
||||||
unique_ptr<DataInnerNode> node;
|
unique_ref<DataInnerNode> node;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr uint32_t DataInnerNodeTest::BLOCKSIZE_BYTES;
|
constexpr uint32_t DataInnerNodeTest::BLOCKSIZE_BYTES;
|
||||||
@ -122,7 +122,7 @@ TEST_F(DataInnerNodeTest, CorrectKeyReturnedAfterLoading) {
|
|||||||
Key key = block->key();
|
Key key = block->key();
|
||||||
DataInnerNode::InitializeNewNode(std::move(block), *leaf);
|
DataInnerNode::InitializeNewNode(std::move(block), *leaf);
|
||||||
|
|
||||||
auto loaded = nodeStore->load(key);
|
auto loaded = std::move(nodeStore->load(key).get());
|
||||||
EXPECT_EQ(key, loaded->key());
|
EXPECT_EQ(key, loaded->key());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ TEST_F(DataInnerNodeTest, BuildingAThreeLevelTreeAndReload) {
|
|||||||
TEST_F(DataInnerNodeTest, ConvertToInternalNode) {
|
TEST_F(DataInnerNodeTest, ConvertToInternalNode) {
|
||||||
auto child = nodeStore->createNewLeafNode();
|
auto child = nodeStore->createNewLeafNode();
|
||||||
Key node_key = node->key();
|
Key node_key = node->key();
|
||||||
unique_ptr<DataInnerNode> converted = DataNode::convertToNewInnerNode(std::move(node), *child);
|
unique_ref<DataInnerNode> converted = DataNode::convertToNewInnerNode(std::move(node), *child);
|
||||||
|
|
||||||
EXPECT_EQ(1u, converted->numChildren());
|
EXPECT_EQ(1u, converted->numChildren());
|
||||||
EXPECT_EQ(child->key(), converted->getChild(0)->key());
|
EXPECT_EQ(child->key(), converted->getChild(0)->key());
|
||||||
|
@ -14,8 +14,8 @@ using ::testing::Test;
|
|||||||
using ::testing::WithParamInterface;
|
using ::testing::WithParamInterface;
|
||||||
using ::testing::Values;
|
using ::testing::Values;
|
||||||
using ::testing::Combine;
|
using ::testing::Combine;
|
||||||
using std::unique_ptr;
|
using cpputils::unique_ref;
|
||||||
using std::make_unique;
|
using cpputils::make_unique_ref;
|
||||||
using std::string;
|
using std::string;
|
||||||
using cpputils::DataFixture;
|
using cpputils::DataFixture;
|
||||||
|
|
||||||
@ -40,9 +40,9 @@ public:
|
|||||||
static constexpr DataNodeLayout LAYOUT = DataNodeLayout(BLOCKSIZE_BYTES);
|
static constexpr DataNodeLayout LAYOUT = DataNodeLayout(BLOCKSIZE_BYTES);
|
||||||
|
|
||||||
DataLeafNodeTest():
|
DataLeafNodeTest():
|
||||||
_blockStore(make_unique<FakeBlockStore>()),
|
_blockStore(make_unique_ref<FakeBlockStore>()),
|
||||||
blockStore(_blockStore.get()),
|
blockStore(_blockStore.get()),
|
||||||
nodeStore(make_unique<DataNodeStore>(std::move(_blockStore), BLOCKSIZE_BYTES)),
|
nodeStore(make_unique_ref<DataNodeStore>(std::move(_blockStore), BLOCKSIZE_BYTES)),
|
||||||
ZEROES(nodeStore->layout().maxBytesPerLeaf()),
|
ZEROES(nodeStore->layout().maxBytesPerLeaf()),
|
||||||
randomData(nodeStore->layout().maxBytesPerLeaf()),
|
randomData(nodeStore->layout().maxBytesPerLeaf()),
|
||||||
leaf(nodeStore->createNewLeafNode()) {
|
leaf(nodeStore->createNewLeafNode()) {
|
||||||
@ -76,9 +76,9 @@ public:
|
|||||||
leaf_to_fill->write(randomData.data(), 0, randomData.size());
|
leaf_to_fill->write(randomData.data(), 0, randomData.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataLeafNode> LoadLeafNode(const Key &key) {
|
unique_ref<DataLeafNode> LoadLeafNode(const Key &key) {
|
||||||
auto leaf = nodeStore->load(key);
|
auto leaf = std::move(nodeStore->load(key).get());
|
||||||
return dynamic_pointer_move<DataLeafNode>(leaf);
|
return std::move(dynamic_pointer_move<DataLeafNode>(leaf).get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResizeLeaf(const Key &key, size_t size) {
|
void ResizeLeaf(const Key &key, size_t size) {
|
||||||
@ -91,13 +91,13 @@ public:
|
|||||||
auto leaf = nodeStore->createNewLeafNode();
|
auto leaf = nodeStore->createNewLeafNode();
|
||||||
FillLeafBlockWithData(leaf.get());
|
FillLeafBlockWithData(leaf.get());
|
||||||
auto child = nodeStore->createNewLeafNode();
|
auto child = nodeStore->createNewLeafNode();
|
||||||
unique_ptr<DataInnerNode> converted = DataNode::convertToNewInnerNode(std::move(leaf), *child);
|
unique_ref<DataInnerNode> converted = DataNode::convertToNewInnerNode(std::move(leaf), *child);
|
||||||
return converted->key();
|
return converted->key();
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataLeafNode> CopyLeafNode(const DataLeafNode &node) {
|
unique_ref<DataLeafNode> CopyLeafNode(const DataLeafNode &node) {
|
||||||
auto copied = nodeStore->createNewNodeAsCopyFrom(node);
|
auto copied = nodeStore->createNewNodeAsCopyFrom(node);
|
||||||
return dynamic_pointer_move<DataLeafNode>(copied);
|
return std::move(dynamic_pointer_move<DataLeafNode>(copied).get());
|
||||||
}
|
}
|
||||||
|
|
||||||
Key InitializeLeafGrowAndReturnKey() {
|
Key InitializeLeafGrowAndReturnKey() {
|
||||||
@ -106,12 +106,12 @@ public:
|
|||||||
return leaf->key();
|
return leaf->key();
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<BlockStore> _blockStore;
|
unique_ref<BlockStore> _blockStore;
|
||||||
BlockStore *blockStore;
|
BlockStore *blockStore;
|
||||||
unique_ptr<DataNodeStore> nodeStore;
|
unique_ref<DataNodeStore> nodeStore;
|
||||||
Data ZEROES;
|
Data ZEROES;
|
||||||
Data randomData;
|
Data randomData;
|
||||||
unique_ptr<DataLeafNode> leaf;
|
unique_ref<DataLeafNode> leaf;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr uint32_t DataLeafNodeTest::BLOCKSIZE_BYTES;
|
constexpr uint32_t DataLeafNodeTest::BLOCKSIZE_BYTES;
|
||||||
@ -129,7 +129,7 @@ TEST_F(DataLeafNodeTest, CorrectKeyReturnedAfterLoading) {
|
|||||||
Key key = block->key();
|
Key key = block->key();
|
||||||
DataLeafNode::InitializeNewNode(std::move(block));
|
DataLeafNode::InitializeNewNode(std::move(block));
|
||||||
|
|
||||||
auto loaded = nodeStore->load(key);
|
auto loaded = std::move(nodeStore->load(key).get());
|
||||||
EXPECT_EQ(key, loaded->key());
|
EXPECT_EQ(key, loaded->key());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +231,7 @@ TEST_F(DataLeafNodeTest, ShrinkingDoesntDestroyValidDataRegion) {
|
|||||||
TEST_F(DataLeafNodeTest, ConvertToInternalNode) {
|
TEST_F(DataLeafNodeTest, ConvertToInternalNode) {
|
||||||
auto child = nodeStore->createNewLeafNode();
|
auto child = nodeStore->createNewLeafNode();
|
||||||
Key leaf_key = leaf->key();
|
Key leaf_key = leaf->key();
|
||||||
unique_ptr<DataInnerNode> converted = DataNode::convertToNewInnerNode(std::move(leaf), *child);
|
unique_ref<DataInnerNode> converted = DataNode::convertToNewInnerNode(std::move(leaf), *child);
|
||||||
|
|
||||||
EXPECT_EQ(1u, converted->numChildren());
|
EXPECT_EQ(1u, converted->numChildren());
|
||||||
EXPECT_EQ(child->key(), converted->getChild(0)->key());
|
EXPECT_EQ(child->key(), converted->getChild(0)->key());
|
||||||
|
@ -7,11 +7,13 @@
|
|||||||
|
|
||||||
#include "messmer/blockstore/implementations/testfake/FakeBlockStore.h"
|
#include "messmer/blockstore/implementations/testfake/FakeBlockStore.h"
|
||||||
#include "messmer/blockstore/implementations/testfake/FakeBlock.h"
|
#include "messmer/blockstore/implementations/testfake/FakeBlock.h"
|
||||||
|
#include <messmer/cpp-utils/pointer/unique_ref_boost_optional_gtest_workaround.h>
|
||||||
|
|
||||||
using ::testing::Test;
|
using ::testing::Test;
|
||||||
using std::unique_ptr;
|
using cpputils::unique_ref;
|
||||||
using std::make_unique;
|
using cpputils::make_unique_ref;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
using boost::none;
|
||||||
|
|
||||||
using blockstore::BlockStore;
|
using blockstore::BlockStore;
|
||||||
using blockstore::testfake::FakeBlockStore;
|
using blockstore::testfake::FakeBlockStore;
|
||||||
@ -25,9 +27,9 @@ class DataNodeStoreTest: public Test {
|
|||||||
public:
|
public:
|
||||||
static constexpr uint32_t BLOCKSIZE_BYTES = 1024;
|
static constexpr uint32_t BLOCKSIZE_BYTES = 1024;
|
||||||
|
|
||||||
unique_ptr<BlockStore> _blockStore = make_unique<FakeBlockStore>();
|
unique_ref<BlockStore> _blockStore = make_unique_ref<FakeBlockStore>();
|
||||||
BlockStore *blockStore = _blockStore.get();
|
BlockStore *blockStore = _blockStore.get();
|
||||||
unique_ptr<DataNodeStore> nodeStore = make_unique<DataNodeStore>(std::move(_blockStore), BLOCKSIZE_BYTES);
|
unique_ref<DataNodeStore> nodeStore = make_unique_ref<DataNodeStore>(std::move(_blockStore), BLOCKSIZE_BYTES);
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr uint32_t DataNodeStoreTest::BLOCKSIZE_BYTES;
|
constexpr uint32_t DataNodeStoreTest::BLOCKSIZE_BYTES;
|
||||||
@ -49,7 +51,7 @@ TEST_F(DataNodeStoreTest, CreateInnerNodeCreatesInnerNode) {
|
|||||||
TEST_F(DataNodeStoreTest, LeafNodeIsRecognizedAfterStoreAndLoad) {
|
TEST_F(DataNodeStoreTest, LeafNodeIsRecognizedAfterStoreAndLoad) {
|
||||||
Key key = nodeStore->createNewLeafNode()->key();
|
Key key = nodeStore->createNewLeafNode()->key();
|
||||||
|
|
||||||
auto loaded_node = nodeStore->load(key);
|
auto loaded_node = std::move(nodeStore->load(key).get());
|
||||||
|
|
||||||
EXPECT_IS_PTR_TYPE(DataLeafNode, loaded_node.get());
|
EXPECT_IS_PTR_TYPE(DataLeafNode, loaded_node.get());
|
||||||
}
|
}
|
||||||
@ -58,7 +60,7 @@ TEST_F(DataNodeStoreTest, InnerNodeWithDepth1IsRecognizedAfterStoreAndLoad) {
|
|||||||
auto leaf = nodeStore->createNewLeafNode();
|
auto leaf = nodeStore->createNewLeafNode();
|
||||||
Key key = nodeStore->createNewInnerNode(*leaf)->key();
|
Key key = nodeStore->createNewInnerNode(*leaf)->key();
|
||||||
|
|
||||||
auto loaded_node = nodeStore->load(key);
|
auto loaded_node = std::move(nodeStore->load(key).get());
|
||||||
|
|
||||||
EXPECT_IS_PTR_TYPE(DataInnerNode, loaded_node.get());
|
EXPECT_IS_PTR_TYPE(DataInnerNode, loaded_node.get());
|
||||||
}
|
}
|
||||||
@ -68,7 +70,7 @@ TEST_F(DataNodeStoreTest, InnerNodeWithDepth2IsRecognizedAfterStoreAndLoad) {
|
|||||||
auto inner = nodeStore->createNewInnerNode(*leaf);
|
auto inner = nodeStore->createNewInnerNode(*leaf);
|
||||||
Key key = nodeStore->createNewInnerNode(*inner)->key();
|
Key key = nodeStore->createNewInnerNode(*inner)->key();
|
||||||
|
|
||||||
auto loaded_node = nodeStore->load(key);
|
auto loaded_node = std::move(nodeStore->load(key).get());
|
||||||
|
|
||||||
EXPECT_IS_PTR_TYPE(DataInnerNode, loaded_node.get());
|
EXPECT_IS_PTR_TYPE(DataInnerNode, loaded_node.get());
|
||||||
}
|
}
|
||||||
@ -101,9 +103,9 @@ TEST_F(DataNodeStoreTest, CreatedLeafNodeIsInitialized) {
|
|||||||
TEST_F(DataNodeStoreTest, NodeIsNotLoadableAfterDeleting) {
|
TEST_F(DataNodeStoreTest, NodeIsNotLoadableAfterDeleting) {
|
||||||
auto nodekey = nodeStore->createNewLeafNode()->key();
|
auto nodekey = nodeStore->createNewLeafNode()->key();
|
||||||
auto node = nodeStore->load(nodekey);
|
auto node = nodeStore->load(nodekey);
|
||||||
EXPECT_NE(nullptr, node.get());
|
EXPECT_NE(none, node);
|
||||||
nodeStore->remove(std::move(node));
|
nodeStore->remove(std::move(*node));
|
||||||
EXPECT_EQ(nullptr, nodeStore->load(nodekey).get());
|
EXPECT_EQ(none, nodeStore->load(nodekey));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DataNodeStoreTest, NumNodesIsCorrectOnEmptyNodestore) {
|
TEST_F(DataNodeStoreTest, NumNodesIsCorrectOnEmptyNodestore) {
|
||||||
|
@ -9,14 +9,14 @@
|
|||||||
using ::testing::Test;
|
using ::testing::Test;
|
||||||
using ::testing::WithParamInterface;
|
using ::testing::WithParamInterface;
|
||||||
using ::testing::Values;
|
using ::testing::Values;
|
||||||
using std::unique_ptr;
|
|
||||||
using std::make_unique;
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
using blockstore::BlockStore;
|
using blockstore::BlockStore;
|
||||||
using blockstore::testfake::FakeBlockStore;
|
using blockstore::testfake::FakeBlockStore;
|
||||||
using cpputils::Data;
|
using cpputils::Data;
|
||||||
using cpputils::DataFixture;
|
using cpputils::DataFixture;
|
||||||
|
using cpputils::unique_ref;
|
||||||
|
using cpputils::make_unique_ref;
|
||||||
using namespace blobstore;
|
using namespace blobstore;
|
||||||
using namespace blobstore::onblocks;
|
using namespace blobstore::onblocks;
|
||||||
using namespace blobstore::onblocks::datanodestore;
|
using namespace blobstore::onblocks::datanodestore;
|
||||||
@ -26,7 +26,7 @@ public:
|
|||||||
static constexpr uint32_t BLOCKSIZE_BYTES = 1024;
|
static constexpr uint32_t BLOCKSIZE_BYTES = 1024;
|
||||||
static constexpr uint32_t DATASIZE_BYTES = DataNodeLayout(DataNodeViewTest::BLOCKSIZE_BYTES).datasizeBytes();
|
static constexpr uint32_t DATASIZE_BYTES = DataNodeLayout(DataNodeViewTest::BLOCKSIZE_BYTES).datasizeBytes();
|
||||||
|
|
||||||
unique_ptr<BlockStore> blockStore = make_unique<FakeBlockStore>();
|
unique_ref<BlockStore> blockStore = make_unique_ref<FakeBlockStore>();
|
||||||
};
|
};
|
||||||
|
|
||||||
class DataNodeViewDepthTest: public DataNodeViewTest, public WithParamInterface<uint8_t> {
|
class DataNodeViewDepthTest: public DataNodeViewTest, public WithParamInterface<uint8_t> {
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
#include "../../../../implementations/onblocks/datanodestore/DataNodeStore.h"
|
#include "../../../../implementations/onblocks/datanodestore/DataNodeStore.h"
|
||||||
#include "../../../../implementations/onblocks/datatreestore/DataTreeStore.h"
|
#include "../../../../implementations/onblocks/datatreestore/DataTreeStore.h"
|
||||||
#include <messmer/blockstore/implementations/testfake/FakeBlockStore.h>
|
#include <messmer/blockstore/implementations/testfake/FakeBlockStore.h>
|
||||||
|
#include <messmer/cpp-utils/pointer/unique_ref_boost_optional_gtest_workaround.h>
|
||||||
|
|
||||||
using blockstore::testfake::FakeBlockStore;
|
using blockstore::testfake::FakeBlockStore;
|
||||||
using blockstore::Key;
|
using blockstore::Key;
|
||||||
using blobstore::onblocks::datanodestore::DataNodeStore;
|
using blobstore::onblocks::datanodestore::DataNodeStore;
|
||||||
using std::make_unique;
|
using boost::none;
|
||||||
|
|
||||||
using namespace blobstore::onblocks::datatreestore;
|
using namespace blobstore::onblocks::datatreestore;
|
||||||
|
|
||||||
@ -16,14 +17,14 @@ class DataTreeStoreTest: public DataTreeTest {
|
|||||||
|
|
||||||
TEST_F(DataTreeStoreTest, CorrectKeyReturned) {
|
TEST_F(DataTreeStoreTest, CorrectKeyReturned) {
|
||||||
Key key = treeStore.createNewTree()->key();
|
Key key = treeStore.createNewTree()->key();
|
||||||
auto tree = treeStore.load(key);
|
auto tree = std::move(treeStore.load(key).get());
|
||||||
EXPECT_EQ(key, tree->key());
|
EXPECT_EQ(key, tree->key());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DataTreeStoreTest, CreatedTreeIsLoadable) {
|
TEST_F(DataTreeStoreTest, CreatedTreeIsLoadable) {
|
||||||
auto key = treeStore.createNewTree()->key();
|
auto key = treeStore.createNewTree()->key();
|
||||||
auto loaded = treeStore.load(key);
|
auto loaded = treeStore.load(key);
|
||||||
EXPECT_NE(nullptr, loaded.get());
|
EXPECT_NE(none, loaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DataTreeStoreTest, NewTreeIsLeafOnly) {
|
TEST_F(DataTreeStoreTest, NewTreeIsLeafOnly) {
|
||||||
@ -35,19 +36,19 @@ TEST_F(DataTreeStoreTest, NewTreeIsLeafOnly) {
|
|||||||
TEST_F(DataTreeStoreTest, TreeIsNotLoadableAfterRemove) {
|
TEST_F(DataTreeStoreTest, TreeIsNotLoadableAfterRemove) {
|
||||||
Key key = treeStore.createNewTree()->key();
|
Key key = treeStore.createNewTree()->key();
|
||||||
auto tree = treeStore.load(key);
|
auto tree = treeStore.load(key);
|
||||||
EXPECT_NE(nullptr, tree.get());
|
EXPECT_NE(none, tree);
|
||||||
treeStore.remove(std::move(tree));
|
treeStore.remove(std::move(*tree));
|
||||||
EXPECT_EQ(nullptr, treeStore.load(key).get());
|
EXPECT_EQ(none, treeStore.load(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DataTreeStoreTest, RemovingTreeRemovesAllNodesOfTheTree) {
|
TEST_F(DataTreeStoreTest, RemovingTreeRemovesAllNodesOfTheTree) {
|
||||||
auto key = CreateThreeLevelMinData()->key();
|
auto key = CreateThreeLevelMinData()->key();
|
||||||
auto tree1 = treeStore.load(key);
|
auto tree1 = std::move(treeStore.load(key).get());
|
||||||
auto tree2_key = treeStore.createNewTree()->key();
|
auto tree2_key = treeStore.createNewTree()->key();
|
||||||
|
|
||||||
treeStore.remove(std::move(tree1));
|
treeStore.remove(std::move(tree1));
|
||||||
|
|
||||||
//Check that the only remaining node is tree2
|
//Check that the only remaining node is tree2
|
||||||
EXPECT_EQ(1, nodeStore->numNodes());
|
EXPECT_EQ(1, nodeStore->numNodes());
|
||||||
EXPECT_NE(nullptr, treeStore.load(tree2_key).get());
|
EXPECT_NE(none, treeStore.load(tree2_key));
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,6 @@ using blobstore::onblocks::datanodestore::DataNodeLayout;
|
|||||||
using blobstore::onblocks::datatreestore::DataTree;
|
using blobstore::onblocks::datatreestore::DataTree;
|
||||||
using blockstore::Key;
|
using blockstore::Key;
|
||||||
|
|
||||||
using std::unique_ptr;
|
|
||||||
|
|
||||||
class DataTreeTest_NumStoredBytes: public DataTreeTest {
|
class DataTreeTest_NumStoredBytes: public DataTreeTest {
|
||||||
public:
|
public:
|
||||||
};
|
};
|
||||||
@ -30,48 +28,48 @@ INSTANTIATE_TEST_CASE_P(FullLastLeaf, DataTreeTest_NumStoredBytes_P, Values(Data
|
|||||||
|
|
||||||
TEST_P(DataTreeTest_NumStoredBytes_P, SingleLeaf) {
|
TEST_P(DataTreeTest_NumStoredBytes_P, SingleLeaf) {
|
||||||
Key key = CreateLeafWithSize(GetParam())->key();
|
Key key = CreateLeafWithSize(GetParam())->key();
|
||||||
auto tree = treeStore.load(key);
|
auto tree = std::move(treeStore.load(key).get());
|
||||||
EXPECT_EQ(GetParam(), tree->numStoredBytes());
|
EXPECT_EQ(GetParam(), tree->numStoredBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DataTreeTest_NumStoredBytes_P, TwoLeafTree) {
|
TEST_P(DataTreeTest_NumStoredBytes_P, TwoLeafTree) {
|
||||||
Key key = CreateTwoLeafWithSecondLeafSize(GetParam())->key();
|
Key key = CreateTwoLeafWithSecondLeafSize(GetParam())->key();
|
||||||
auto tree = treeStore.load(key);
|
auto tree = std::move(treeStore.load(key).get());
|
||||||
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf() + GetParam(), tree->numStoredBytes());
|
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf() + GetParam(), tree->numStoredBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DataTreeTest_NumStoredBytes_P, FullTwolevelTree) {
|
TEST_P(DataTreeTest_NumStoredBytes_P, FullTwolevelTree) {
|
||||||
Key key = CreateFullTwoLevelWithLastLeafSize(GetParam())->key();
|
Key key = CreateFullTwoLevelWithLastLeafSize(GetParam())->key();
|
||||||
auto tree = treeStore.load(key);
|
auto tree = std::move(treeStore.load(key).get());
|
||||||
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf()*(nodeStore->layout().maxChildrenPerInnerNode()-1) + GetParam(), tree->numStoredBytes());
|
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf()*(nodeStore->layout().maxChildrenPerInnerNode()-1) + GetParam(), tree->numStoredBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DataTreeTest_NumStoredBytes_P, ThreeLevelTreeWithOneChild) {
|
TEST_P(DataTreeTest_NumStoredBytes_P, ThreeLevelTreeWithOneChild) {
|
||||||
Key key = CreateThreeLevelWithOneChildAndLastLeafSize(GetParam())->key();
|
Key key = CreateThreeLevelWithOneChildAndLastLeafSize(GetParam())->key();
|
||||||
auto tree = treeStore.load(key);
|
auto tree = std::move(treeStore.load(key).get());
|
||||||
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf() + GetParam(), tree->numStoredBytes());
|
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf() + GetParam(), tree->numStoredBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DataTreeTest_NumStoredBytes_P, ThreeLevelTreeWithTwoChildren) {
|
TEST_P(DataTreeTest_NumStoredBytes_P, ThreeLevelTreeWithTwoChildren) {
|
||||||
Key key = CreateThreeLevelWithTwoChildrenAndLastLeafSize(GetParam())->key();
|
Key key = CreateThreeLevelWithTwoChildrenAndLastLeafSize(GetParam())->key();
|
||||||
auto tree = treeStore.load(key);
|
auto tree = std::move(treeStore.load(key).get());
|
||||||
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf()*nodeStore->layout().maxChildrenPerInnerNode() + nodeStore->layout().maxBytesPerLeaf() + GetParam(), tree->numStoredBytes());
|
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf()*nodeStore->layout().maxChildrenPerInnerNode() + nodeStore->layout().maxBytesPerLeaf() + GetParam(), tree->numStoredBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DataTreeTest_NumStoredBytes_P, ThreeLevelTreeWithThreeChildren) {
|
TEST_P(DataTreeTest_NumStoredBytes_P, ThreeLevelTreeWithThreeChildren) {
|
||||||
Key key = CreateThreeLevelWithThreeChildrenAndLastLeafSize(GetParam())->key();
|
Key key = CreateThreeLevelWithThreeChildrenAndLastLeafSize(GetParam())->key();
|
||||||
auto tree = treeStore.load(key);
|
auto tree = std::move(treeStore.load(key).get());
|
||||||
EXPECT_EQ(2*nodeStore->layout().maxBytesPerLeaf()*nodeStore->layout().maxChildrenPerInnerNode() + nodeStore->layout().maxBytesPerLeaf() + GetParam(), tree->numStoredBytes());
|
EXPECT_EQ(2*nodeStore->layout().maxBytesPerLeaf()*nodeStore->layout().maxChildrenPerInnerNode() + nodeStore->layout().maxBytesPerLeaf() + GetParam(), tree->numStoredBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DataTreeTest_NumStoredBytes_P, FullThreeLevelTree) {
|
TEST_P(DataTreeTest_NumStoredBytes_P, FullThreeLevelTree) {
|
||||||
Key key = CreateFullThreeLevelWithLastLeafSize(GetParam())->key();
|
Key key = CreateFullThreeLevelWithLastLeafSize(GetParam())->key();
|
||||||
auto tree = treeStore.load(key);
|
auto tree = std::move(treeStore.load(key).get());
|
||||||
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf()*nodeStore->layout().maxChildrenPerInnerNode()*(nodeStore->layout().maxChildrenPerInnerNode()-1) + nodeStore->layout().maxBytesPerLeaf()*(nodeStore->layout().maxChildrenPerInnerNode()-1) + GetParam(), tree->numStoredBytes());
|
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf()*nodeStore->layout().maxChildrenPerInnerNode()*(nodeStore->layout().maxChildrenPerInnerNode()-1) + nodeStore->layout().maxBytesPerLeaf()*(nodeStore->layout().maxChildrenPerInnerNode()-1) + GetParam(), tree->numStoredBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(DataTreeTest_NumStoredBytes_P, FourLevelMinDataTree) {
|
TEST_P(DataTreeTest_NumStoredBytes_P, FourLevelMinDataTree) {
|
||||||
Key key = CreateFourLevelMinDataWithLastLeafSize(GetParam())->key();
|
Key key = CreateFourLevelMinDataWithLastLeafSize(GetParam())->key();
|
||||||
auto tree = treeStore.load(key);
|
auto tree = std::move(treeStore.load(key).get());
|
||||||
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf()*nodeStore->layout().maxChildrenPerInnerNode()*nodeStore->layout().maxChildrenPerInnerNode() + GetParam(), tree->numStoredBytes());
|
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf()*nodeStore->layout().maxChildrenPerInnerNode()*nodeStore->layout().maxChildrenPerInnerNode() + GetParam(), tree->numStoredBytes());
|
||||||
}
|
}
|
||||||
|
@ -22,49 +22,50 @@ using blobstore::onblocks::datatreestore::DataTree;
|
|||||||
using blobstore::onblocks::utils::ceilDivision;
|
using blobstore::onblocks::utils::ceilDivision;
|
||||||
using blockstore::Key;
|
using blockstore::Key;
|
||||||
using cpputils::Data;
|
using cpputils::Data;
|
||||||
|
using boost::none;
|
||||||
|
|
||||||
using std::unique_ptr;
|
using cpputils::unique_ref;
|
||||||
|
|
||||||
class DataTreeTest_ResizeByTraversing: public DataTreeTest {
|
class DataTreeTest_ResizeByTraversing: public DataTreeTest {
|
||||||
public:
|
public:
|
||||||
static constexpr DataNodeLayout LAYOUT = DataNodeLayout(BLOCKSIZE_BYTES);
|
static constexpr DataNodeLayout LAYOUT = DataNodeLayout(BLOCKSIZE_BYTES);
|
||||||
|
|
||||||
unique_ptr<DataTree> CreateTree(unique_ptr<DataNode> root) {
|
unique_ref<DataTree> CreateTree(unique_ref<DataNode> root) {
|
||||||
Key key = root->key();
|
Key key = root->key();
|
||||||
root.reset();
|
cpputils::to_unique_ptr(std::move(root)).reset(); //Destruct
|
||||||
return treeStore.load(key);
|
return std::move(treeStore.load(key).get());
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTree> CreateLeafTreeWithSize(uint32_t size) {
|
unique_ref<DataTree> CreateLeafTreeWithSize(uint32_t size) {
|
||||||
return CreateTree(CreateLeafWithSize(size));
|
return CreateTree(CreateLeafWithSize(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTree> CreateTwoLeafTreeWithSecondLeafSize(uint32_t size) {
|
unique_ref<DataTree> CreateTwoLeafTreeWithSecondLeafSize(uint32_t size) {
|
||||||
return CreateTree(CreateTwoLeafWithSecondLeafSize(size));
|
return CreateTree(CreateTwoLeafWithSecondLeafSize(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTree> CreateFullTwoLevelTreeWithLastLeafSize(uint32_t size) {
|
unique_ref<DataTree> CreateFullTwoLevelTreeWithLastLeafSize(uint32_t size) {
|
||||||
return CreateTree(CreateFullTwoLevelWithLastLeafSize(size));
|
return CreateTree(CreateFullTwoLevelWithLastLeafSize(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTree> CreateThreeLevelTreeWithTwoChildrenAndLastLeafSize(uint32_t size) {
|
unique_ref<DataTree> CreateThreeLevelTreeWithTwoChildrenAndLastLeafSize(uint32_t size) {
|
||||||
return CreateTree(CreateThreeLevelWithTwoChildrenAndLastLeafSize(size));
|
return CreateTree(CreateThreeLevelWithTwoChildrenAndLastLeafSize(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTree> CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(uint32_t size) {
|
unique_ref<DataTree> CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(uint32_t size) {
|
||||||
return CreateTree(CreateThreeLevelWithThreeChildrenAndLastLeafSize(size));
|
return CreateTree(CreateThreeLevelWithThreeChildrenAndLastLeafSize(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTree> CreateFullThreeLevelTreeWithLastLeafSize(uint32_t size) {
|
unique_ref<DataTree> CreateFullThreeLevelTreeWithLastLeafSize(uint32_t size) {
|
||||||
return CreateTree(CreateFullThreeLevelWithLastLeafSize(size));
|
return CreateTree(CreateFullThreeLevelWithLastLeafSize(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTree> CreateFourLevelMinDataTreeWithLastLeafSize(uint32_t size) {
|
unique_ref<DataTree> CreateFourLevelMinDataTreeWithLastLeafSize(uint32_t size) {
|
||||||
return CreateTree(CreateFourLevelMinDataWithLastLeafSize(size));
|
return CreateTree(CreateFourLevelMinDataWithLastLeafSize(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EXPECT_IS_LEFTMAXDATA_TREE(const Key &key) {
|
void EXPECT_IS_LEFTMAXDATA_TREE(const Key &key) {
|
||||||
auto root = nodeStore->load(key);
|
auto root = std::move(nodeStore->load(key).get());
|
||||||
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root.get());
|
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root.get());
|
||||||
if (inner != nullptr) {
|
if (inner != nullptr) {
|
||||||
for (uint32_t i = 0; i < inner->numChildren()-1; ++i) {
|
for (uint32_t i = 0; i < inner->numChildren()-1; ++i) {
|
||||||
@ -75,7 +76,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EXPECT_IS_MAXDATA_TREE(const Key &key) {
|
void EXPECT_IS_MAXDATA_TREE(const Key &key) {
|
||||||
auto root = nodeStore->load(key);
|
auto root = std::move(nodeStore->load(key).get());
|
||||||
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root.get());
|
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root.get());
|
||||||
if (inner != nullptr) {
|
if (inner != nullptr) {
|
||||||
for (uint32_t i = 0; i < inner->numChildren(); ++i) {
|
for (uint32_t i = 0; i < inner->numChildren(); ++i) {
|
||||||
@ -89,7 +90,7 @@ public:
|
|||||||
};
|
};
|
||||||
constexpr DataNodeLayout DataTreeTest_ResizeByTraversing::LAYOUT;
|
constexpr DataNodeLayout DataTreeTest_ResizeByTraversing::LAYOUT;
|
||||||
|
|
||||||
class DataTreeTest_ResizeByTraversing_P: public DataTreeTest_ResizeByTraversing, public WithParamInterface<tuple<function<unique_ptr<DataTree>(DataTreeTest_ResizeByTraversing*, uint32_t)>, uint32_t, uint32_t>> {
|
class DataTreeTest_ResizeByTraversing_P: public DataTreeTest_ResizeByTraversing, public WithParamInterface<tuple<function<unique_ref<DataTree>(DataTreeTest_ResizeByTraversing*, uint32_t)>, uint32_t, uint32_t>> {
|
||||||
public:
|
public:
|
||||||
DataTreeTest_ResizeByTraversing_P()
|
DataTreeTest_ResizeByTraversing_P()
|
||||||
: oldLastLeafSize(get<1>(GetParam())),
|
: oldLastLeafSize(get<1>(GetParam())),
|
||||||
@ -103,7 +104,7 @@ public:
|
|||||||
|
|
||||||
void GrowTree(const Key &key, uint32_t numLeavesToAdd) {
|
void GrowTree(const Key &key, uint32_t numLeavesToAdd) {
|
||||||
auto tree = treeStore.load(key);
|
auto tree = treeStore.load(key);
|
||||||
GrowTree(tree.get(), numLeavesToAdd);
|
GrowTree(tree.get().get(), numLeavesToAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrowTree(DataTree *tree, uint32_t numLeavesToAdd) {
|
void GrowTree(DataTree *tree, uint32_t numLeavesToAdd) {
|
||||||
@ -114,18 +115,18 @@ public:
|
|||||||
tree->flush();
|
tree->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataLeafNode> LastLeaf(const Key &key) {
|
unique_ref<DataLeafNode> LastLeaf(const Key &key) {
|
||||||
auto root = nodeStore->load(key);
|
auto root = std::move(nodeStore->load(key).get());
|
||||||
auto leaf = dynamic_pointer_move<DataLeafNode>(root);
|
auto leaf = dynamic_pointer_move<DataLeafNode>(root);
|
||||||
if (leaf.get() != nullptr) {
|
if (leaf != none) {
|
||||||
return leaf;
|
return std::move(*leaf);
|
||||||
}
|
}
|
||||||
auto inner = dynamic_pointer_move<DataInnerNode>(root);
|
auto inner = std::move(dynamic_pointer_move<DataInnerNode>(root).get());
|
||||||
return LastLeaf(inner->LastChild()->key());
|
return LastLeaf(inner->LastChild()->key());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t oldLastLeafSize;
|
uint32_t oldLastLeafSize;
|
||||||
unique_ptr<DataTree> tree;
|
unique_ref<DataTree> tree;
|
||||||
uint32_t numberOfLeavesToAdd;
|
uint32_t numberOfLeavesToAdd;
|
||||||
uint32_t newNumberOfLeaves;
|
uint32_t newNumberOfLeaves;
|
||||||
Data ZEROES;
|
Data ZEROES;
|
||||||
@ -133,7 +134,7 @@ public:
|
|||||||
INSTANTIATE_TEST_CASE_P(DataTreeTest_ResizeByTraversing_P, DataTreeTest_ResizeByTraversing_P,
|
INSTANTIATE_TEST_CASE_P(DataTreeTest_ResizeByTraversing_P, DataTreeTest_ResizeByTraversing_P,
|
||||||
Combine(
|
Combine(
|
||||||
//Tree we're starting with
|
//Tree we're starting with
|
||||||
Values<function<unique_ptr<DataTree>(DataTreeTest_ResizeByTraversing*, uint32_t)>>(
|
Values<function<unique_ref<DataTree>(DataTreeTest_ResizeByTraversing*, uint32_t)>>(
|
||||||
mem_fn(&DataTreeTest_ResizeByTraversing::CreateLeafTreeWithSize),
|
mem_fn(&DataTreeTest_ResizeByTraversing::CreateLeafTreeWithSize),
|
||||||
mem_fn(&DataTreeTest_ResizeByTraversing::CreateTwoLeafTreeWithSecondLeafSize),
|
mem_fn(&DataTreeTest_ResizeByTraversing::CreateTwoLeafTreeWithSecondLeafSize),
|
||||||
mem_fn(&DataTreeTest_ResizeByTraversing::CreateFullTwoLevelTreeWithLastLeafSize),
|
mem_fn(&DataTreeTest_ResizeByTraversing::CreateFullTwoLevelTreeWithLastLeafSize),
|
||||||
@ -191,10 +192,10 @@ TEST_P(DataTreeTest_ResizeByTraversing_P, DataStaysIntact) {
|
|||||||
uint32_t oldNumberOfLeaves = std::max(1u, ceilDivision(tree->numStoredBytes(), nodeStore->layout().maxBytesPerLeaf()));
|
uint32_t oldNumberOfLeaves = std::max(1u, ceilDivision(tree->numStoredBytes(), nodeStore->layout().maxBytesPerLeaf()));
|
||||||
TwoLevelDataFixture data(nodeStore, TwoLevelDataFixture::SizePolicy::Unchanged);
|
TwoLevelDataFixture data(nodeStore, TwoLevelDataFixture::SizePolicy::Unchanged);
|
||||||
Key key = tree->key();
|
Key key = tree->key();
|
||||||
tree.reset();
|
cpputils::to_unique_ptr(std::move(tree)).reset(); // Call destructor
|
||||||
data.FillInto(nodeStore->load(key).get());
|
data.FillInto(nodeStore->load(key).get().get());
|
||||||
|
|
||||||
GrowTree(key, newNumberOfLeaves);
|
GrowTree(key, newNumberOfLeaves);
|
||||||
|
|
||||||
data.EXPECT_DATA_CORRECT(nodeStore->load(key).get(), oldNumberOfLeaves, oldLastLeafSize);
|
data.EXPECT_DATA_CORRECT(nodeStore->load(key).get().get(), oldNumberOfLeaves, oldLastLeafSize);
|
||||||
}
|
}
|
||||||
|
@ -22,49 +22,50 @@ using blobstore::onblocks::datatreestore::DataTree;
|
|||||||
using blobstore::onblocks::utils::ceilDivision;
|
using blobstore::onblocks::utils::ceilDivision;
|
||||||
using blockstore::Key;
|
using blockstore::Key;
|
||||||
using cpputils::Data;
|
using cpputils::Data;
|
||||||
|
using boost::none;
|
||||||
|
|
||||||
using std::unique_ptr;
|
using cpputils::unique_ref;
|
||||||
|
|
||||||
class DataTreeTest_ResizeNumBytes: public DataTreeTest {
|
class DataTreeTest_ResizeNumBytes: public DataTreeTest {
|
||||||
public:
|
public:
|
||||||
static constexpr DataNodeLayout LAYOUT = DataNodeLayout(BLOCKSIZE_BYTES);
|
static constexpr DataNodeLayout LAYOUT = DataNodeLayout(BLOCKSIZE_BYTES);
|
||||||
|
|
||||||
unique_ptr<DataTree> CreateTree(unique_ptr<DataNode> root) {
|
unique_ref<DataTree> CreateTree(unique_ref<DataNode> root) {
|
||||||
Key key = root->key();
|
Key key = root->key();
|
||||||
root.reset();
|
cpputils::to_unique_ptr(std::move(root)).reset(); // Destruct
|
||||||
return treeStore.load(key);
|
return std::move(treeStore.load(key).get());
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTree> CreateLeafTreeWithSize(uint32_t size) {
|
unique_ref<DataTree> CreateLeafTreeWithSize(uint32_t size) {
|
||||||
return CreateTree(CreateLeafWithSize(size));
|
return CreateTree(CreateLeafWithSize(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTree> CreateTwoLeafTreeWithSecondLeafSize(uint32_t size) {
|
unique_ref<DataTree> CreateTwoLeafTreeWithSecondLeafSize(uint32_t size) {
|
||||||
return CreateTree(CreateTwoLeafWithSecondLeafSize(size));
|
return CreateTree(CreateTwoLeafWithSecondLeafSize(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTree> CreateFullTwoLevelTreeWithLastLeafSize(uint32_t size) {
|
unique_ref<DataTree> CreateFullTwoLevelTreeWithLastLeafSize(uint32_t size) {
|
||||||
return CreateTree(CreateFullTwoLevelWithLastLeafSize(size));
|
return CreateTree(CreateFullTwoLevelWithLastLeafSize(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTree> CreateThreeLevelTreeWithTwoChildrenAndLastLeafSize(uint32_t size) {
|
unique_ref<DataTree> CreateThreeLevelTreeWithTwoChildrenAndLastLeafSize(uint32_t size) {
|
||||||
return CreateTree(CreateThreeLevelWithTwoChildrenAndLastLeafSize(size));
|
return CreateTree(CreateThreeLevelWithTwoChildrenAndLastLeafSize(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTree> CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(uint32_t size) {
|
unique_ref<DataTree> CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(uint32_t size) {
|
||||||
return CreateTree(CreateThreeLevelWithThreeChildrenAndLastLeafSize(size));
|
return CreateTree(CreateThreeLevelWithThreeChildrenAndLastLeafSize(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTree> CreateFullThreeLevelTreeWithLastLeafSize(uint32_t size) {
|
unique_ref<DataTree> CreateFullThreeLevelTreeWithLastLeafSize(uint32_t size) {
|
||||||
return CreateTree(CreateFullThreeLevelWithLastLeafSize(size));
|
return CreateTree(CreateFullThreeLevelWithLastLeafSize(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTree> CreateFourLevelMinDataTreeWithLastLeafSize(uint32_t size) {
|
unique_ref<DataTree> CreateFourLevelMinDataTreeWithLastLeafSize(uint32_t size) {
|
||||||
return CreateTree(CreateFourLevelMinDataWithLastLeafSize(size));
|
return CreateTree(CreateFourLevelMinDataWithLastLeafSize(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EXPECT_IS_LEFTMAXDATA_TREE(const Key &key) {
|
void EXPECT_IS_LEFTMAXDATA_TREE(const Key &key) {
|
||||||
auto root = nodeStore->load(key);
|
auto root = std::move(nodeStore->load(key).get());
|
||||||
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root.get());
|
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root.get());
|
||||||
if (inner != nullptr) {
|
if (inner != nullptr) {
|
||||||
for (uint32_t i = 0; i < inner->numChildren()-1; ++i) {
|
for (uint32_t i = 0; i < inner->numChildren()-1; ++i) {
|
||||||
@ -75,7 +76,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EXPECT_IS_MAXDATA_TREE(const Key &key) {
|
void EXPECT_IS_MAXDATA_TREE(const Key &key) {
|
||||||
auto root = nodeStore->load(key);
|
auto root = std::move(nodeStore->load(key).get());
|
||||||
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root.get());
|
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root.get());
|
||||||
if (inner != nullptr) {
|
if (inner != nullptr) {
|
||||||
for (uint32_t i = 0; i < inner->numChildren(); ++i) {
|
for (uint32_t i = 0; i < inner->numChildren(); ++i) {
|
||||||
@ -89,7 +90,7 @@ public:
|
|||||||
};
|
};
|
||||||
constexpr DataNodeLayout DataTreeTest_ResizeNumBytes::LAYOUT;
|
constexpr DataNodeLayout DataTreeTest_ResizeNumBytes::LAYOUT;
|
||||||
|
|
||||||
class DataTreeTest_ResizeNumBytes_P: public DataTreeTest_ResizeNumBytes, public WithParamInterface<tuple<function<unique_ptr<DataTree>(DataTreeTest_ResizeNumBytes*, uint32_t)>, uint32_t, uint32_t, uint32_t>> {
|
class DataTreeTest_ResizeNumBytes_P: public DataTreeTest_ResizeNumBytes, public WithParamInterface<tuple<function<unique_ref<DataTree>(DataTreeTest_ResizeNumBytes*, uint32_t)>, uint32_t, uint32_t, uint32_t>> {
|
||||||
public:
|
public:
|
||||||
DataTreeTest_ResizeNumBytes_P()
|
DataTreeTest_ResizeNumBytes_P()
|
||||||
: oldLastLeafSize(get<1>(GetParam())),
|
: oldLastLeafSize(get<1>(GetParam())),
|
||||||
@ -103,21 +104,21 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ResizeTree(const Key &key, uint64_t size) {
|
void ResizeTree(const Key &key, uint64_t size) {
|
||||||
treeStore.load(key)->resizeNumBytes(size);
|
treeStore.load(key).get()->resizeNumBytes(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataLeafNode> LastLeaf(const Key &key) {
|
unique_ref<DataLeafNode> LastLeaf(const Key &key) {
|
||||||
auto root = nodeStore->load(key);
|
auto root = std::move(nodeStore->load(key).get());
|
||||||
auto leaf = dynamic_pointer_move<DataLeafNode>(root);
|
auto leaf = dynamic_pointer_move<DataLeafNode>(root);
|
||||||
if (leaf.get() != nullptr) {
|
if (leaf != none) {
|
||||||
return leaf;
|
return std::move(*leaf);
|
||||||
}
|
}
|
||||||
auto inner = dynamic_pointer_move<DataInnerNode>(root);
|
auto inner = std::move(dynamic_pointer_move<DataInnerNode>(root).get());
|
||||||
return LastLeaf(inner->LastChild()->key());
|
return LastLeaf(inner->LastChild()->key());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t oldLastLeafSize;
|
uint32_t oldLastLeafSize;
|
||||||
unique_ptr<DataTree> tree;
|
unique_ref<DataTree> tree;
|
||||||
uint32_t newNumberOfLeaves;
|
uint32_t newNumberOfLeaves;
|
||||||
uint32_t newLastLeafSize;
|
uint32_t newLastLeafSize;
|
||||||
uint64_t newSize;
|
uint64_t newSize;
|
||||||
@ -126,7 +127,7 @@ public:
|
|||||||
INSTANTIATE_TEST_CASE_P(DataTreeTest_ResizeNumBytes_P, DataTreeTest_ResizeNumBytes_P,
|
INSTANTIATE_TEST_CASE_P(DataTreeTest_ResizeNumBytes_P, DataTreeTest_ResizeNumBytes_P,
|
||||||
Combine(
|
Combine(
|
||||||
//Tree we're starting with
|
//Tree we're starting with
|
||||||
Values<function<unique_ptr<DataTree>(DataTreeTest_ResizeNumBytes*, uint32_t)>>(
|
Values<function<unique_ref<DataTree>(DataTreeTest_ResizeNumBytes*, uint32_t)>>(
|
||||||
mem_fn(&DataTreeTest_ResizeNumBytes::CreateLeafTreeWithSize),
|
mem_fn(&DataTreeTest_ResizeNumBytes::CreateLeafTreeWithSize),
|
||||||
mem_fn(&DataTreeTest_ResizeNumBytes::CreateTwoLeafTreeWithSecondLeafSize),
|
mem_fn(&DataTreeTest_ResizeNumBytes::CreateTwoLeafTreeWithSecondLeafSize),
|
||||||
mem_fn(&DataTreeTest_ResizeNumBytes::CreateFullTwoLevelTreeWithLastLeafSize),
|
mem_fn(&DataTreeTest_ResizeNumBytes::CreateFullTwoLevelTreeWithLastLeafSize),
|
||||||
@ -193,15 +194,15 @@ TEST_P(DataTreeTest_ResizeNumBytes_P, DataStaysIntact) {
|
|||||||
uint32_t oldNumberOfLeaves = std::max(1u, ceilDivision(tree->numStoredBytes(), nodeStore->layout().maxBytesPerLeaf()));
|
uint32_t oldNumberOfLeaves = std::max(1u, ceilDivision(tree->numStoredBytes(), nodeStore->layout().maxBytesPerLeaf()));
|
||||||
TwoLevelDataFixture data(nodeStore, TwoLevelDataFixture::SizePolicy::Unchanged);
|
TwoLevelDataFixture data(nodeStore, TwoLevelDataFixture::SizePolicy::Unchanged);
|
||||||
Key key = tree->key();
|
Key key = tree->key();
|
||||||
tree.reset();
|
cpputils::to_unique_ptr(std::move(tree)).reset(); // Call destructor
|
||||||
data.FillInto(nodeStore->load(key).get());
|
data.FillInto(nodeStore->load(key).get().get());
|
||||||
|
|
||||||
ResizeTree(key, newSize);
|
ResizeTree(key, newSize);
|
||||||
|
|
||||||
if (oldNumberOfLeaves < newNumberOfLeaves || (oldNumberOfLeaves == newNumberOfLeaves && oldLastLeafSize < newLastLeafSize)) {
|
if (oldNumberOfLeaves < newNumberOfLeaves || (oldNumberOfLeaves == newNumberOfLeaves && oldLastLeafSize < newLastLeafSize)) {
|
||||||
data.EXPECT_DATA_CORRECT(nodeStore->load(key).get(), oldNumberOfLeaves, oldLastLeafSize);
|
data.EXPECT_DATA_CORRECT(nodeStore->load(key).get().get(), oldNumberOfLeaves, oldLastLeafSize);
|
||||||
} else {
|
} else {
|
||||||
data.EXPECT_DATA_CORRECT(nodeStore->load(key).get(), newNumberOfLeaves, newLastLeafSize);
|
data.EXPECT_DATA_CORRECT(nodeStore->load(key).get().get(), newNumberOfLeaves, newLastLeafSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,7 +212,7 @@ TEST_F(DataTreeTest_ResizeNumBytes, ResizeToZero_NumBytesIsCorrect) {
|
|||||||
auto tree = CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(10u);
|
auto tree = CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(10u);
|
||||||
tree->resizeNumBytes(0);
|
tree->resizeNumBytes(0);
|
||||||
Key key = tree->key();
|
Key key = tree->key();
|
||||||
tree.reset();
|
cpputils::to_unique_ptr(std::move(tree)).reset(); // Call destructor
|
||||||
auto leaf = LoadLeafNode(key);
|
auto leaf = LoadLeafNode(key);
|
||||||
EXPECT_EQ(0u, leaf->numBytes());
|
EXPECT_EQ(0u, leaf->numBytes());
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ using blobstore::onblocks::datanodestore::DataNode;
|
|||||||
using blobstore::onblocks::datatreestore::DataTree;
|
using blobstore::onblocks::datatreestore::DataTree;
|
||||||
using blockstore::Key;
|
using blockstore::Key;
|
||||||
|
|
||||||
using std::unique_ptr;
|
using cpputils::unique_ref;
|
||||||
|
|
||||||
class TraversorMock {
|
class TraversorMock {
|
||||||
public:
|
public:
|
||||||
@ -22,7 +22,7 @@ MATCHER_P(KeyEq, expected, "node key equals") {
|
|||||||
|
|
||||||
class DataTreeTest_TraverseLeaves: public DataTreeTest {
|
class DataTreeTest_TraverseLeaves: public DataTreeTest {
|
||||||
public:
|
public:
|
||||||
unique_ptr<DataInnerNode> CreateThreeLevel() {
|
unique_ref<DataInnerNode> CreateThreeLevel() {
|
||||||
return CreateInner({
|
return CreateInner({
|
||||||
CreateFullTwoLevel(),
|
CreateFullTwoLevel(),
|
||||||
CreateFullTwoLevel(),
|
CreateFullTwoLevel(),
|
||||||
@ -32,7 +32,7 @@ public:
|
|||||||
CreateInner({CreateLeaf(), CreateLeaf(), CreateLeaf()})});
|
CreateInner({CreateLeaf(), CreateLeaf(), CreateLeaf()})});
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> CreateFourLevel() {
|
unique_ref<DataInnerNode> CreateFourLevel() {
|
||||||
return CreateInner({
|
return CreateInner({
|
||||||
CreateFullThreeLevel(),
|
CreateFullThreeLevel(),
|
||||||
CreateFullThreeLevel(),
|
CreateFullThreeLevel(),
|
||||||
@ -56,7 +56,7 @@ public:
|
|||||||
|
|
||||||
void TraverseLeaves(DataNode *root, uint32_t beginIndex, uint32_t endIndex) {
|
void TraverseLeaves(DataNode *root, uint32_t beginIndex, uint32_t endIndex) {
|
||||||
root->flush();
|
root->flush();
|
||||||
auto tree = treeStore.load(root->key());
|
auto tree = std::move(treeStore.load(root->key()).get());
|
||||||
tree->traverseLeaves(beginIndex, endIndex, [this] (DataLeafNode *leaf, uint32_t nodeIndex) {
|
tree->traverseLeaves(beginIndex, endIndex, [this] (DataLeafNode *leaf, uint32_t nodeIndex) {
|
||||||
traversor.called(leaf, nodeIndex);
|
traversor.called(leaf, nodeIndex);
|
||||||
});
|
});
|
||||||
|
@ -8,8 +8,6 @@
|
|||||||
#include "../../../../../implementations/onblocks/datatreestore/impl/algorithms.h"
|
#include "../../../../../implementations/onblocks/datatreestore/impl/algorithms.h"
|
||||||
|
|
||||||
using ::testing::Test;
|
using ::testing::Test;
|
||||||
using std::unique_ptr;
|
|
||||||
using std::make_unique;
|
|
||||||
using std::pair;
|
using std::pair;
|
||||||
using std::make_pair;
|
using std::make_pair;
|
||||||
|
|
||||||
@ -28,7 +26,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void check(const TestData &testData) {
|
void check(const TestData &testData) {
|
||||||
auto root = nodeStore->load(testData.rootNode);
|
auto root = std::move(nodeStore->load(testData.rootNode).get());
|
||||||
auto result = GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(nodeStore, root.get());
|
auto result = GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(nodeStore, root.get());
|
||||||
EXPECT_EQ(testData.expectedResult, result->key());
|
EXPECT_EQ(testData.expectedResult, result->key());
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,6 @@
|
|||||||
#include "../../../../../implementations/onblocks/datatreestore/impl/algorithms.h"
|
#include "../../../../../implementations/onblocks/datatreestore/impl/algorithms.h"
|
||||||
|
|
||||||
using ::testing::Test;
|
using ::testing::Test;
|
||||||
using std::unique_ptr;
|
|
||||||
using std::make_unique;
|
|
||||||
using std::pair;
|
using std::pair;
|
||||||
using std::make_pair;
|
using std::make_pair;
|
||||||
|
|
||||||
@ -28,7 +26,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void check(const TestData &testData) {
|
void check(const TestData &testData) {
|
||||||
auto root = nodeStore->load(testData.rootNode);
|
auto root = std::move(nodeStore->load(testData.rootNode).get());
|
||||||
auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, root.get());
|
auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, root.get());
|
||||||
EXPECT_EQ(testData.expectedResult, result->key());
|
EXPECT_EQ(testData.expectedResult, result->key());
|
||||||
}
|
}
|
||||||
@ -80,19 +78,19 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest, Leaf) {
|
TEST_F(GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest, Leaf) {
|
||||||
auto leaf = nodeStore->load(CreateLeafOnlyTree());
|
auto leaf = std::move(nodeStore->load(CreateLeafOnlyTree()).get());
|
||||||
auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, leaf.get());
|
auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, leaf.get());
|
||||||
EXPECT_EQ(nullptr, result.get());
|
EXPECT_EQ(nullptr, result.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest, TwoRightBorderNodes) {
|
TEST_F(GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest, TwoRightBorderNodes) {
|
||||||
auto node = nodeStore->load(CreateTwoRightBorderNodes());
|
auto node = std::move(nodeStore->load(CreateTwoRightBorderNodes()).get());
|
||||||
auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, node.get());
|
auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, node.get());
|
||||||
EXPECT_EQ(nullptr, result.get());
|
EXPECT_EQ(nullptr, result.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest, ThreeRightBorderNodes) {
|
TEST_F(GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest, ThreeRightBorderNodes) {
|
||||||
auto node = nodeStore->load(CreateThreeRightBorderNodes());
|
auto node = std::move(nodeStore->load(CreateThreeRightBorderNodes()).get());
|
||||||
auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, node.get());
|
auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, node.get());
|
||||||
EXPECT_EQ(nullptr, result.get());
|
EXPECT_EQ(nullptr, result.get());
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "messmer/blockstore/implementations/testfake/FakeBlockStore.h"
|
#include "messmer/blockstore/implementations/testfake/FakeBlockStore.h"
|
||||||
#include <messmer/cpp-utils/pointer/cast.h>
|
#include <messmer/cpp-utils/pointer/cast.h>
|
||||||
|
#include <messmer/cpp-utils/pointer/unique_ref_boost_optional_gtest_workaround.h>
|
||||||
|
|
||||||
using blobstore::onblocks::datanodestore::DataNodeStore;
|
using blobstore::onblocks::datanodestore::DataNodeStore;
|
||||||
using blobstore::onblocks::datanodestore::DataNode;
|
using blobstore::onblocks::datanodestore::DataNode;
|
||||||
@ -10,35 +11,36 @@ using blobstore::onblocks::datanodestore::DataLeafNode;
|
|||||||
using blobstore::onblocks::datatreestore::DataTree;
|
using blobstore::onblocks::datatreestore::DataTree;
|
||||||
using blockstore::testfake::FakeBlockStore;
|
using blockstore::testfake::FakeBlockStore;
|
||||||
using blockstore::Key;
|
using blockstore::Key;
|
||||||
using std::make_unique;
|
using cpputils::unique_ref;
|
||||||
using std::unique_ptr;
|
using cpputils::make_unique_ref;
|
||||||
using std::initializer_list;
|
using std::initializer_list;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
using boost::none;
|
||||||
using cpputils::dynamic_pointer_move;
|
using cpputils::dynamic_pointer_move;
|
||||||
|
|
||||||
constexpr uint32_t DataTreeTest::BLOCKSIZE_BYTES;
|
constexpr uint32_t DataTreeTest::BLOCKSIZE_BYTES;
|
||||||
|
|
||||||
DataTreeTest::DataTreeTest()
|
DataTreeTest::DataTreeTest()
|
||||||
:_nodeStore(make_unique<DataNodeStore>(make_unique<FakeBlockStore>(), BLOCKSIZE_BYTES)),
|
:_nodeStore(make_unique_ref<DataNodeStore>(make_unique_ref<FakeBlockStore>(), BLOCKSIZE_BYTES)),
|
||||||
nodeStore(_nodeStore.get()),
|
nodeStore(_nodeStore.get()),
|
||||||
treeStore(std::move(_nodeStore)) {
|
treeStore(std::move(_nodeStore)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataLeafNode> DataTreeTest::CreateLeaf() {
|
unique_ref<DataLeafNode> DataTreeTest::CreateLeaf() {
|
||||||
return nodeStore->createNewLeafNode();
|
return nodeStore->createNewLeafNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataTreeTest::CreateInner(initializer_list<unique_ptr<DataNode>> children) {
|
unique_ref<DataInnerNode> DataTreeTest::CreateInner(initializer_list<unique_ref<DataNode>> children) {
|
||||||
vector<const DataNode*> childrenVector(children.size());
|
vector<const DataNode*> childrenVector(children.size());
|
||||||
std::transform(children.begin(), children.end(), childrenVector.begin(), [](const unique_ptr<DataNode> &ptr) {return ptr.get();});
|
std::transform(children.begin(), children.end(), childrenVector.begin(), [](const unique_ref<DataNode> &ptr) {return ptr.get();});
|
||||||
return CreateInner(childrenVector);
|
return CreateInner(childrenVector);
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataTreeTest::CreateInner(initializer_list<const DataNode*> children) {
|
unique_ref<DataInnerNode> DataTreeTest::CreateInner(initializer_list<const DataNode*> children) {
|
||||||
return CreateInner(vector<const DataNode*>(children));
|
return CreateInner(vector<const DataNode*>(children));
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataTreeTest::CreateInner(vector<const DataNode*> children) {
|
unique_ref<DataInnerNode> DataTreeTest::CreateInner(vector<const DataNode*> children) {
|
||||||
assert(children.size() >= 1);
|
assert(children.size() >= 1);
|
||||||
auto node = nodeStore->createNewInnerNode(**children.begin());
|
auto node = nodeStore->createNewInnerNode(**children.begin());
|
||||||
for(auto child = children.begin()+1; child != children.end(); ++child) {
|
for(auto child = children.begin()+1; child != children.end(); ++child) {
|
||||||
@ -47,9 +49,9 @@ unique_ptr<DataInnerNode> DataTreeTest::CreateInner(vector<const DataNode*> chil
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTree> DataTreeTest::CreateLeafOnlyTree() {
|
unique_ref<DataTree> DataTreeTest::CreateLeafOnlyTree() {
|
||||||
auto key = CreateLeaf()->key();
|
auto key = CreateLeaf()->key();
|
||||||
return treeStore.load(key);
|
return std::move(treeStore.load(key).get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataTreeTest::FillNode(DataInnerNode *node) {
|
void DataTreeTest::FillNode(DataInnerNode *node) {
|
||||||
@ -64,69 +66,69 @@ void DataTreeTest::FillNodeTwoLevel(DataInnerNode *node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataTreeTest::CreateFullTwoLevel() {
|
unique_ref<DataInnerNode> DataTreeTest::CreateFullTwoLevel() {
|
||||||
auto root = CreateInner({CreateLeaf().get()});
|
auto root = CreateInner({CreateLeaf().get()});
|
||||||
FillNode(root.get());
|
FillNode(root.get());
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataTreeTest::CreateThreeLevelMinData() {
|
unique_ref<DataInnerNode> DataTreeTest::CreateThreeLevelMinData() {
|
||||||
return CreateInner({
|
return CreateInner({
|
||||||
CreateFullTwoLevel(),
|
CreateFullTwoLevel(),
|
||||||
CreateInner({CreateLeaf()})
|
CreateInner({CreateLeaf()})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataTreeTest::CreateFourLevelMinData() {
|
unique_ref<DataInnerNode> DataTreeTest::CreateFourLevelMinData() {
|
||||||
return CreateInner({
|
return CreateInner({
|
||||||
CreateFullThreeLevel(),
|
CreateFullThreeLevel(),
|
||||||
CreateInner({CreateInner({CreateLeaf()})})
|
CreateInner({CreateInner({CreateLeaf()})})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataTreeTest::CreateFullThreeLevel() {
|
unique_ref<DataInnerNode> DataTreeTest::CreateFullThreeLevel() {
|
||||||
auto root = CreateInner({CreateFullTwoLevel().get()});
|
auto root = CreateInner({CreateFullTwoLevel().get()});
|
||||||
FillNodeTwoLevel(root.get());
|
FillNodeTwoLevel(root.get());
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataTreeTest::LoadInnerNode(const Key &key) {
|
unique_ref<DataInnerNode> DataTreeTest::LoadInnerNode(const Key &key) {
|
||||||
auto node = nodeStore->load(key);
|
auto node = std::move(nodeStore->load(key).get());
|
||||||
auto casted = dynamic_pointer_move<DataInnerNode>(node);
|
auto casted = dynamic_pointer_move<DataInnerNode>(node);
|
||||||
EXPECT_NE(nullptr, casted.get()) << "Is not an inner node";
|
EXPECT_NE(none, casted) << "Is not an inner node";
|
||||||
return casted;
|
return std::move(*casted);
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataLeafNode> DataTreeTest::LoadLeafNode(const Key &key) {
|
unique_ref<DataLeafNode> DataTreeTest::LoadLeafNode(const Key &key) {
|
||||||
auto node = nodeStore->load(key);
|
auto node = std::move(nodeStore->load(key).get());
|
||||||
auto casted = dynamic_pointer_move<DataLeafNode>(node);
|
auto casted = dynamic_pointer_move<DataLeafNode>(node);
|
||||||
EXPECT_NE(nullptr, casted.get()) << "Is not a leaf node";
|
EXPECT_NE(none, casted) << "Is not a leaf node";
|
||||||
return casted;
|
return std::move(*casted);
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataTreeTest::CreateTwoLeaf() {
|
unique_ref<DataInnerNode> DataTreeTest::CreateTwoLeaf() {
|
||||||
return CreateInner({CreateLeaf().get(), CreateLeaf().get()});
|
return CreateInner({CreateLeaf().get(), CreateLeaf().get()});
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataTree> DataTreeTest::CreateTwoLeafTree() {
|
unique_ref<DataTree> DataTreeTest::CreateTwoLeafTree() {
|
||||||
auto key = CreateTwoLeaf()->key();
|
auto key = CreateTwoLeaf()->key();
|
||||||
return treeStore.load(key);
|
return std::move(treeStore.load(key).get());
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataLeafNode> DataTreeTest::CreateLeafWithSize(uint32_t size) {
|
unique_ref<DataLeafNode> DataTreeTest::CreateLeafWithSize(uint32_t size) {
|
||||||
auto leaf = CreateLeaf();
|
auto leaf = CreateLeaf();
|
||||||
leaf->resize(size);
|
leaf->resize(size);
|
||||||
return leaf;
|
return leaf;
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataTreeTest::CreateTwoLeafWithSecondLeafSize(uint32_t size) {
|
unique_ref<DataInnerNode> DataTreeTest::CreateTwoLeafWithSecondLeafSize(uint32_t size) {
|
||||||
return CreateInner({
|
return CreateInner({
|
||||||
CreateLeafWithSize(nodeStore->layout().maxBytesPerLeaf()),
|
CreateLeafWithSize(nodeStore->layout().maxBytesPerLeaf()),
|
||||||
CreateLeafWithSize(size)
|
CreateLeafWithSize(size)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataTreeTest::CreateFullTwoLevelWithLastLeafSize(uint32_t size) {
|
unique_ref<DataInnerNode> DataTreeTest::CreateFullTwoLevelWithLastLeafSize(uint32_t size) {
|
||||||
auto root = CreateFullTwoLevel();
|
auto root = CreateFullTwoLevel();
|
||||||
for (uint32_t i = 0; i < root->numChildren()-1; ++i) {
|
for (uint32_t i = 0; i < root->numChildren()-1; ++i) {
|
||||||
LoadLeafNode(root->getChild(i)->key())->resize(nodeStore->layout().maxBytesPerLeaf());
|
LoadLeafNode(root->getChild(i)->key())->resize(nodeStore->layout().maxBytesPerLeaf());
|
||||||
@ -135,7 +137,7 @@ unique_ptr<DataInnerNode> DataTreeTest::CreateFullTwoLevelWithLastLeafSize(uint3
|
|||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataTreeTest::CreateThreeLevelWithOneChildAndLastLeafSize(uint32_t size) {
|
unique_ref<DataInnerNode> DataTreeTest::CreateThreeLevelWithOneChildAndLastLeafSize(uint32_t size) {
|
||||||
return CreateInner({
|
return CreateInner({
|
||||||
CreateInner({
|
CreateInner({
|
||||||
CreateLeafWithSize(nodeStore->layout().maxBytesPerLeaf()),
|
CreateLeafWithSize(nodeStore->layout().maxBytesPerLeaf()),
|
||||||
@ -144,7 +146,7 @@ unique_ptr<DataInnerNode> DataTreeTest::CreateThreeLevelWithOneChildAndLastLeafS
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataTreeTest::CreateThreeLevelWithTwoChildrenAndLastLeafSize(uint32_t size) {
|
unique_ref<DataInnerNode> DataTreeTest::CreateThreeLevelWithTwoChildrenAndLastLeafSize(uint32_t size) {
|
||||||
return CreateInner({
|
return CreateInner({
|
||||||
CreateFullTwoLevelWithLastLeafSize(nodeStore->layout().maxBytesPerLeaf()),
|
CreateFullTwoLevelWithLastLeafSize(nodeStore->layout().maxBytesPerLeaf()),
|
||||||
CreateInner({
|
CreateInner({
|
||||||
@ -154,7 +156,7 @@ unique_ptr<DataInnerNode> DataTreeTest::CreateThreeLevelWithTwoChildrenAndLastLe
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataTreeTest::CreateThreeLevelWithThreeChildrenAndLastLeafSize(uint32_t size) {
|
unique_ref<DataInnerNode> DataTreeTest::CreateThreeLevelWithThreeChildrenAndLastLeafSize(uint32_t size) {
|
||||||
return CreateInner({
|
return CreateInner({
|
||||||
CreateFullTwoLevelWithLastLeafSize(nodeStore->layout().maxBytesPerLeaf()),
|
CreateFullTwoLevelWithLastLeafSize(nodeStore->layout().maxBytesPerLeaf()),
|
||||||
CreateFullTwoLevelWithLastLeafSize(nodeStore->layout().maxBytesPerLeaf()),
|
CreateFullTwoLevelWithLastLeafSize(nodeStore->layout().maxBytesPerLeaf()),
|
||||||
@ -165,7 +167,7 @@ unique_ptr<DataInnerNode> DataTreeTest::CreateThreeLevelWithThreeChildrenAndLast
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataTreeTest::CreateFullThreeLevelWithLastLeafSize(uint32_t size) {
|
unique_ref<DataInnerNode> DataTreeTest::CreateFullThreeLevelWithLastLeafSize(uint32_t size) {
|
||||||
auto root = CreateFullThreeLevel();
|
auto root = CreateFullThreeLevel();
|
||||||
for (uint32_t i = 0; i < root->numChildren(); ++i) {
|
for (uint32_t i = 0; i < root->numChildren(); ++i) {
|
||||||
auto node = LoadInnerNode(root->getChild(i)->key());
|
auto node = LoadInnerNode(root->getChild(i)->key());
|
||||||
@ -177,7 +179,7 @@ unique_ptr<DataInnerNode> DataTreeTest::CreateFullThreeLevelWithLastLeafSize(uin
|
|||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> DataTreeTest::CreateFourLevelMinDataWithLastLeafSize(uint32_t size) {
|
unique_ref<DataInnerNode> DataTreeTest::CreateFourLevelMinDataWithLastLeafSize(uint32_t size) {
|
||||||
return CreateInner({
|
return CreateInner({
|
||||||
CreateFullThreeLevelWithLastLeafSize(nodeStore->layout().maxBytesPerLeaf()),
|
CreateFullThreeLevelWithLastLeafSize(nodeStore->layout().maxBytesPerLeaf()),
|
||||||
CreateInner({CreateInner({CreateLeafWithSize(size)})})
|
CreateInner({CreateInner({CreateLeafWithSize(size)})})
|
||||||
|
@ -16,35 +16,35 @@ public:
|
|||||||
|
|
||||||
static constexpr uint32_t BLOCKSIZE_BYTES = 256;
|
static constexpr uint32_t BLOCKSIZE_BYTES = 256;
|
||||||
|
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataLeafNode> CreateLeaf();
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataLeafNode> CreateLeaf();
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateInner(std::vector<const blobstore::onblocks::datanodestore::DataNode *> children);
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateInner(std::vector<const blobstore::onblocks::datanodestore::DataNode *> children);
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateInner(std::initializer_list<const blobstore::onblocks::datanodestore::DataNode *> children);
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateInner(std::initializer_list<const blobstore::onblocks::datanodestore::DataNode *> children);
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateInner(std::initializer_list<std::unique_ptr<blobstore::onblocks::datanodestore::DataNode>> children);
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateInner(std::initializer_list<cpputils::unique_ref<blobstore::onblocks::datanodestore::DataNode>> children);
|
||||||
|
|
||||||
std::unique_ptr<blobstore::onblocks::datatreestore::DataTree> CreateLeafOnlyTree();
|
cpputils::unique_ref<blobstore::onblocks::datatreestore::DataTree> CreateLeafOnlyTree();
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateTwoLeaf();
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateTwoLeaf();
|
||||||
std::unique_ptr<blobstore::onblocks::datatreestore::DataTree> CreateTwoLeafTree();
|
cpputils::unique_ref<blobstore::onblocks::datatreestore::DataTree> CreateTwoLeafTree();
|
||||||
void FillNode(blobstore::onblocks::datanodestore::DataInnerNode *node);
|
void FillNode(blobstore::onblocks::datanodestore::DataInnerNode *node);
|
||||||
void FillNodeTwoLevel(blobstore::onblocks::datanodestore::DataInnerNode *node);
|
void FillNodeTwoLevel(blobstore::onblocks::datanodestore::DataInnerNode *node);
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullTwoLevel();
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullTwoLevel();
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullThreeLevel();
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullThreeLevel();
|
||||||
|
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelMinData();
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelMinData();
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateFourLevelMinData();
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateFourLevelMinData();
|
||||||
|
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> LoadInnerNode(const blockstore::Key &key);
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> LoadInnerNode(const blockstore::Key &key);
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataLeafNode> LoadLeafNode(const blockstore::Key &key);
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataLeafNode> LoadLeafNode(const blockstore::Key &key);
|
||||||
|
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataLeafNode> CreateLeafWithSize(uint32_t size);
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataLeafNode> CreateLeafWithSize(uint32_t size);
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateTwoLeafWithSecondLeafSize(uint32_t size);
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateTwoLeafWithSecondLeafSize(uint32_t size);
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullTwoLevelWithLastLeafSize(uint32_t size);
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullTwoLevelWithLastLeafSize(uint32_t size);
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelWithOneChildAndLastLeafSize(uint32_t size);
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelWithOneChildAndLastLeafSize(uint32_t size);
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelWithTwoChildrenAndLastLeafSize(uint32_t size);
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelWithTwoChildrenAndLastLeafSize(uint32_t size);
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelWithThreeChildrenAndLastLeafSize(uint32_t size);
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelWithThreeChildrenAndLastLeafSize(uint32_t size);
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullThreeLevelWithLastLeafSize(uint32_t size);
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullThreeLevelWithLastLeafSize(uint32_t size);
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateFourLevelMinDataWithLastLeafSize(uint32_t size);
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateFourLevelMinDataWithLastLeafSize(uint32_t size);
|
||||||
|
|
||||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataNodeStore> _nodeStore;
|
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataNodeStore> _nodeStore;
|
||||||
blobstore::onblocks::datanodestore::DataNodeStore *nodeStore;
|
blobstore::onblocks::datanodestore::DataNodeStore *nodeStore;
|
||||||
blobstore::onblocks::datatreestore::DataTreeStore treeStore;
|
blobstore::onblocks::datatreestore::DataTreeStore treeStore;
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ private:
|
|||||||
auto inner = dynamic_cast<blobstore::onblocks::datanodestore::DataInnerNode*>(node);
|
auto inner = dynamic_cast<blobstore::onblocks::datanodestore::DataInnerNode*>(node);
|
||||||
int leafIndex = firstLeafIndex;
|
int leafIndex = firstLeafIndex;
|
||||||
for (uint32_t i = 0; i < inner->numChildren(); ++i) {
|
for (uint32_t i = 0; i < inner->numChildren(); ++i) {
|
||||||
auto child = _dataNodeStore->load(inner->getChild(i)->key());
|
auto child = std::move(_dataNodeStore->load(inner->getChild(i)->key()).get());
|
||||||
leafIndex = ForEachLeaf(child.get(), leafIndex, endLeafIndex, action);
|
leafIndex = ForEachLeaf(child.get(), leafIndex, endLeafIndex, action);
|
||||||
}
|
}
|
||||||
return leafIndex;
|
return leafIndex;
|
||||||
|
@ -3,14 +3,12 @@
|
|||||||
#include <messmer/blockstore/implementations/testfake/FakeBlockStore.h>
|
#include <messmer/blockstore/implementations/testfake/FakeBlockStore.h>
|
||||||
#include "../../../../implementations/onblocks/BlobStoreOnBlocks.h"
|
#include "../../../../implementations/onblocks/BlobStoreOnBlocks.h"
|
||||||
|
|
||||||
using std::make_unique;
|
|
||||||
using std::unique_ptr;
|
|
||||||
|
|
||||||
using blobstore::onblocks::BlobStoreOnBlocks;
|
using blobstore::onblocks::BlobStoreOnBlocks;
|
||||||
using blockstore::testfake::FakeBlockStore;
|
using blockstore::testfake::FakeBlockStore;
|
||||||
|
using cpputils::make_unique_ref;
|
||||||
|
|
||||||
constexpr uint32_t BlobStoreTest::BLOCKSIZE_BYTES;
|
constexpr uint32_t BlobStoreTest::BLOCKSIZE_BYTES;
|
||||||
|
|
||||||
BlobStoreTest::BlobStoreTest()
|
BlobStoreTest::BlobStoreTest()
|
||||||
: blobStore(make_unique<BlobStoreOnBlocks>(make_unique<FakeBlockStore>(), BLOCKSIZE_BYTES)) {
|
: blobStore(make_unique_ref<BlobStoreOnBlocks>(make_unique_ref<FakeBlockStore>(), BLOCKSIZE_BYTES)) {
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ public:
|
|||||||
|
|
||||||
static constexpr uint32_t BLOCKSIZE_BYTES = 4096;
|
static constexpr uint32_t BLOCKSIZE_BYTES = 4096;
|
||||||
|
|
||||||
std::unique_ptr<blobstore::BlobStore> blobStore;
|
cpputils::unique_ref<blobstore::BlobStore> blobStore;
|
||||||
|
|
||||||
cpputils::unique_ref<blobstore::Blob> loadBlob(const blockstore::Key &key) {
|
cpputils::unique_ref<blobstore::Blob> loadBlob(const blockstore::Key &key) {
|
||||||
auto loaded = blobStore->load(key);
|
auto loaded = blobStore->load(key);
|
||||||
|
Loading…
Reference in New Issue
Block a user