Use unique_ref instead of unique_ptr

This commit is contained in:
Sebastian Messmer 2015-06-26 15:59:18 +02:00
parent 7fae2d1e59
commit 3d1341114b
36 changed files with 346 additions and 316 deletions

View File

@ -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);
} }

View File

@ -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;
}; };
} }

View File

@ -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) {

View File

@ -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;
}; };
} }

View File

@ -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;
} }

View File

@ -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();

View File

@ -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 {

View File

@ -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();

View File

@ -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());

View File

@ -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;

View File

@ -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));

View File

@ -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);

View File

@ -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 {

View File

@ -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);
}; };

View File

@ -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));
} }

View File

@ -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);
}; };

View File

@ -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;

View File

@ -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));
} }

View File

@ -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);

View File

@ -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));
} }

View File

@ -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());

View File

@ -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());

View File

@ -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) {

View File

@ -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> {

View File

@ -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));
} }

View File

@ -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());
} }

View File

@ -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);
} }

View File

@ -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());
} }

View File

@ -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);
}); });

View File

@ -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());
} }

View File

@ -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());
} }

View File

@ -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)})})

View File

@ -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;

View File

@ -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;

View File

@ -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)) {
} }

View File

@ -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);