diff --git a/implementations/onblocks/BlobOnBlocks.cpp b/implementations/onblocks/BlobOnBlocks.cpp index b850b456..737fa45a 100644 --- a/implementations/onblocks/BlobOnBlocks.cpp +++ b/implementations/onblocks/BlobOnBlocks.cpp @@ -4,6 +4,7 @@ #include "datanodestore/DataLeafNode.h" #include "utils/Math.h" #include +#include using std::function; using cpputils::unique_ref; @@ -49,9 +50,9 @@ void BlobOnBlocks::traverseLeaves(uint64_t beginByte, uint64_t sizeBytes, functi } void BlobOnBlocks::read(void *target, uint64_t offset, uint64_t count) const { - assert(offset <= _datatree->numStoredBytes() && offset + count <= size()); + ASSERT(offset <= _datatree->numStoredBytes() && offset + count <= size(), "BlobOnBlocks::read() read outside blob. Use BlobOnBlocks::tryRead() if this should be allowed."); uint64_t read = tryRead(target, offset, count); - assert(read == count); + ASSERT(read == count, "BlobOnBlocks::read() couldn't read all requested bytes. Use BlobOnBlocks::tryRead() if this should be allowed."); } uint64_t BlobOnBlocks::tryRead(void *target, uint64_t offset, uint64_t count) const { diff --git a/implementations/onblocks/BlobStoreOnBlocks.cpp b/implementations/onblocks/BlobStoreOnBlocks.cpp index 86b3131a..795c6e5f 100644 --- a/implementations/onblocks/BlobStoreOnBlocks.cpp +++ b/implementations/onblocks/BlobStoreOnBlocks.cpp @@ -8,6 +8,7 @@ #include "BlobStoreOnBlocks.h" #include "BlobOnBlocks.h" #include +#include using cpputils::unique_ref; using cpputils::make_unique_ref; @@ -47,7 +48,7 @@ optional> BlobStoreOnBlocks::load(const Key &key) { void BlobStoreOnBlocks::remove(unique_ref blob) { auto _blob = dynamic_pointer_move(blob); - assert(_blob != none); + ASSERT(_blob != none, "Passed Blob in BlobStoreOnBlocks::remove() is not a BlobOnBlocks."); _dataTreeStore->remove((*_blob)->releaseTree()); } diff --git a/implementations/onblocks/datanodestore/DataInnerNode.cpp b/implementations/onblocks/datanodestore/DataInnerNode.cpp index fcfd9b6a..c2004912 100644 --- a/implementations/onblocks/datanodestore/DataInnerNode.cpp +++ b/implementations/onblocks/datanodestore/DataInnerNode.cpp @@ -1,5 +1,6 @@ #include "DataInnerNode.h" #include "DataNodeStore.h" +#include using blockstore::Block; using cpputils::Data; @@ -13,7 +14,7 @@ namespace datanodestore { DataInnerNode::DataInnerNode(DataNodeView view) : DataNode(std::move(view)) { - assert(depth() > 0); + ASSERT(depth() > 0, "Inner node can't have depth 0. Is this a leaf maybe?"); } DataInnerNode::~DataInnerNode() { @@ -61,19 +62,19 @@ DataInnerNode::ChildEntry *DataInnerNode::getChild(unsigned int index) { } const DataInnerNode::ChildEntry *DataInnerNode::getChild(unsigned int index) const { - assert(index < numChildren()); + ASSERT(index < numChildren(), "Accessing child out of range"); return ChildrenBegin()+index; } void DataInnerNode::addChild(const DataNode &child) { - assert(numChildren() < maxStoreableChildren()); - assert(child.depth() == depth()-1); + ASSERT(numChildren() < maxStoreableChildren(), "Adding more children than we can store"); + ASSERT(child.depth() == depth()-1, "The child that should be added has wrong depth"); node().setSize(node().Size()+1); LastChild()->setKey(child.key()); } void DataInnerNode::removeLastChild() { - assert(node().Size() > 1); + ASSERT(node().Size() > 1, "There is no child to remove"); node().setSize(node().Size()-1); } diff --git a/implementations/onblocks/datanodestore/DataLeafNode.cpp b/implementations/onblocks/datanodestore/DataLeafNode.cpp index 3ab7e910..2791c9af 100644 --- a/implementations/onblocks/datanodestore/DataLeafNode.cpp +++ b/implementations/onblocks/datanodestore/DataLeafNode.cpp @@ -1,5 +1,6 @@ #include "DataLeafNode.h" #include "DataInnerNode.h" +#include using blockstore::Block; using cpputils::Data; @@ -13,8 +14,8 @@ namespace datanodestore { DataLeafNode::DataLeafNode(DataNodeView view) : DataNode(std::move(view)) { - assert(node().Depth() == 0); - assert(numBytes() <= maxStoreableBytes()); + ASSERT(node().Depth() == 0, "Leaf node must have depth 0. Is it an inner node instead?"); + ASSERT(numBytes() <= maxStoreableBytes(), "Leaf says it stores more bytes than it has space for"); } DataLeafNode::~DataLeafNode() { @@ -29,12 +30,12 @@ unique_ref DataLeafNode::InitializeNewNode(unique_ref block } void DataLeafNode::read(void *target, uint64_t offset, uint64_t size) const { - assert(offset <= node().Size() && offset + size <= node().Size()); // Also check offset, because the addition could lead to overflows + ASSERT(offset <= node().Size() && offset + size <= node().Size(), "Read out of valid area"); // Also check offset, because the addition could lead to overflows std::memcpy(target, (uint8_t*)node().data() + offset, size); } void DataLeafNode::write(const void *source, uint64_t offset, uint64_t size) { - assert(offset <= node().Size() && offset + size <= node().Size()); // Also check offset, because the addition could lead to overflows + ASSERT(offset <= node().Size() && offset + size <= node().Size(), "Write out of valid area"); // Also check offset, because the addition could lead to overflows node().write(source, offset, size); } @@ -43,7 +44,7 @@ uint32_t DataLeafNode::numBytes() const { } void DataLeafNode::resize(uint32_t new_size) { - assert(new_size <= maxStoreableBytes()); + ASSERT(new_size <= maxStoreableBytes(), "Trying to resize to a size larger than the maximal size"); uint32_t old_size = node().Size(); if (new_size < old_size) { fillDataWithZeroesFromTo(new_size, old_size); diff --git a/implementations/onblocks/datanodestore/DataNodeStore.cpp b/implementations/onblocks/datanodestore/DataNodeStore.cpp index c44b4518..b70e8081 100644 --- a/implementations/onblocks/datanodestore/DataNodeStore.cpp +++ b/implementations/onblocks/datanodestore/DataNodeStore.cpp @@ -4,7 +4,7 @@ #include "messmer/blockstore/interface/BlockStore.h" #include "messmer/blockstore/interface/Block.h" #include "messmer/blockstore/utils/BlockStoreUtils.h" - +#include using blockstore::BlockStore; using blockstore::Block; @@ -28,7 +28,7 @@ DataNodeStore::~DataNodeStore() { } unique_ref DataNodeStore::load(unique_ref block) { - assert(block->size() == _layout.blocksizeBytes()); + ASSERT(block->size() == _layout.blocksizeBytes(), "Loading block of wrong size"); DataNodeView node(std::move(block)); if (node.Depth() == 0) { @@ -41,7 +41,7 @@ unique_ref DataNodeStore::load(unique_ref block) { } unique_ref 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(), "Source node has wrong layout. Is it from the same DataNodeStore?"); //TODO Initialize block and then create it in the blockstore - this is more efficient than creating it and then writing to it auto block = _blockstore->create(Data(_layout.blocksizeBytes()).FillWithZeroes()); return DataInnerNode::InitializeNewNode(std::move(block), first_child); @@ -63,14 +63,14 @@ optional> DataNodeStore::load(const Key &key) { } unique_ref 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(), "Source node has wrong layout. Is it from the same DataNodeStore?"); auto newBlock = blockstore::utils::copyToNewBlock(_blockstore.get(), source.node().block()); return load(std::move(newBlock)); } unique_ref DataNodeStore::overwriteNodeWith(unique_ref target, const DataNode &source) { - assert(target->node().layout().blocksizeBytes() == _layout.blocksizeBytes()); - assert(source.node().layout().blocksizeBytes() == _layout.blocksizeBytes()); + ASSERT(target->node().layout().blocksizeBytes() == _layout.blocksizeBytes(), "Target node has wrong layout. Is it from the same DataNodeStore?"); + ASSERT(source.node().layout().blocksizeBytes() == _layout.blocksizeBytes(), "Source node has wrong layout. Is it from the same DataNodeStore?"); Key key = target->key(); { auto targetBlock = target->node().releaseBlock(); @@ -78,7 +78,7 @@ unique_ref DataNodeStore::overwriteNodeWith(unique_ref targe blockstore::utils::copyTo(targetBlock.get(), source.node().block()); } auto loaded = load(key); - assert(loaded != none); + ASSERT(loaded != none, "Couldn't load the target node after overwriting it"); return std::move(*loaded); } @@ -97,7 +97,7 @@ void DataNodeStore::removeSubtree(unique_ref node) { if (inner != nullptr) { for (uint32_t i = 0; i < inner->numChildren(); ++i) { auto child = load(inner->getChild(i)->key()); - assert(child != none); + ASSERT(child != none, "Couldn't load child node"); removeSubtree(std::move(*child)); } } diff --git a/implementations/onblocks/datatreestore/DataTree.cpp b/implementations/onblocks/datatreestore/DataTree.cpp index a8e10312..90df408c 100644 --- a/implementations/onblocks/datatreestore/DataTree.cpp +++ b/implementations/onblocks/datatreestore/DataTree.cpp @@ -10,6 +10,7 @@ #include "messmer/cpp-utils/pointer/cast.h" #include "messmer/cpp-utils/pointer/optional_ownership_ptr.h" #include +#include using blockstore::Key; using blobstore::onblocks::datanodestore::DataNodeStore; @@ -45,7 +46,7 @@ DataTree::~DataTree() { void DataTree::removeLastDataLeaf() { auto deletePosOrNull = algorithms::GetLowestRightBorderNodeWithMoreThanOneChildOrNull(_nodeStore, _rootNode.get()); - assert(deletePosOrNull.get() != nullptr); //TODO Correct exception (tree has only one leaf, can't shrink it) + ASSERT(deletePosOrNull.get() != nullptr, "Tree has only one leaf, can't shrink it."); deleteLastChildSubtree(deletePosOrNull.get()); @@ -54,10 +55,10 @@ void DataTree::removeLastDataLeaf() { void DataTree::ifRootHasOnlyOneChildReplaceRootWithItsChild() { DataInnerNode *rootNode = dynamic_cast(_rootNode.get()); - assert(rootNode != nullptr); + ASSERT(rootNode != nullptr, "RootNode is not an inner node"); if (rootNode->numChildren() == 1) { auto child = _nodeStore->load(rootNode->getChild(0)->key()); - assert(child != none); + ASSERT(child != none, "Couldn't load first child of root node"); _rootNode = _nodeStore->overwriteNodeWith(std::move(_rootNode), **child); _nodeStore->remove(std::move(*child)); } @@ -65,7 +66,7 @@ void DataTree::ifRootHasOnlyOneChildReplaceRootWithItsChild() { void DataTree::deleteLastChildSubtree(DataInnerNode *node) { auto lastChild = _nodeStore->load(node->LastChild()->key()); - assert(lastChild != none); + ASSERT(lastChild != none, "Couldn't load last child"); _nodeStore->removeSubtree(std::move(*lastChild)); node->removeLastChild(); } @@ -105,7 +106,7 @@ unique_ref DataTree::createChainOfInnerNodes(unsigned int num, unique_ } DataInnerNode* DataTree::increaseTreeDepth(unsigned int levels) { - assert(levels >= 1); + ASSERT(levels >= 1, "Parameter out of bounds: tried to increase tree depth by zero."); auto copyOfOldRoot = _nodeStore->createNewNodeAsCopyFrom(*_rootNode); auto chain = createChainOfInnerNodes(levels-1, copyOfOldRoot.get()); auto newRootNode = DataNode::convertToNewInnerNode(std::move(_rootNode), *chain); @@ -146,7 +147,7 @@ uint32_t DataTree::_numLeaves(const DataNode &node) const { const DataInnerNode &inner = dynamic_cast(node); uint64_t numLeavesInLeftChildren = (inner.numChildren()-1) * leavesPerFullChild(inner); auto lastChild = _nodeStore->load(inner.LastChild()->key()); - assert(lastChild != none); + ASSERT(lastChild != none, "Couldn't load last child"); uint64_t numLeavesInRightChild = _numLeaves(**lastChild); return numLeavesInLeftChildren + numLeavesInRightChild; @@ -154,7 +155,7 @@ uint32_t DataTree::_numLeaves(const DataNode &node) const { void DataTree::traverseLeaves(uint32_t beginIndex, uint32_t endIndex, function func) { unique_lock lock(_mutex); //TODO Only lock when resizing - assert(beginIndex <= endIndex); + ASSERT(beginIndex <= endIndex, "Invalid parameters"); uint8_t neededTreeDepth = utils::ceilLog(_nodeStore->layout().maxChildrenPerInnerNode(), endIndex); uint32_t numLeaves = this->numLeaves(); @@ -192,7 +193,7 @@ void DataTree::traverseLeaves(uint32_t beginIndex, uint32_t endIndex, function func) { DataLeafNode *leaf = dynamic_cast(root); if (leaf != nullptr) { - assert(beginIndex <= 1 && endIndex <= 1); + ASSERT(beginIndex <= 1 && endIndex <= 1, "If root node is a leaf, the (sub)tree has only one leaf - access indices must be 0 or 1."); if (beginIndex == 0 && endIndex == 1) { func(leaf, leafOffset); } @@ -219,13 +220,13 @@ vector> DataTree::getOrCreateChildren(DataInnerNode *node, children.reserve(end-begin); for (uint32_t childIndex = begin; childIndex < std::min(node->numChildren(), end); ++childIndex) { auto child = _nodeStore->load(node->getChild(childIndex)->key()); - assert(child != none); + ASSERT(child != none, "Couldn't load child node"); children.emplace_back(std::move(*child)); } for (uint32_t childIndex = node->numChildren(); childIndex < end; ++childIndex) { children.emplace_back(addChildTo(node)); } - assert(children.size() == end-begin); + ASSERT(children.size() == end-begin, "Number of children in the result is wrong"); return children; } @@ -259,7 +260,7 @@ uint64_t DataTree::_numStoredBytes(const DataNode &root) const { const DataInnerNode &inner = dynamic_cast(root); uint64_t numBytesInLeftChildren = (inner.numChildren()-1) * leavesPerFullChild(inner) * _nodeStore->layout().maxBytesPerLeaf(); auto lastChild = _nodeStore->load(inner.LastChild()->key()); - assert(lastChild != none); + ASSERT(lastChild != none, "Couldn't load last child"); uint64_t numBytesInRightChild = _numStoredBytes(**lastChild); return numBytesInLeftChildren + numBytesInRightChild; @@ -272,7 +273,7 @@ void DataTree::resizeNumBytes(uint64_t newNumBytes) { //TODO Faster implementation possible (no addDataLeaf()/removeLastDataLeaf() in a loop, but directly resizing) LastLeaf(_rootNode.get())->resize(_nodeStore->layout().maxBytesPerLeaf()); uint64_t currentNumBytes = _numStoredBytes(); - assert(currentNumBytes % _nodeStore->layout().maxBytesPerLeaf() == 0); + ASSERT(currentNumBytes % _nodeStore->layout().maxBytesPerLeaf() == 0, "The last leaf is not a max data leaf, although we just resized it to be one."); uint32_t currentNumLeaves = currentNumBytes / _nodeStore->layout().maxBytesPerLeaf(); uint32_t newNumLeaves = std::max(1u, utils::ceilDivision(newNumBytes, _nodeStore->layout().maxBytesPerLeaf())); @@ -285,7 +286,7 @@ void DataTree::resizeNumBytes(uint64_t newNumBytes) { uint32_t newLastLeafSize = newNumBytes - (newNumLeaves-1)*_nodeStore->layout().maxBytesPerLeaf(); LastLeaf(_rootNode.get())->resize(newLastLeafSize); } - assert(newNumBytes == numStoredBytes()); + ASSERT(newNumBytes == numStoredBytes(), "We resized to the wrong number of bytes"); } optional_ownership_ptr DataTree::LastLeaf(DataNode *root) { @@ -296,7 +297,7 @@ optional_ownership_ptr DataTree::LastLeaf(DataNode *root) { DataInnerNode *inner = dynamic_cast(root); auto lastChild = _nodeStore->load(inner->LastChild()->key()); - assert(lastChild != none); + ASSERT(lastChild != none, "Couldn't load last child"); return WithOwnership(LastLeaf(std::move(*lastChild))); } @@ -306,9 +307,9 @@ unique_ref DataTree::LastLeaf(unique_ref root) { return std::move(*leaf); } auto inner = dynamic_pointer_move(root); - assert(inner != none); + ASSERT(inner != none, "Root node is neither a leaf nor an inner node"); auto child = _nodeStore->load((*inner)->LastChild()->key()); - assert(child != none); + ASSERT(child != none, "Couldn't load last child"); return LastLeaf(std::move(*child)); } diff --git a/implementations/onblocks/datatreestore/impl/algorithms.cpp b/implementations/onblocks/datatreestore/impl/algorithms.cpp index 3d2d71c2..89d64903 100644 --- a/implementations/onblocks/datatreestore/impl/algorithms.cpp +++ b/implementations/onblocks/datatreestore/impl/algorithms.cpp @@ -4,6 +4,7 @@ #include "../../datanodestore/DataInnerNode.h" #include "../../datanodestore/DataNodeStore.h" +#include using std::function; using cpputils::optional_ownership_ptr; @@ -24,7 +25,7 @@ namespace algorithms { optional> getLastChildAsInnerNode(DataNodeStore *nodeStore, const DataInnerNode &node) { Key key = node.LastChild()->key(); auto lastChild = nodeStore->load(key); - assert(lastChild != none); + ASSERT(lastChild != none, "Couldn't load last child"); return dynamic_pointer_move(*lastChild); } @@ -39,7 +40,7 @@ optional_ownership_ptr GetLowestInnerRightBorderNodeWithCondition if (condition(*currentNode)) { result = std::move(currentNode); } - assert(lastChild != none || static_cast(i) == rootNode->depth()-1); + ASSERT(lastChild != none || static_cast(i) == rootNode->depth()-1, "Couldn't get last child as inner node but we're not deep enough yet for the last child to be a leaf"); if (lastChild != none) { currentNode = cpputils::WithOwnership(std::move(*lastChild)); } diff --git a/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp b/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp index e8864222..d906dff0 100644 --- a/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp +++ b/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp @@ -41,7 +41,7 @@ unique_ref DataTreeTest::CreateInner(initializer_list DataTreeTest::CreateInner(vector children) { - assert(children.size() >= 1); + ASSERT(children.size() >= 1, "An inner node must have at least one child"); auto node = nodeStore->createNewInnerNode(**children.begin()); for(auto child = children.begin()+1; child != children.end(); ++child) { node->addChild(**child); diff --git a/test/implementations/onblocks/datatreestore/testutils/TwoLevelDataFixture.h b/test/implementations/onblocks/datatreestore/testutils/TwoLevelDataFixture.h index 03b4748e..6e2e8594 100644 --- a/test/implementations/onblocks/datatreestore/testutils/TwoLevelDataFixture.h +++ b/test/implementations/onblocks/datatreestore/testutils/TwoLevelDataFixture.h @@ -5,6 +5,7 @@ #include #include #include "LeafDataFixture.h" +#include //TODO Rename, since we now allow any number of levels // A data fixture containing data for a two-level tree (one inner node with leaf children). @@ -70,7 +71,8 @@ private: case SizePolicy::Unchanged: return leaf->numBytes(); default: - assert(false); + ASSERT(false, "Unknown size policy"); + abort(); // The assert above already aborts. This is just to prevent the style checker from complaining about exiting a non-void function } }