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 <cmath>
|
||||
|
||||
using std::unique_ptr;
|
||||
using std::function;
|
||||
using cpputils::unique_ref;
|
||||
using blobstore::onblocks::datanodestore::DataLeafNode;
|
||||
using blobstore::onblocks::datanodestore::DataNodeLayout;
|
||||
using blockstore::Key;
|
||||
@ -16,7 +16,7 @@ namespace onblocks {
|
||||
|
||||
using parallelaccessdatatreestore::DataTreeRef;
|
||||
|
||||
BlobOnBlocks::BlobOnBlocks(unique_ptr<DataTreeRef> datatree)
|
||||
BlobOnBlocks::BlobOnBlocks(unique_ref<DataTreeRef> datatree)
|
||||
: _datatree(std::move(datatree)) {
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ Key BlobOnBlocks::key() const {
|
||||
return _datatree->key();
|
||||
}
|
||||
|
||||
unique_ptr<DataTreeRef> BlobOnBlocks::releaseTree() {
|
||||
unique_ref<DataTreeRef> BlobOnBlocks::releaseTree() {
|
||||
return std::move(_datatree);
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ class DataTreeRef;
|
||||
|
||||
class BlobOnBlocks: public Blob {
|
||||
public:
|
||||
BlobOnBlocks(std::unique_ptr<parallelaccessdatatreestore::DataTreeRef> datatree);
|
||||
BlobOnBlocks(cpputils::unique_ref<parallelaccessdatatreestore::DataTreeRef> datatree);
|
||||
virtual ~BlobOnBlocks();
|
||||
|
||||
blockstore::Key key() const override;
|
||||
@ -31,14 +31,14 @@ public:
|
||||
|
||||
void flush() override;
|
||||
|
||||
std::unique_ptr<parallelaccessdatatreestore::DataTreeRef> releaseTree();
|
||||
cpputils::unique_ref<parallelaccessdatatreestore::DataTreeRef> releaseTree();
|
||||
|
||||
private:
|
||||
|
||||
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);
|
||||
|
||||
std::unique_ptr<parallelaccessdatatreestore::DataTreeRef> _datatree;
|
||||
cpputils::unique_ref<parallelaccessdatatreestore::DataTreeRef> _datatree;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -9,9 +9,6 @@
|
||||
#include "BlobOnBlocks.h"
|
||||
#include <messmer/cpp-utils/pointer/cast.h>
|
||||
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
|
||||
using cpputils::unique_ref;
|
||||
using cpputils::make_unique_ref;
|
||||
|
||||
@ -29,8 +26,8 @@ using datanodestore::DataNodeStore;
|
||||
using datatreestore::DataTreeStore;
|
||||
using parallelaccessdatatreestore::ParallelAccessDataTreeStore;
|
||||
|
||||
BlobStoreOnBlocks::BlobStoreOnBlocks(unique_ptr<BlockStore> blockStore, uint32_t blocksizeBytes)
|
||||
: _dataTreeStore(make_unique<ParallelAccessDataTreeStore>(make_unique<DataTreeStore>(make_unique<DataNodeStore>(make_unique<ParallelAccessBlockStore>(std::move(blockStore)), blocksizeBytes)))) {
|
||||
BlobStoreOnBlocks::BlobStoreOnBlocks(unique_ref<BlockStore> blockStore, uint32_t blocksizeBytes)
|
||||
: _dataTreeStore(make_unique_ref<ParallelAccessDataTreeStore>(make_unique_ref<DataTreeStore>(make_unique_ref<DataNodeStore>(make_unique_ref<ParallelAccessBlockStore>(std::move(blockStore)), blocksizeBytes)))) {
|
||||
}
|
||||
|
||||
BlobStoreOnBlocks::~BlobStoreOnBlocks() {
|
||||
@ -42,10 +39,10 @@ unique_ref<Blob> BlobStoreOnBlocks::create() {
|
||||
|
||||
optional<unique_ref<Blob>> BlobStoreOnBlocks::load(const Key &key) {
|
||||
auto tree = _dataTreeStore->load(key);
|
||||
if (tree == nullptr) {
|
||||
if (tree == 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) {
|
||||
|
@ -15,7 +15,7 @@ class ParallelAccessDataTreeStore;
|
||||
|
||||
class BlobStoreOnBlocks: public BlobStore {
|
||||
public:
|
||||
BlobStoreOnBlocks(std::unique_ptr<blockstore::BlockStore> blockStore, uint32_t blocksizeBytes);
|
||||
BlobStoreOnBlocks(cpputils::unique_ref<blockstore::BlockStore> blockStore, uint32_t blocksizeBytes);
|
||||
virtual ~BlobStoreOnBlocks();
|
||||
|
||||
cpputils::unique_ref<Blob> create() override;
|
||||
@ -24,7 +24,7 @@ public:
|
||||
void remove(cpputils::unique_ref<Blob> blob) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<parallelaccessdatatreestore::ParallelAccessDataTreeStore> _dataTreeStore;
|
||||
cpputils::unique_ref<parallelaccessdatatreestore::ParallelAccessDataTreeStore> _dataTreeStore;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -2,9 +2,10 @@
|
||||
#include "DataNodeStore.h"
|
||||
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
using blockstore::Block;
|
||||
using cpputils::Data;
|
||||
using cpputils::unique_ref;
|
||||
using cpputils::make_unique_ref;
|
||||
using blockstore::Key;
|
||||
|
||||
namespace blobstore {
|
||||
@ -19,11 +20,11 @@ DataInnerNode::DataInnerNode(DataNodeView view)
|
||||
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));
|
||||
node.setDepth(first_child.depth() + 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());
|
||||
return result;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ namespace datanodestore {
|
||||
|
||||
class DataInnerNode: public DataNode {
|
||||
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);
|
||||
virtual ~DataInnerNode();
|
||||
|
@ -2,10 +2,11 @@
|
||||
#include "DataInnerNode.h"
|
||||
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
using blockstore::Block;
|
||||
using cpputils::Data;
|
||||
using blockstore::Key;
|
||||
using cpputils::unique_ref;
|
||||
using cpputils::make_unique_ref;
|
||||
|
||||
namespace blobstore {
|
||||
namespace onblocks {
|
||||
@ -20,12 +21,12 @@ DataLeafNode::DataLeafNode(DataNodeView view)
|
||||
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));
|
||||
node.setDepth(0);
|
||||
node.setSize(0);
|
||||
//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 {
|
||||
|
@ -11,7 +11,7 @@ class DataInnerNode;
|
||||
|
||||
class DataLeafNode: public DataNode {
|
||||
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);
|
||||
virtual ~DataLeafNode();
|
||||
|
@ -7,9 +7,8 @@
|
||||
using blockstore::Block;
|
||||
using blockstore::Key;
|
||||
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
using std::runtime_error;
|
||||
using cpputils::unique_ref;
|
||||
|
||||
namespace blobstore {
|
||||
namespace onblocks {
|
||||
@ -38,7 +37,7 @@ uint8_t DataNode::depth() const {
|
||||
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();
|
||||
auto block = node->_node.releaseBlock();
|
||||
blockstore::utils::fillWithZeroes(block.get());
|
||||
|
@ -19,7 +19,7 @@ public:
|
||||
|
||||
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;
|
||||
|
||||
|
@ -10,76 +10,81 @@ using blockstore::BlockStore;
|
||||
using blockstore::Block;
|
||||
using blockstore::Key;
|
||||
using cpputils::Data;
|
||||
using cpputils::unique_ref;
|
||||
using cpputils::make_unique_ref;
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
using std::runtime_error;
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
|
||||
namespace blobstore {
|
||||
namespace onblocks {
|
||||
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) {
|
||||
}
|
||||
|
||||
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());
|
||||
DataNodeView node(std::move(block));
|
||||
|
||||
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) {
|
||||
return unique_ptr<DataInnerNode>(new DataInnerNode(std::move(node)));
|
||||
return make_unique_ref<DataInnerNode>(std::move(node));
|
||||
} else {
|
||||
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
|
||||
//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());
|
||||
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
|
||||
auto block = _blockstore->create(Data(_layout.blocksizeBytes()).FillWithZeroes());
|
||||
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);
|
||||
if (block == nullptr) {
|
||||
return nullptr;
|
||||
return none;
|
||||
}
|
||||
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
|
||||
auto newBlock = blockstore::utils::copyToNewBlock(_blockstore.get(), source.node().block());
|
||||
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(source.node().layout().blocksizeBytes() == _layout.blocksizeBytes());
|
||||
Key key = target->key();
|
||||
{
|
||||
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());
|
||||
}
|
||||
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();
|
||||
node.reset();
|
||||
cpputils::to_unique_ptr(std::move(node)).reset(); // Call destructor
|
||||
_blockstore->remove(std::move(block));
|
||||
}
|
||||
|
||||
@ -87,12 +92,13 @@ uint64_t DataNodeStore::numNodes() const {
|
||||
return _blockstore->numBlocks();
|
||||
}
|
||||
|
||||
void DataNodeStore::removeSubtree(unique_ptr<DataNode> node) {
|
||||
void DataNodeStore::removeSubtree(unique_ref<DataNode> node) {
|
||||
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(node.get());
|
||||
if (inner != nullptr) {
|
||||
for (uint32_t i = 0; i < inner->numChildren(); ++i) {
|
||||
auto child = load(inner->getChild(i)->key());
|
||||
removeSubtree(std::move(child));
|
||||
assert(child != none);
|
||||
removeSubtree(std::move(*child));
|
||||
}
|
||||
}
|
||||
remove(std::move(node));
|
||||
|
@ -21,33 +21,33 @@ class DataInnerNode;
|
||||
|
||||
class DataNodeStore {
|
||||
public:
|
||||
DataNodeStore(std::unique_ptr<blockstore::BlockStore> blockstore, uint32_t blocksizeBytes);
|
||||
DataNodeStore(cpputils::unique_ref<blockstore::BlockStore> blockstore, uint32_t blocksizeBytes);
|
||||
virtual ~DataNodeStore();
|
||||
|
||||
static constexpr uint8_t MAX_DEPTH = 10;
|
||||
|
||||
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();
|
||||
std::unique_ptr<DataInnerNode> createNewInnerNode(const DataNode &first_child);
|
||||
cpputils::unique_ref<DataLeafNode> createNewLeafNode();
|
||||
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;
|
||||
//TODO Test overwriteNodeWith(), createNodeAsCopyFrom(), removeSubtree()
|
||||
|
||||
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;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DataNodeStore);
|
||||
|
@ -18,24 +18,25 @@ using blobstore::onblocks::datanodestore::DataInnerNode;
|
||||
using blobstore::onblocks::datanodestore::DataLeafNode;
|
||||
using blobstore::onblocks::datanodestore::DataNodeLayout;
|
||||
|
||||
using std::unique_ptr;
|
||||
using std::dynamic_pointer_cast;
|
||||
using std::function;
|
||||
using boost::shared_mutex;
|
||||
using boost::shared_lock;
|
||||
using boost::unique_lock;
|
||||
using boost::none;
|
||||
using std::vector;
|
||||
|
||||
using cpputils::dynamic_pointer_move;
|
||||
using cpputils::optional_ownership_ptr;
|
||||
using cpputils::WithOwnership;
|
||||
using cpputils::WithoutOwnership;
|
||||
using cpputils::unique_ref;
|
||||
|
||||
namespace blobstore {
|
||||
namespace onblocks {
|
||||
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)) {
|
||||
}
|
||||
|
||||
@ -56,18 +57,20 @@ void DataTree::ifRootHasOnlyOneChildReplaceRootWithItsChild() {
|
||||
assert(rootNode != nullptr);
|
||||
if (rootNode->numChildren() == 1) {
|
||||
auto child = _nodeStore->load(rootNode->getChild(0)->key());
|
||||
_rootNode = _nodeStore->overwriteNodeWith(std::move(_rootNode), *child);
|
||||
_nodeStore->remove(std::move(child));
|
||||
assert(child != none);
|
||||
_rootNode = _nodeStore->overwriteNodeWith(std::move(_rootNode), **child);
|
||||
_nodeStore->remove(std::move(*child));
|
||||
}
|
||||
}
|
||||
|
||||
void DataTree::deleteLastChildSubtree(DataInnerNode *node) {
|
||||
auto lastChild = _nodeStore->load(node->LastChild()->key());
|
||||
_nodeStore->removeSubtree(std::move(lastChild));
|
||||
assert(lastChild != none);
|
||||
_nodeStore->removeSubtree(std::move(*lastChild));
|
||||
node->removeLastChild();
|
||||
}
|
||||
|
||||
unique_ptr<DataLeafNode> DataTree::addDataLeaf() {
|
||||
unique_ref<DataLeafNode> DataTree::addDataLeaf() {
|
||||
auto insertPosOrNull = algorithms::GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(_nodeStore, _rootNode.get());
|
||||
if (insertPosOrNull) {
|
||||
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 chain = createChainOfInnerNodes(insertPos->depth()-1, new_leaf.get());
|
||||
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) {
|
||||
//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);
|
||||
for(unsigned int i=0; i<num; ++i) {
|
||||
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;
|
||||
}
|
||||
|
||||
unique_ptr<DataNode> DataTree::createChainOfInnerNodes(unsigned int num, unique_ptr<DataNode> child) {
|
||||
unique_ptr<DataNode> chain = std::move(child);
|
||||
unique_ref<DataNode> DataTree::createChainOfInnerNodes(unsigned int num, unique_ref<DataNode> child) {
|
||||
unique_ref<DataNode> chain = std::move(child);
|
||||
for(unsigned int i=0; i<num; ++i) {
|
||||
chain = _nodeStore->createNewInnerNode(*chain);
|
||||
}
|
||||
@ -111,7 +115,7 @@ DataInnerNode* DataTree::increaseTreeDepth(unsigned int levels) {
|
||||
return result;
|
||||
}
|
||||
|
||||
unique_ptr<DataLeafNode> DataTree::addDataLeafToFullTree() {
|
||||
unique_ref<DataLeafNode> DataTree::addDataLeafToFullTree() {
|
||||
DataInnerNode *rootNode = increaseTreeDepth(1);
|
||||
auto newLeaf = addDataLeafAt(rootNode);
|
||||
return newLeaf;
|
||||
@ -125,7 +129,7 @@ void DataTree::flush() const {
|
||||
_rootNode->flush();
|
||||
}
|
||||
|
||||
unique_ptr<DataNode> DataTree::releaseRootNode() {
|
||||
unique_ref<DataNode> DataTree::releaseRootNode() {
|
||||
return std::move(_rootNode);
|
||||
}
|
||||
|
||||
@ -143,7 +147,8 @@ uint32_t DataTree::_numLeaves(const DataNode &node) const {
|
||||
const DataInnerNode &inner = dynamic_cast<const DataInnerNode&>(node);
|
||||
uint64_t numLeavesInLeftChildren = (inner.numChildren()-1) * leavesPerFullChild(inner);
|
||||
auto lastChild = _nodeStore->load(inner.LastChild()->key());
|
||||
uint64_t numLeavesInRightChild = _numLeaves(*lastChild);
|
||||
assert(lastChild != none);
|
||||
uint64_t numLeavesInRightChild = _numLeaves(**lastChild);
|
||||
|
||||
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 beginChild = beginIndex/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) {
|
||||
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_ptr<DataNode>> children;
|
||||
vector<unique_ref<DataNode>> DataTree::getOrCreateChildren(DataInnerNode *node, uint32_t begin, uint32_t end) {
|
||||
vector<unique_ref<DataNode>> children;
|
||||
children.reserve(end-begin);
|
||||
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) {
|
||||
children.emplace_back(addChildTo(node));
|
||||
@ -223,7 +230,7 @@ vector<unique_ptr<DataNode>> DataTree::getOrCreateChildren(DataInnerNode *node,
|
||||
return children;
|
||||
}
|
||||
|
||||
unique_ptr<DataNode> DataTree::addChildTo(DataInnerNode *node) {
|
||||
unique_ref<DataNode> DataTree::addChildTo(DataInnerNode *node) {
|
||||
auto new_leaf = _nodeStore->createNewLeafNode();
|
||||
new_leaf->resize(_nodeStore->layout().maxBytesPerLeaf());
|
||||
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);
|
||||
uint64_t numBytesInLeftChildren = (inner.numChildren()-1) * leavesPerFullChild(inner) * _nodeStore->layout().maxBytesPerLeaf();
|
||||
auto lastChild = _nodeStore->load(inner.LastChild()->key());
|
||||
uint64_t numBytesInRightChild = _numStoredBytes(*lastChild);
|
||||
assert(lastChild != none);
|
||||
uint64_t numBytesInRightChild = _numStoredBytes(**lastChild);
|
||||
|
||||
return numBytesInLeftChildren + numBytesInRightChild;
|
||||
}
|
||||
@ -288,16 +296,22 @@ optional_ownership_ptr<DataLeafNode> DataTree::LastLeaf(DataNode *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);
|
||||
if (leaf.get() != nullptr) {
|
||||
return leaf;
|
||||
if (leaf != none) {
|
||||
return std::move(*leaf);
|
||||
}
|
||||
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 {
|
||||
|
@ -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.
|
||||
class DataTree {
|
||||
public:
|
||||
DataTree(datanodestore::DataNodeStore *nodeStore, std::unique_ptr<datanodestore::DataNode> rootNode);
|
||||
DataTree(datanodestore::DataNodeStore *nodeStore, cpputils::unique_ref<datanodestore::DataNode> rootNode);
|
||||
virtual ~DataTree();
|
||||
|
||||
const blockstore::Key &key() const;
|
||||
@ -40,18 +40,18 @@ public:
|
||||
private:
|
||||
mutable boost::shared_mutex _mutex;
|
||||
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();
|
||||
|
||||
std::unique_ptr<datanodestore::DataNode> releaseRootNode();
|
||||
cpputils::unique_ref<datanodestore::DataNode> releaseRootNode();
|
||||
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);
|
||||
std::unique_ptr<datanodestore::DataNode> createChainOfInnerNodes(unsigned int num, std::unique_ptr<datanodestore::DataNode> child);
|
||||
std::unique_ptr<datanodestore::DataLeafNode> addDataLeafToFullTree();
|
||||
cpputils::unique_ref<datanodestore::DataNode> createChainOfInnerNodes(unsigned int num, cpputils::unique_ref<datanodestore::DataNode> child);
|
||||
cpputils::unique_ref<datanodestore::DataLeafNode> addDataLeafToFullTree();
|
||||
|
||||
void deleteLastChildSubtree(datanodestore::DataInnerNode *node);
|
||||
void ifRootHasOnlyOneChildReplaceRootWithItsChild();
|
||||
@ -63,10 +63,10 @@ private:
|
||||
uint64_t _numStoredBytes(const datanodestore::DataNode &root) const;
|
||||
uint32_t _numLeaves(const datanodestore::DataNode &node) const;
|
||||
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);
|
||||
std::vector<std::unique_ptr<datanodestore::DataNode>> getOrCreateChildren(datanodestore::DataInnerNode *node, uint32_t begin, uint32_t end);
|
||||
std::unique_ptr<datanodestore::DataNode> addChildTo(datanodestore::DataInnerNode *node);
|
||||
std::vector<cpputils::unique_ref<datanodestore::DataNode>> getOrCreateChildren(datanodestore::DataInnerNode *node, uint32_t begin, uint32_t end);
|
||||
cpputils::unique_ref<datanodestore::DataNode> addChildTo(datanodestore::DataInnerNode *node);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DataTree);
|
||||
};
|
||||
|
@ -4,7 +4,10 @@
|
||||
#include "DataTree.h"
|
||||
|
||||
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::DataNode;
|
||||
@ -13,30 +16,29 @@ namespace blobstore {
|
||||
namespace onblocks {
|
||||
namespace datatreestore {
|
||||
|
||||
DataTreeStore::DataTreeStore(unique_ptr<DataNodeStore> nodeStore)
|
||||
DataTreeStore::DataTreeStore(unique_ref<DataNodeStore> nodeStore)
|
||||
: _nodeStore(std::move(nodeStore)) {
|
||||
}
|
||||
|
||||
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);
|
||||
if (node.get() == nullptr) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return make_unique<DataTree>(_nodeStore.get(), std::move(node));
|
||||
if (node == none) {
|
||||
return none;
|
||||
}
|
||||
return make_unique_ref<DataTree>(_nodeStore.get(), std::move(*node));
|
||||
}
|
||||
|
||||
unique_ptr<DataTree> DataTreeStore::createNewTree() {
|
||||
unique_ptr<DataNode> newleaf = _nodeStore->createNewLeafNode();
|
||||
return make_unique<DataTree>(_nodeStore.get(), std::move(newleaf));
|
||||
unique_ref<DataTree> DataTreeStore::createNewTree() {
|
||||
auto newleaf = _nodeStore->createNewLeafNode();
|
||||
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();
|
||||
tree.reset();
|
||||
to_unique_ptr(std::move(tree)).reset(); // Destruct tree
|
||||
_nodeStore->removeSubtree(std::move(root));
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,9 @@
|
||||
|
||||
#include <memory>
|
||||
#include <messmer/cpp-utils/macros.h>
|
||||
#include <messmer/cpp-utils/pointer/unique_ref.h>
|
||||
#include <messmer/blockstore/utils/Key.h>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace blobstore {
|
||||
namespace onblocks {
|
||||
@ -16,17 +18,17 @@ class DataTree;
|
||||
|
||||
class DataTreeStore {
|
||||
public:
|
||||
DataTreeStore(std::unique_ptr<datanodestore::DataNodeStore> nodeStore);
|
||||
DataTreeStore(cpputils::unique_ref<datanodestore::DataNodeStore> nodeStore);
|
||||
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:
|
||||
std::unique_ptr<datanodestore::DataNodeStore> _nodeStore;
|
||||
cpputils::unique_ref<datanodestore::DataNodeStore> _nodeStore;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DataTreeStore);
|
||||
};
|
||||
|
@ -6,23 +6,26 @@
|
||||
#include "../../datanodestore/DataNodeStore.h"
|
||||
|
||||
using std::function;
|
||||
using std::unique_ptr;
|
||||
using cpputils::optional_ownership_ptr;
|
||||
using cpputils::dynamic_pointer_move;
|
||||
using cpputils::unique_ref;
|
||||
using blobstore::onblocks::datanodestore::DataInnerNode;
|
||||
using blobstore::onblocks::datanodestore::DataNode;
|
||||
using blobstore::onblocks::datanodestore::DataNodeStore;
|
||||
using blockstore::Key;
|
||||
using boost::optional;
|
||||
using boost::none;
|
||||
|
||||
namespace blobstore {
|
||||
namespace onblocks {
|
||||
namespace datatreestore {
|
||||
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();
|
||||
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).
|
||||
@ -31,11 +34,16 @@ optional_ownership_ptr<DataInnerNode> GetLowestInnerRightBorderNodeWithCondition
|
||||
optional_ownership_ptr<DataInnerNode> currentNode = cpputils::WithoutOwnership(dynamic_cast<DataInnerNode*>(rootNode));
|
||||
optional_ownership_ptr<DataInnerNode> result = cpputils::null<DataInnerNode>();
|
||||
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);
|
||||
if (condition(*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;
|
||||
|
@ -4,8 +4,9 @@
|
||||
#include "../datanodestore/DataNodeStore.h"
|
||||
#include "../datanodestore/DataLeafNode.h"
|
||||
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
using cpputils::unique_ref;
|
||||
using cpputils::make_unique_ref;
|
||||
using boost::optional;
|
||||
|
||||
using blobstore::onblocks::datatreestore::DataTreeStore;
|
||||
using blockstore::Key;
|
||||
@ -16,24 +17,24 @@ using datatreestore::DataTreeStore;
|
||||
using datatreestore::DataTree;
|
||||
namespace parallelaccessdatatreestore {
|
||||
|
||||
ParallelAccessDataTreeStore::ParallelAccessDataTreeStore(unique_ptr<DataTreeStore> dataTreeStore)
|
||||
: _dataTreeStore(std::move(dataTreeStore)), _parallelAccessStore(make_unique<ParallelAccessDataTreeStoreAdapter>(_dataTreeStore.get())) {
|
||||
ParallelAccessDataTreeStore::ParallelAccessDataTreeStore(unique_ref<DataTreeStore> dataTreeStore)
|
||||
: _dataTreeStore(std::move(dataTreeStore)), _parallelAccessStore(make_unique_ref<ParallelAccessDataTreeStoreAdapter>(_dataTreeStore.get())) {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
unique_ptr<DataTreeRef> ParallelAccessDataTreeStore::createNewTree() {
|
||||
unique_ref<DataTreeRef> ParallelAccessDataTreeStore::createNewTree() {
|
||||
auto dataTree = _dataTreeStore->createNewTree();
|
||||
Key key = dataTree->key();
|
||||
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();
|
||||
return _parallelAccessStore.remove(key, std::move(tree));
|
||||
}
|
||||
|
@ -20,17 +20,17 @@ class DataTreeRef;
|
||||
|
||||
class ParallelAccessDataTreeStore {
|
||||
public:
|
||||
ParallelAccessDataTreeStore(std::unique_ptr<datatreestore::DataTreeStore> dataTreeStore);
|
||||
ParallelAccessDataTreeStore(cpputils::unique_ref<datatreestore::DataTreeStore> dataTreeStore);
|
||||
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:
|
||||
std::unique_ptr<datatreestore::DataTreeStore> _dataTreeStore;
|
||||
cpputils::unique_ref<datatreestore::DataTreeStore> _dataTreeStore;
|
||||
parallelaccessstore::ParallelAccessStore<datatreestore::DataTree, DataTreeRef, blockstore::Key> _parallelAccessStore;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ParallelAccessDataTreeStore);
|
||||
|
@ -16,11 +16,11 @@ public:
|
||||
:_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);
|
||||
}
|
||||
|
||||
void removeFromBaseStore(std::unique_ptr<datatreestore::DataTree> dataTree) override {
|
||||
void removeFromBaseStore(cpputils::unique_ref<datatreestore::DataTree> dataTree) override {
|
||||
return _baseDataTreeStore->remove(std::move(dataTree));
|
||||
}
|
||||
|
||||
|
@ -22,17 +22,17 @@ using namespace blobstore;
|
||||
using namespace blobstore::onblocks;
|
||||
using namespace blobstore::onblocks::datanodestore;
|
||||
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
using cpputils::unique_ref;
|
||||
using cpputils::make_unique_ref;
|
||||
|
||||
class DataInnerNodeTest: public Test {
|
||||
public:
|
||||
static constexpr uint32_t BLOCKSIZE_BYTES = 1024;
|
||||
|
||||
DataInnerNodeTest() :
|
||||
_blockStore(make_unique<FakeBlockStore>()),
|
||||
_blockStore(make_unique_ref<FakeBlockStore>()),
|
||||
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()),
|
||||
leaf(nodeStore->createNewLeafNode()),
|
||||
node(nodeStore->createNewInnerNode(*leaf)) {
|
||||
@ -40,26 +40,26 @@ public:
|
||||
ZEROES.FillWithZeroes();
|
||||
}
|
||||
|
||||
unique_ptr<DataInnerNode> LoadInnerNode(const Key &key) {
|
||||
auto node = nodeStore->load(key);
|
||||
return dynamic_pointer_move<DataInnerNode>(node);
|
||||
unique_ref<DataInnerNode> LoadInnerNode(const Key &key) {
|
||||
auto node = std::move(nodeStore->load(key).get());
|
||||
return std::move(dynamic_pointer_move<DataInnerNode>(node).get());
|
||||
}
|
||||
|
||||
Key CreateNewInnerNodeReturnKey(const DataNode &firstChild) {
|
||||
return nodeStore->createNewInnerNode(firstChild)->key();
|
||||
}
|
||||
|
||||
unique_ptr<DataInnerNode> CreateNewInnerNode() {
|
||||
unique_ref<DataInnerNode> CreateNewInnerNode() {
|
||||
auto new_leaf = nodeStore->createNewLeafNode();
|
||||
return nodeStore->createNewInnerNode(*new_leaf);
|
||||
}
|
||||
|
||||
unique_ptr<DataInnerNode> CreateAndLoadNewInnerNode(const DataNode &firstChild) {
|
||||
unique_ref<DataInnerNode> CreateAndLoadNewInnerNode(const DataNode &firstChild) {
|
||||
auto key = CreateNewInnerNodeReturnKey(firstChild);
|
||||
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);
|
||||
node->addChild(secondChild);
|
||||
return node;
|
||||
@ -69,7 +69,7 @@ public:
|
||||
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);
|
||||
return LoadInnerNode(key);
|
||||
}
|
||||
@ -85,13 +85,13 @@ public:
|
||||
AddALeafTo(node.get());
|
||||
AddALeafTo(node.get());
|
||||
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();
|
||||
}
|
||||
|
||||
unique_ptr<DataInnerNode> CopyInnerNode(const DataInnerNode &node) {
|
||||
unique_ref<DataInnerNode> CopyInnerNode(const DataInnerNode &node) {
|
||||
auto copied = nodeStore->createNewNodeAsCopyFrom(node);
|
||||
return dynamic_pointer_move<DataInnerNode>(copied);
|
||||
return std::move(dynamic_pointer_move<DataInnerNode>(copied).get());
|
||||
}
|
||||
|
||||
Key InitializeInnerNodeAddLeafReturnKey() {
|
||||
@ -100,12 +100,12 @@ public:
|
||||
return node->key();
|
||||
}
|
||||
|
||||
unique_ptr<BlockStore> _blockStore;
|
||||
unique_ref<BlockStore> _blockStore;
|
||||
BlockStore *blockStore;
|
||||
unique_ptr<DataNodeStore> nodeStore;
|
||||
unique_ref<DataNodeStore> nodeStore;
|
||||
Data ZEROES;
|
||||
unique_ptr<DataLeafNode> leaf;
|
||||
unique_ptr<DataInnerNode> node;
|
||||
unique_ref<DataLeafNode> leaf;
|
||||
unique_ref<DataInnerNode> node;
|
||||
};
|
||||
|
||||
constexpr uint32_t DataInnerNodeTest::BLOCKSIZE_BYTES;
|
||||
@ -122,7 +122,7 @@ TEST_F(DataInnerNodeTest, CorrectKeyReturnedAfterLoading) {
|
||||
Key key = block->key();
|
||||
DataInnerNode::InitializeNewNode(std::move(block), *leaf);
|
||||
|
||||
auto loaded = nodeStore->load(key);
|
||||
auto loaded = std::move(nodeStore->load(key).get());
|
||||
EXPECT_EQ(key, loaded->key());
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ TEST_F(DataInnerNodeTest, BuildingAThreeLevelTreeAndReload) {
|
||||
TEST_F(DataInnerNodeTest, ConvertToInternalNode) {
|
||||
auto child = nodeStore->createNewLeafNode();
|
||||
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(child->key(), converted->getChild(0)->key());
|
||||
|
@ -14,8 +14,8 @@ using ::testing::Test;
|
||||
using ::testing::WithParamInterface;
|
||||
using ::testing::Values;
|
||||
using ::testing::Combine;
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
using cpputils::unique_ref;
|
||||
using cpputils::make_unique_ref;
|
||||
using std::string;
|
||||
using cpputils::DataFixture;
|
||||
|
||||
@ -40,9 +40,9 @@ public:
|
||||
static constexpr DataNodeLayout LAYOUT = DataNodeLayout(BLOCKSIZE_BYTES);
|
||||
|
||||
DataLeafNodeTest():
|
||||
_blockStore(make_unique<FakeBlockStore>()),
|
||||
_blockStore(make_unique_ref<FakeBlockStore>()),
|
||||
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()),
|
||||
randomData(nodeStore->layout().maxBytesPerLeaf()),
|
||||
leaf(nodeStore->createNewLeafNode()) {
|
||||
@ -76,9 +76,9 @@ public:
|
||||
leaf_to_fill->write(randomData.data(), 0, randomData.size());
|
||||
}
|
||||
|
||||
unique_ptr<DataLeafNode> LoadLeafNode(const Key &key) {
|
||||
auto leaf = nodeStore->load(key);
|
||||
return dynamic_pointer_move<DataLeafNode>(leaf);
|
||||
unique_ref<DataLeafNode> LoadLeafNode(const Key &key) {
|
||||
auto leaf = std::move(nodeStore->load(key).get());
|
||||
return std::move(dynamic_pointer_move<DataLeafNode>(leaf).get());
|
||||
}
|
||||
|
||||
void ResizeLeaf(const Key &key, size_t size) {
|
||||
@ -91,13 +91,13 @@ public:
|
||||
auto leaf = nodeStore->createNewLeafNode();
|
||||
FillLeafBlockWithData(leaf.get());
|
||||
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();
|
||||
}
|
||||
|
||||
unique_ptr<DataLeafNode> CopyLeafNode(const DataLeafNode &node) {
|
||||
unique_ref<DataLeafNode> CopyLeafNode(const DataLeafNode &node) {
|
||||
auto copied = nodeStore->createNewNodeAsCopyFrom(node);
|
||||
return dynamic_pointer_move<DataLeafNode>(copied);
|
||||
return std::move(dynamic_pointer_move<DataLeafNode>(copied).get());
|
||||
}
|
||||
|
||||
Key InitializeLeafGrowAndReturnKey() {
|
||||
@ -106,12 +106,12 @@ public:
|
||||
return leaf->key();
|
||||
}
|
||||
|
||||
unique_ptr<BlockStore> _blockStore;
|
||||
unique_ref<BlockStore> _blockStore;
|
||||
BlockStore *blockStore;
|
||||
unique_ptr<DataNodeStore> nodeStore;
|
||||
unique_ref<DataNodeStore> nodeStore;
|
||||
Data ZEROES;
|
||||
Data randomData;
|
||||
unique_ptr<DataLeafNode> leaf;
|
||||
unique_ref<DataLeafNode> leaf;
|
||||
};
|
||||
|
||||
constexpr uint32_t DataLeafNodeTest::BLOCKSIZE_BYTES;
|
||||
@ -129,7 +129,7 @@ TEST_F(DataLeafNodeTest, CorrectKeyReturnedAfterLoading) {
|
||||
Key key = block->key();
|
||||
DataLeafNode::InitializeNewNode(std::move(block));
|
||||
|
||||
auto loaded = nodeStore->load(key);
|
||||
auto loaded = std::move(nodeStore->load(key).get());
|
||||
EXPECT_EQ(key, loaded->key());
|
||||
}
|
||||
|
||||
@ -231,7 +231,7 @@ TEST_F(DataLeafNodeTest, ShrinkingDoesntDestroyValidDataRegion) {
|
||||
TEST_F(DataLeafNodeTest, ConvertToInternalNode) {
|
||||
auto child = nodeStore->createNewLeafNode();
|
||||
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(child->key(), converted->getChild(0)->key());
|
||||
|
@ -7,11 +7,13 @@
|
||||
|
||||
#include "messmer/blockstore/implementations/testfake/FakeBlockStore.h"
|
||||
#include "messmer/blockstore/implementations/testfake/FakeBlock.h"
|
||||
#include <messmer/cpp-utils/pointer/unique_ref_boost_optional_gtest_workaround.h>
|
||||
|
||||
using ::testing::Test;
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
using cpputils::unique_ref;
|
||||
using cpputils::make_unique_ref;
|
||||
using std::string;
|
||||
using boost::none;
|
||||
|
||||
using blockstore::BlockStore;
|
||||
using blockstore::testfake::FakeBlockStore;
|
||||
@ -25,9 +27,9 @@ class DataNodeStoreTest: public Test {
|
||||
public:
|
||||
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();
|
||||
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;
|
||||
@ -49,7 +51,7 @@ TEST_F(DataNodeStoreTest, CreateInnerNodeCreatesInnerNode) {
|
||||
TEST_F(DataNodeStoreTest, LeafNodeIsRecognizedAfterStoreAndLoad) {
|
||||
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());
|
||||
}
|
||||
@ -58,7 +60,7 @@ TEST_F(DataNodeStoreTest, InnerNodeWithDepth1IsRecognizedAfterStoreAndLoad) {
|
||||
auto leaf = nodeStore->createNewLeafNode();
|
||||
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());
|
||||
}
|
||||
@ -68,7 +70,7 @@ TEST_F(DataNodeStoreTest, InnerNodeWithDepth2IsRecognizedAfterStoreAndLoad) {
|
||||
auto inner = nodeStore->createNewInnerNode(*leaf);
|
||||
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());
|
||||
}
|
||||
@ -101,9 +103,9 @@ TEST_F(DataNodeStoreTest, CreatedLeafNodeIsInitialized) {
|
||||
TEST_F(DataNodeStoreTest, NodeIsNotLoadableAfterDeleting) {
|
||||
auto nodekey = nodeStore->createNewLeafNode()->key();
|
||||
auto node = nodeStore->load(nodekey);
|
||||
EXPECT_NE(nullptr, node.get());
|
||||
nodeStore->remove(std::move(node));
|
||||
EXPECT_EQ(nullptr, nodeStore->load(nodekey).get());
|
||||
EXPECT_NE(none, node);
|
||||
nodeStore->remove(std::move(*node));
|
||||
EXPECT_EQ(none, nodeStore->load(nodekey));
|
||||
}
|
||||
|
||||
TEST_F(DataNodeStoreTest, NumNodesIsCorrectOnEmptyNodestore) {
|
||||
|
@ -9,14 +9,14 @@
|
||||
using ::testing::Test;
|
||||
using ::testing::WithParamInterface;
|
||||
using ::testing::Values;
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
using std::string;
|
||||
|
||||
using blockstore::BlockStore;
|
||||
using blockstore::testfake::FakeBlockStore;
|
||||
using cpputils::Data;
|
||||
using cpputils::DataFixture;
|
||||
using cpputils::unique_ref;
|
||||
using cpputils::make_unique_ref;
|
||||
using namespace blobstore;
|
||||
using namespace blobstore::onblocks;
|
||||
using namespace blobstore::onblocks::datanodestore;
|
||||
@ -26,7 +26,7 @@ public:
|
||||
static constexpr uint32_t BLOCKSIZE_BYTES = 1024;
|
||||
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> {
|
||||
|
@ -3,11 +3,12 @@
|
||||
#include "../../../../implementations/onblocks/datanodestore/DataNodeStore.h"
|
||||
#include "../../../../implementations/onblocks/datatreestore/DataTreeStore.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::Key;
|
||||
using blobstore::onblocks::datanodestore::DataNodeStore;
|
||||
using std::make_unique;
|
||||
using boost::none;
|
||||
|
||||
using namespace blobstore::onblocks::datatreestore;
|
||||
|
||||
@ -16,14 +17,14 @@ class DataTreeStoreTest: public DataTreeTest {
|
||||
|
||||
TEST_F(DataTreeStoreTest, CorrectKeyReturned) {
|
||||
Key key = treeStore.createNewTree()->key();
|
||||
auto tree = treeStore.load(key);
|
||||
auto tree = std::move(treeStore.load(key).get());
|
||||
EXPECT_EQ(key, tree->key());
|
||||
}
|
||||
|
||||
TEST_F(DataTreeStoreTest, CreatedTreeIsLoadable) {
|
||||
auto key = treeStore.createNewTree()->key();
|
||||
auto loaded = treeStore.load(key);
|
||||
EXPECT_NE(nullptr, loaded.get());
|
||||
EXPECT_NE(none, loaded);
|
||||
}
|
||||
|
||||
TEST_F(DataTreeStoreTest, NewTreeIsLeafOnly) {
|
||||
@ -35,19 +36,19 @@ TEST_F(DataTreeStoreTest, NewTreeIsLeafOnly) {
|
||||
TEST_F(DataTreeStoreTest, TreeIsNotLoadableAfterRemove) {
|
||||
Key key = treeStore.createNewTree()->key();
|
||||
auto tree = treeStore.load(key);
|
||||
EXPECT_NE(nullptr, tree.get());
|
||||
treeStore.remove(std::move(tree));
|
||||
EXPECT_EQ(nullptr, treeStore.load(key).get());
|
||||
EXPECT_NE(none, tree);
|
||||
treeStore.remove(std::move(*tree));
|
||||
EXPECT_EQ(none, treeStore.load(key));
|
||||
}
|
||||
|
||||
TEST_F(DataTreeStoreTest, RemovingTreeRemovesAllNodesOfTheTree) {
|
||||
auto key = CreateThreeLevelMinData()->key();
|
||||
auto tree1 = treeStore.load(key);
|
||||
auto tree1 = std::move(treeStore.load(key).get());
|
||||
auto tree2_key = treeStore.createNewTree()->key();
|
||||
|
||||
treeStore.remove(std::move(tree1));
|
||||
|
||||
//Check that the only remaining node is tree2
|
||||
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 blockstore::Key;
|
||||
|
||||
using std::unique_ptr;
|
||||
|
||||
class DataTreeTest_NumStoredBytes: public DataTreeTest {
|
||||
public:
|
||||
};
|
||||
@ -30,48 +28,48 @@ INSTANTIATE_TEST_CASE_P(FullLastLeaf, DataTreeTest_NumStoredBytes_P, Values(Data
|
||||
|
||||
TEST_P(DataTreeTest_NumStoredBytes_P, SingleLeaf) {
|
||||
Key key = CreateLeafWithSize(GetParam())->key();
|
||||
auto tree = treeStore.load(key);
|
||||
auto tree = std::move(treeStore.load(key).get());
|
||||
EXPECT_EQ(GetParam(), tree->numStoredBytes());
|
||||
}
|
||||
|
||||
TEST_P(DataTreeTest_NumStoredBytes_P, TwoLeafTree) {
|
||||
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());
|
||||
}
|
||||
|
||||
TEST_P(DataTreeTest_NumStoredBytes_P, FullTwolevelTree) {
|
||||
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());
|
||||
}
|
||||
|
||||
TEST_P(DataTreeTest_NumStoredBytes_P, ThreeLevelTreeWithOneChild) {
|
||||
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());
|
||||
}
|
||||
|
||||
TEST_P(DataTreeTest_NumStoredBytes_P, ThreeLevelTreeWithTwoChildren) {
|
||||
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());
|
||||
}
|
||||
|
||||
TEST_P(DataTreeTest_NumStoredBytes_P, ThreeLevelTreeWithThreeChildren) {
|
||||
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());
|
||||
}
|
||||
|
||||
TEST_P(DataTreeTest_NumStoredBytes_P, FullThreeLevelTree) {
|
||||
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());
|
||||
}
|
||||
|
||||
TEST_P(DataTreeTest_NumStoredBytes_P, FourLevelMinDataTree) {
|
||||
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());
|
||||
}
|
||||
|
@ -22,49 +22,50 @@ using blobstore::onblocks::datatreestore::DataTree;
|
||||
using blobstore::onblocks::utils::ceilDivision;
|
||||
using blockstore::Key;
|
||||
using cpputils::Data;
|
||||
using boost::none;
|
||||
|
||||
using std::unique_ptr;
|
||||
using cpputils::unique_ref;
|
||||
|
||||
class DataTreeTest_ResizeByTraversing: public DataTreeTest {
|
||||
public:
|
||||
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();
|
||||
root.reset();
|
||||
return treeStore.load(key);
|
||||
cpputils::to_unique_ptr(std::move(root)).reset(); //Destruct
|
||||
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));
|
||||
}
|
||||
|
||||
unique_ptr<DataTree> CreateTwoLeafTreeWithSecondLeafSize(uint32_t size) {
|
||||
unique_ref<DataTree> CreateTwoLeafTreeWithSecondLeafSize(uint32_t size) {
|
||||
return CreateTree(CreateTwoLeafWithSecondLeafSize(size));
|
||||
}
|
||||
|
||||
unique_ptr<DataTree> CreateFullTwoLevelTreeWithLastLeafSize(uint32_t size) {
|
||||
unique_ref<DataTree> CreateFullTwoLevelTreeWithLastLeafSize(uint32_t size) {
|
||||
return CreateTree(CreateFullTwoLevelWithLastLeafSize(size));
|
||||
}
|
||||
|
||||
unique_ptr<DataTree> CreateThreeLevelTreeWithTwoChildrenAndLastLeafSize(uint32_t size) {
|
||||
unique_ref<DataTree> CreateThreeLevelTreeWithTwoChildrenAndLastLeafSize(uint32_t size) {
|
||||
return CreateTree(CreateThreeLevelWithTwoChildrenAndLastLeafSize(size));
|
||||
}
|
||||
|
||||
unique_ptr<DataTree> CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(uint32_t size) {
|
||||
unique_ref<DataTree> CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(uint32_t size) {
|
||||
return CreateTree(CreateThreeLevelWithThreeChildrenAndLastLeafSize(size));
|
||||
}
|
||||
|
||||
unique_ptr<DataTree> CreateFullThreeLevelTreeWithLastLeafSize(uint32_t size) {
|
||||
unique_ref<DataTree> CreateFullThreeLevelTreeWithLastLeafSize(uint32_t size) {
|
||||
return CreateTree(CreateFullThreeLevelWithLastLeafSize(size));
|
||||
}
|
||||
|
||||
unique_ptr<DataTree> CreateFourLevelMinDataTreeWithLastLeafSize(uint32_t size) {
|
||||
unique_ref<DataTree> CreateFourLevelMinDataTreeWithLastLeafSize(uint32_t size) {
|
||||
return CreateTree(CreateFourLevelMinDataWithLastLeafSize(size));
|
||||
}
|
||||
|
||||
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());
|
||||
if (inner != nullptr) {
|
||||
for (uint32_t i = 0; i < inner->numChildren()-1; ++i) {
|
||||
@ -75,7 +76,7 @@ public:
|
||||
}
|
||||
|
||||
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());
|
||||
if (inner != nullptr) {
|
||||
for (uint32_t i = 0; i < inner->numChildren(); ++i) {
|
||||
@ -89,7 +90,7 @@ public:
|
||||
};
|
||||
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:
|
||||
DataTreeTest_ResizeByTraversing_P()
|
||||
: oldLastLeafSize(get<1>(GetParam())),
|
||||
@ -103,7 +104,7 @@ public:
|
||||
|
||||
void GrowTree(const Key &key, uint32_t numLeavesToAdd) {
|
||||
auto tree = treeStore.load(key);
|
||||
GrowTree(tree.get(), numLeavesToAdd);
|
||||
GrowTree(tree.get().get(), numLeavesToAdd);
|
||||
}
|
||||
|
||||
void GrowTree(DataTree *tree, uint32_t numLeavesToAdd) {
|
||||
@ -114,18 +115,18 @@ public:
|
||||
tree->flush();
|
||||
}
|
||||
|
||||
unique_ptr<DataLeafNode> LastLeaf(const Key &key) {
|
||||
auto root = nodeStore->load(key);
|
||||
unique_ref<DataLeafNode> LastLeaf(const Key &key) {
|
||||
auto root = std::move(nodeStore->load(key).get());
|
||||
auto leaf = dynamic_pointer_move<DataLeafNode>(root);
|
||||
if (leaf.get() != nullptr) {
|
||||
return leaf;
|
||||
if (leaf != none) {
|
||||
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());
|
||||
}
|
||||
|
||||
uint32_t oldLastLeafSize;
|
||||
unique_ptr<DataTree> tree;
|
||||
unique_ref<DataTree> tree;
|
||||
uint32_t numberOfLeavesToAdd;
|
||||
uint32_t newNumberOfLeaves;
|
||||
Data ZEROES;
|
||||
@ -133,7 +134,7 @@ public:
|
||||
INSTANTIATE_TEST_CASE_P(DataTreeTest_ResizeByTraversing_P, DataTreeTest_ResizeByTraversing_P,
|
||||
Combine(
|
||||
//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::CreateTwoLeafTreeWithSecondLeafSize),
|
||||
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()));
|
||||
TwoLevelDataFixture data(nodeStore, TwoLevelDataFixture::SizePolicy::Unchanged);
|
||||
Key key = tree->key();
|
||||
tree.reset();
|
||||
data.FillInto(nodeStore->load(key).get());
|
||||
cpputils::to_unique_ptr(std::move(tree)).reset(); // Call destructor
|
||||
data.FillInto(nodeStore->load(key).get().get());
|
||||
|
||||
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 blockstore::Key;
|
||||
using cpputils::Data;
|
||||
using boost::none;
|
||||
|
||||
using std::unique_ptr;
|
||||
using cpputils::unique_ref;
|
||||
|
||||
class DataTreeTest_ResizeNumBytes: public DataTreeTest {
|
||||
public:
|
||||
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();
|
||||
root.reset();
|
||||
return treeStore.load(key);
|
||||
cpputils::to_unique_ptr(std::move(root)).reset(); // Destruct
|
||||
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));
|
||||
}
|
||||
|
||||
unique_ptr<DataTree> CreateTwoLeafTreeWithSecondLeafSize(uint32_t size) {
|
||||
unique_ref<DataTree> CreateTwoLeafTreeWithSecondLeafSize(uint32_t size) {
|
||||
return CreateTree(CreateTwoLeafWithSecondLeafSize(size));
|
||||
}
|
||||
|
||||
unique_ptr<DataTree> CreateFullTwoLevelTreeWithLastLeafSize(uint32_t size) {
|
||||
unique_ref<DataTree> CreateFullTwoLevelTreeWithLastLeafSize(uint32_t size) {
|
||||
return CreateTree(CreateFullTwoLevelWithLastLeafSize(size));
|
||||
}
|
||||
|
||||
unique_ptr<DataTree> CreateThreeLevelTreeWithTwoChildrenAndLastLeafSize(uint32_t size) {
|
||||
unique_ref<DataTree> CreateThreeLevelTreeWithTwoChildrenAndLastLeafSize(uint32_t size) {
|
||||
return CreateTree(CreateThreeLevelWithTwoChildrenAndLastLeafSize(size));
|
||||
}
|
||||
|
||||
unique_ptr<DataTree> CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(uint32_t size) {
|
||||
unique_ref<DataTree> CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(uint32_t size) {
|
||||
return CreateTree(CreateThreeLevelWithThreeChildrenAndLastLeafSize(size));
|
||||
}
|
||||
|
||||
unique_ptr<DataTree> CreateFullThreeLevelTreeWithLastLeafSize(uint32_t size) {
|
||||
unique_ref<DataTree> CreateFullThreeLevelTreeWithLastLeafSize(uint32_t size) {
|
||||
return CreateTree(CreateFullThreeLevelWithLastLeafSize(size));
|
||||
}
|
||||
|
||||
unique_ptr<DataTree> CreateFourLevelMinDataTreeWithLastLeafSize(uint32_t size) {
|
||||
unique_ref<DataTree> CreateFourLevelMinDataTreeWithLastLeafSize(uint32_t size) {
|
||||
return CreateTree(CreateFourLevelMinDataWithLastLeafSize(size));
|
||||
}
|
||||
|
||||
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());
|
||||
if (inner != nullptr) {
|
||||
for (uint32_t i = 0; i < inner->numChildren()-1; ++i) {
|
||||
@ -75,7 +76,7 @@ public:
|
||||
}
|
||||
|
||||
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());
|
||||
if (inner != nullptr) {
|
||||
for (uint32_t i = 0; i < inner->numChildren(); ++i) {
|
||||
@ -89,7 +90,7 @@ public:
|
||||
};
|
||||
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:
|
||||
DataTreeTest_ResizeNumBytes_P()
|
||||
: oldLastLeafSize(get<1>(GetParam())),
|
||||
@ -103,21 +104,21 @@ public:
|
||||
}
|
||||
|
||||
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) {
|
||||
auto root = nodeStore->load(key);
|
||||
unique_ref<DataLeafNode> LastLeaf(const Key &key) {
|
||||
auto root = std::move(nodeStore->load(key).get());
|
||||
auto leaf = dynamic_pointer_move<DataLeafNode>(root);
|
||||
if (leaf.get() != nullptr) {
|
||||
return leaf;
|
||||
if (leaf != none) {
|
||||
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());
|
||||
}
|
||||
|
||||
uint32_t oldLastLeafSize;
|
||||
unique_ptr<DataTree> tree;
|
||||
unique_ref<DataTree> tree;
|
||||
uint32_t newNumberOfLeaves;
|
||||
uint32_t newLastLeafSize;
|
||||
uint64_t newSize;
|
||||
@ -126,7 +127,7 @@ public:
|
||||
INSTANTIATE_TEST_CASE_P(DataTreeTest_ResizeNumBytes_P, DataTreeTest_ResizeNumBytes_P,
|
||||
Combine(
|
||||
//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::CreateTwoLeafTreeWithSecondLeafSize),
|
||||
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()));
|
||||
TwoLevelDataFixture data(nodeStore, TwoLevelDataFixture::SizePolicy::Unchanged);
|
||||
Key key = tree->key();
|
||||
tree.reset();
|
||||
data.FillInto(nodeStore->load(key).get());
|
||||
cpputils::to_unique_ptr(std::move(tree)).reset(); // Call destructor
|
||||
data.FillInto(nodeStore->load(key).get().get());
|
||||
|
||||
ResizeTree(key, newSize);
|
||||
|
||||
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 {
|
||||
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);
|
||||
tree->resizeNumBytes(0);
|
||||
Key key = tree->key();
|
||||
tree.reset();
|
||||
cpputils::to_unique_ptr(std::move(tree)).reset(); // Call destructor
|
||||
auto leaf = LoadLeafNode(key);
|
||||
EXPECT_EQ(0u, leaf->numBytes());
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ using blobstore::onblocks::datanodestore::DataNode;
|
||||
using blobstore::onblocks::datatreestore::DataTree;
|
||||
using blockstore::Key;
|
||||
|
||||
using std::unique_ptr;
|
||||
using cpputils::unique_ref;
|
||||
|
||||
class TraversorMock {
|
||||
public:
|
||||
@ -22,7 +22,7 @@ MATCHER_P(KeyEq, expected, "node key equals") {
|
||||
|
||||
class DataTreeTest_TraverseLeaves: public DataTreeTest {
|
||||
public:
|
||||
unique_ptr<DataInnerNode> CreateThreeLevel() {
|
||||
unique_ref<DataInnerNode> CreateThreeLevel() {
|
||||
return CreateInner({
|
||||
CreateFullTwoLevel(),
|
||||
CreateFullTwoLevel(),
|
||||
@ -32,7 +32,7 @@ public:
|
||||
CreateInner({CreateLeaf(), CreateLeaf(), CreateLeaf()})});
|
||||
}
|
||||
|
||||
unique_ptr<DataInnerNode> CreateFourLevel() {
|
||||
unique_ref<DataInnerNode> CreateFourLevel() {
|
||||
return CreateInner({
|
||||
CreateFullThreeLevel(),
|
||||
CreateFullThreeLevel(),
|
||||
@ -56,7 +56,7 @@ public:
|
||||
|
||||
void TraverseLeaves(DataNode *root, uint32_t beginIndex, uint32_t endIndex) {
|
||||
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) {
|
||||
traversor.called(leaf, nodeIndex);
|
||||
});
|
||||
|
@ -8,8 +8,6 @@
|
||||
#include "../../../../../implementations/onblocks/datatreestore/impl/algorithms.h"
|
||||
|
||||
using ::testing::Test;
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
using std::pair;
|
||||
using std::make_pair;
|
||||
|
||||
@ -28,7 +26,7 @@ public:
|
||||
};
|
||||
|
||||
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());
|
||||
EXPECT_EQ(testData.expectedResult, result->key());
|
||||
}
|
||||
|
@ -8,8 +8,6 @@
|
||||
#include "../../../../../implementations/onblocks/datatreestore/impl/algorithms.h"
|
||||
|
||||
using ::testing::Test;
|
||||
using std::unique_ptr;
|
||||
using std::make_unique;
|
||||
using std::pair;
|
||||
using std::make_pair;
|
||||
|
||||
@ -28,7 +26,7 @@ public:
|
||||
};
|
||||
|
||||
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());
|
||||
EXPECT_EQ(testData.expectedResult, result->key());
|
||||
}
|
||||
@ -80,19 +78,19 @@ public:
|
||||
};
|
||||
|
||||
TEST_F(GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest, Leaf) {
|
||||
auto leaf = nodeStore->load(CreateLeafOnlyTree());
|
||||
auto leaf = std::move(nodeStore->load(CreateLeafOnlyTree()).get());
|
||||
auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, leaf.get());
|
||||
EXPECT_EQ(nullptr, result.get());
|
||||
}
|
||||
|
||||
TEST_F(GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest, TwoRightBorderNodes) {
|
||||
auto node = nodeStore->load(CreateTwoRightBorderNodes());
|
||||
auto node = std::move(nodeStore->load(CreateTwoRightBorderNodes()).get());
|
||||
auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, node.get());
|
||||
EXPECT_EQ(nullptr, result.get());
|
||||
}
|
||||
|
||||
TEST_F(GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest, ThreeRightBorderNodes) {
|
||||
auto node = nodeStore->load(CreateThreeRightBorderNodes());
|
||||
auto node = std::move(nodeStore->load(CreateThreeRightBorderNodes()).get());
|
||||
auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, node.get());
|
||||
EXPECT_EQ(nullptr, result.get());
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "messmer/blockstore/implementations/testfake/FakeBlockStore.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::DataNode;
|
||||
@ -10,35 +11,36 @@ using blobstore::onblocks::datanodestore::DataLeafNode;
|
||||
using blobstore::onblocks::datatreestore::DataTree;
|
||||
using blockstore::testfake::FakeBlockStore;
|
||||
using blockstore::Key;
|
||||
using std::make_unique;
|
||||
using std::unique_ptr;
|
||||
using cpputils::unique_ref;
|
||||
using cpputils::make_unique_ref;
|
||||
using std::initializer_list;
|
||||
using std::vector;
|
||||
using boost::none;
|
||||
using cpputils::dynamic_pointer_move;
|
||||
|
||||
constexpr uint32_t DataTreeTest::BLOCKSIZE_BYTES;
|
||||
|
||||
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()),
|
||||
treeStore(std::move(_nodeStore)) {
|
||||
}
|
||||
|
||||
unique_ptr<DataLeafNode> DataTreeTest::CreateLeaf() {
|
||||
unique_ref<DataLeafNode> DataTreeTest::CreateLeaf() {
|
||||
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());
|
||||
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);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
unique_ptr<DataInnerNode> DataTreeTest::CreateInner(vector<const DataNode*> children) {
|
||||
unique_ref<DataInnerNode> DataTreeTest::CreateInner(vector<const DataNode*> children) {
|
||||
assert(children.size() >= 1);
|
||||
auto node = nodeStore->createNewInnerNode(**children.begin());
|
||||
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;
|
||||
}
|
||||
|
||||
unique_ptr<DataTree> DataTreeTest::CreateLeafOnlyTree() {
|
||||
unique_ref<DataTree> DataTreeTest::CreateLeafOnlyTree() {
|
||||
auto key = CreateLeaf()->key();
|
||||
return treeStore.load(key);
|
||||
return std::move(treeStore.load(key).get());
|
||||
}
|
||||
|
||||
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()});
|
||||
FillNode(root.get());
|
||||
return root;
|
||||
}
|
||||
|
||||
unique_ptr<DataInnerNode> DataTreeTest::CreateThreeLevelMinData() {
|
||||
unique_ref<DataInnerNode> DataTreeTest::CreateThreeLevelMinData() {
|
||||
return CreateInner({
|
||||
CreateFullTwoLevel(),
|
||||
CreateInner({CreateLeaf()})
|
||||
});
|
||||
}
|
||||
|
||||
unique_ptr<DataInnerNode> DataTreeTest::CreateFourLevelMinData() {
|
||||
unique_ref<DataInnerNode> DataTreeTest::CreateFourLevelMinData() {
|
||||
return CreateInner({
|
||||
CreateFullThreeLevel(),
|
||||
CreateInner({CreateInner({CreateLeaf()})})
|
||||
});
|
||||
}
|
||||
|
||||
unique_ptr<DataInnerNode> DataTreeTest::CreateFullThreeLevel() {
|
||||
unique_ref<DataInnerNode> DataTreeTest::CreateFullThreeLevel() {
|
||||
auto root = CreateInner({CreateFullTwoLevel().get()});
|
||||
FillNodeTwoLevel(root.get());
|
||||
return root;
|
||||
}
|
||||
|
||||
unique_ptr<DataInnerNode> DataTreeTest::LoadInnerNode(const Key &key) {
|
||||
auto node = nodeStore->load(key);
|
||||
unique_ref<DataInnerNode> DataTreeTest::LoadInnerNode(const Key &key) {
|
||||
auto node = std::move(nodeStore->load(key).get());
|
||||
auto casted = dynamic_pointer_move<DataInnerNode>(node);
|
||||
EXPECT_NE(nullptr, casted.get()) << "Is not an inner node";
|
||||
return casted;
|
||||
EXPECT_NE(none, casted) << "Is not an inner node";
|
||||
return std::move(*casted);
|
||||
}
|
||||
|
||||
unique_ptr<DataLeafNode> DataTreeTest::LoadLeafNode(const Key &key) {
|
||||
auto node = nodeStore->load(key);
|
||||
unique_ref<DataLeafNode> DataTreeTest::LoadLeafNode(const Key &key) {
|
||||
auto node = std::move(nodeStore->load(key).get());
|
||||
auto casted = dynamic_pointer_move<DataLeafNode>(node);
|
||||
EXPECT_NE(nullptr, casted.get()) << "Is not a leaf node";
|
||||
return casted;
|
||||
EXPECT_NE(none, casted) << "Is not a leaf node";
|
||||
return std::move(*casted);
|
||||
}
|
||||
|
||||
unique_ptr<DataInnerNode> DataTreeTest::CreateTwoLeaf() {
|
||||
unique_ref<DataInnerNode> DataTreeTest::CreateTwoLeaf() {
|
||||
return CreateInner({CreateLeaf().get(), CreateLeaf().get()});
|
||||
}
|
||||
|
||||
unique_ptr<DataTree> DataTreeTest::CreateTwoLeafTree() {
|
||||
unique_ref<DataTree> DataTreeTest::CreateTwoLeafTree() {
|
||||
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();
|
||||
leaf->resize(size);
|
||||
return leaf;
|
||||
}
|
||||
|
||||
unique_ptr<DataInnerNode> DataTreeTest::CreateTwoLeafWithSecondLeafSize(uint32_t size) {
|
||||
unique_ref<DataInnerNode> DataTreeTest::CreateTwoLeafWithSecondLeafSize(uint32_t size) {
|
||||
return CreateInner({
|
||||
CreateLeafWithSize(nodeStore->layout().maxBytesPerLeaf()),
|
||||
CreateLeafWithSize(size)
|
||||
});
|
||||
}
|
||||
|
||||
unique_ptr<DataInnerNode> DataTreeTest::CreateFullTwoLevelWithLastLeafSize(uint32_t size) {
|
||||
unique_ref<DataInnerNode> DataTreeTest::CreateFullTwoLevelWithLastLeafSize(uint32_t size) {
|
||||
auto root = CreateFullTwoLevel();
|
||||
for (uint32_t i = 0; i < root->numChildren()-1; ++i) {
|
||||
LoadLeafNode(root->getChild(i)->key())->resize(nodeStore->layout().maxBytesPerLeaf());
|
||||
@ -135,7 +137,7 @@ unique_ptr<DataInnerNode> DataTreeTest::CreateFullTwoLevelWithLastLeafSize(uint3
|
||||
return root;
|
||||
}
|
||||
|
||||
unique_ptr<DataInnerNode> DataTreeTest::CreateThreeLevelWithOneChildAndLastLeafSize(uint32_t size) {
|
||||
unique_ref<DataInnerNode> DataTreeTest::CreateThreeLevelWithOneChildAndLastLeafSize(uint32_t size) {
|
||||
return CreateInner({
|
||||
CreateInner({
|
||||
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({
|
||||
CreateFullTwoLevelWithLastLeafSize(nodeStore->layout().maxBytesPerLeaf()),
|
||||
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({
|
||||
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();
|
||||
for (uint32_t i = 0; i < root->numChildren(); ++i) {
|
||||
auto node = LoadInnerNode(root->getChild(i)->key());
|
||||
@ -177,7 +179,7 @@ unique_ptr<DataInnerNode> DataTreeTest::CreateFullThreeLevelWithLastLeafSize(uin
|
||||
return root;
|
||||
}
|
||||
|
||||
unique_ptr<DataInnerNode> DataTreeTest::CreateFourLevelMinDataWithLastLeafSize(uint32_t size) {
|
||||
unique_ref<DataInnerNode> DataTreeTest::CreateFourLevelMinDataWithLastLeafSize(uint32_t size) {
|
||||
return CreateInner({
|
||||
CreateFullThreeLevelWithLastLeafSize(nodeStore->layout().maxBytesPerLeaf()),
|
||||
CreateInner({CreateInner({CreateLeafWithSize(size)})})
|
||||
|
@ -16,35 +16,35 @@ public:
|
||||
|
||||
static constexpr uint32_t BLOCKSIZE_BYTES = 256;
|
||||
|
||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataLeafNode> CreateLeaf();
|
||||
std::unique_ptr<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);
|
||||
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::DataLeafNode> CreateLeaf();
|
||||
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateInner(std::vector<const blobstore::onblocks::datanodestore::DataNode *> children);
|
||||
cpputils::unique_ref<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<cpputils::unique_ref<blobstore::onblocks::datanodestore::DataNode>> children);
|
||||
|
||||
std::unique_ptr<blobstore::onblocks::datatreestore::DataTree> CreateLeafOnlyTree();
|
||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateTwoLeaf();
|
||||
std::unique_ptr<blobstore::onblocks::datatreestore::DataTree> CreateTwoLeafTree();
|
||||
cpputils::unique_ref<blobstore::onblocks::datatreestore::DataTree> CreateLeafOnlyTree();
|
||||
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateTwoLeaf();
|
||||
cpputils::unique_ref<blobstore::onblocks::datatreestore::DataTree> CreateTwoLeafTree();
|
||||
void FillNode(blobstore::onblocks::datanodestore::DataInnerNode *node);
|
||||
void FillNodeTwoLevel(blobstore::onblocks::datanodestore::DataInnerNode *node);
|
||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullTwoLevel();
|
||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullThreeLevel();
|
||||
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullTwoLevel();
|
||||
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullThreeLevel();
|
||||
|
||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelMinData();
|
||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateFourLevelMinData();
|
||||
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelMinData();
|
||||
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateFourLevelMinData();
|
||||
|
||||
std::unique_ptr<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::DataInnerNode> LoadInnerNode(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);
|
||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateTwoLeafWithSecondLeafSize(uint32_t size);
|
||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullTwoLevelWithLastLeafSize(uint32_t size);
|
||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelWithOneChildAndLastLeafSize(uint32_t size);
|
||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelWithTwoChildrenAndLastLeafSize(uint32_t size);
|
||||
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelWithThreeChildrenAndLastLeafSize(uint32_t size);
|
||||
std::unique_ptr<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::DataLeafNode> CreateLeafWithSize(uint32_t size);
|
||||
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateTwoLeafWithSecondLeafSize(uint32_t size);
|
||||
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullTwoLevelWithLastLeafSize(uint32_t size);
|
||||
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelWithOneChildAndLastLeafSize(uint32_t size);
|
||||
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelWithTwoChildrenAndLastLeafSize(uint32_t size);
|
||||
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelWithThreeChildrenAndLastLeafSize(uint32_t size);
|
||||
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullThreeLevelWithLastLeafSize(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::datatreestore::DataTreeStore treeStore;
|
||||
|
||||
|
@ -50,7 +50,7 @@ private:
|
||||
auto inner = dynamic_cast<blobstore::onblocks::datanodestore::DataInnerNode*>(node);
|
||||
int leafIndex = firstLeafIndex;
|
||||
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);
|
||||
}
|
||||
return leafIndex;
|
||||
|
@ -3,14 +3,12 @@
|
||||
#include <messmer/blockstore/implementations/testfake/FakeBlockStore.h>
|
||||
#include "../../../../implementations/onblocks/BlobStoreOnBlocks.h"
|
||||
|
||||
using std::make_unique;
|
||||
using std::unique_ptr;
|
||||
|
||||
using blobstore::onblocks::BlobStoreOnBlocks;
|
||||
using blockstore::testfake::FakeBlockStore;
|
||||
using cpputils::make_unique_ref;
|
||||
|
||||
constexpr uint32_t BlobStoreTest::BLOCKSIZE_BYTES;
|
||||
|
||||
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;
|
||||
|
||||
std::unique_ptr<blobstore::BlobStore> blobStore;
|
||||
cpputils::unique_ref<blobstore::BlobStore> blobStore;
|
||||
|
||||
cpputils::unique_ref<blobstore::Blob> loadBlob(const blockstore::Key &key) {
|
||||
auto loaded = blobStore->load(key);
|
||||
|
Loading…
Reference in New Issue
Block a user