Fix locking
This commit is contained in:
parent
9a959cfab9
commit
3f43dcfe10
@ -112,7 +112,6 @@ unique_ptr<DataNode> DataTree::releaseRootNode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DataTree::traverseLeaves(uint32_t beginIndex, uint32_t endIndex, function<void (DataLeafNode*, uint32_t)> func) {
|
void DataTree::traverseLeaves(uint32_t beginIndex, uint32_t endIndex, function<void (DataLeafNode*, uint32_t)> func) {
|
||||||
shared_lock<shared_mutex> lock(_mutex);
|
|
||||||
const_cast<const DataTree*>(this)->traverseLeaves(beginIndex, endIndex, [func](const DataLeafNode* leaf, uint32_t leafIndex) {
|
const_cast<const DataTree*>(this)->traverseLeaves(beginIndex, endIndex, [func](const DataLeafNode* leaf, uint32_t leafIndex) {
|
||||||
func(const_cast<DataLeafNode*>(leaf), leafIndex);
|
func(const_cast<DataLeafNode*>(leaf), leafIndex);
|
||||||
});
|
});
|
||||||
@ -156,11 +155,15 @@ uint32_t DataTree::leavesPerFullChild(const DataInnerNode &root) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64_t DataTree::numStoredBytes() const {
|
uint64_t DataTree::numStoredBytes() const {
|
||||||
return numStoredBytes(*_rootNode);
|
shared_lock<shared_mutex> lock(_mutex);
|
||||||
|
return _numStoredBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t DataTree::numStoredBytes(const DataNode &root) const {
|
uint64_t DataTree::_numStoredBytes() const {
|
||||||
shared_lock<shared_mutex> lock(_mutex);
|
return _numStoredBytes(*_rootNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t DataTree::_numStoredBytes(const DataNode &root) const {
|
||||||
const DataLeafNode *leaf = dynamic_cast<const DataLeafNode*>(&root);
|
const DataLeafNode *leaf = dynamic_cast<const DataLeafNode*>(&root);
|
||||||
if (leaf != nullptr) {
|
if (leaf != nullptr) {
|
||||||
return leaf->numBytes();
|
return leaf->numBytes();
|
||||||
@ -169,16 +172,18 @@ 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);
|
uint64_t numBytesInRightChild = _numStoredBytes(*lastChild);
|
||||||
|
|
||||||
return numBytesInLeftChildren + numBytesInRightChild;
|
return numBytesInLeftChildren + numBytesInRightChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataTree::resizeNumBytes(uint64_t newNumBytes) {
|
void DataTree::resizeNumBytes(uint64_t newNumBytes) {
|
||||||
unique_lock<shared_mutex> lock(_mutex);
|
boost::upgrade_lock<shared_mutex> lock(_mutex);
|
||||||
|
{
|
||||||
|
boost::upgrade_to_unique_lock<shared_mutex> exclusiveLock(lock);
|
||||||
//TODO Faster implementation possible (no addDataLeaf()/removeLastDataLeaf() in a loop, but directly resizing)
|
//TODO Faster implementation possible (no addDataLeaf()/removeLastDataLeaf() in a loop, but directly resizing)
|
||||||
LastLeaf(_rootNode.get())->resize(_nodeStore->layout().maxBytesPerLeaf());
|
LastLeaf(_rootNode.get())->resize(_nodeStore->layout().maxBytesPerLeaf());
|
||||||
uint64_t currentNumBytes = numStoredBytes();
|
uint64_t currentNumBytes = _numStoredBytes();
|
||||||
assert(currentNumBytes % _nodeStore->layout().maxBytesPerLeaf() == 0);
|
assert(currentNumBytes % _nodeStore->layout().maxBytesPerLeaf() == 0);
|
||||||
uint32_t currentNumLeaves = currentNumBytes / _nodeStore->layout().maxBytesPerLeaf();
|
uint32_t currentNumLeaves = currentNumBytes / _nodeStore->layout().maxBytesPerLeaf();
|
||||||
uint32_t newNumLeaves = std::max(1u, utils::ceilDivision(newNumBytes, _nodeStore->layout().maxBytesPerLeaf()));
|
uint32_t newNumLeaves = std::max(1u, utils::ceilDivision(newNumBytes, _nodeStore->layout().maxBytesPerLeaf()));
|
||||||
@ -191,10 +196,10 @@ void DataTree::resizeNumBytes(uint64_t newNumBytes) {
|
|||||||
}
|
}
|
||||||
uint32_t newLastLeafSize = newNumBytes - (newNumLeaves-1)*_nodeStore->layout().maxBytesPerLeaf();
|
uint32_t newLastLeafSize = newNumBytes - (newNumLeaves-1)*_nodeStore->layout().maxBytesPerLeaf();
|
||||||
LastLeaf(_rootNode.get())->resize(newLastLeafSize);
|
LastLeaf(_rootNode.get())->resize(newLastLeafSize);
|
||||||
|
|
||||||
assert(newNumBytes == numStoredBytes());
|
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
|
assert(newNumBytes == numStoredBytes());
|
||||||
|
}
|
||||||
|
|
||||||
optional_ownership_ptr<DataLeafNode> DataTree::LastLeaf(DataNode *root) {
|
optional_ownership_ptr<DataLeafNode> DataTree::LastLeaf(DataNode *root) {
|
||||||
DataLeafNode *leaf = dynamic_cast<DataLeafNode*>(root);
|
DataLeafNode *leaf = dynamic_cast<DataLeafNode*>(root);
|
||||||
|
@ -55,9 +55,11 @@ private:
|
|||||||
void deleteLastChildSubtree(datanodestore::DataInnerNode *node);
|
void deleteLastChildSubtree(datanodestore::DataInnerNode *node);
|
||||||
void ifRootHasOnlyOneChildReplaceRootWithItsChild();
|
void ifRootHasOnlyOneChildReplaceRootWithItsChild();
|
||||||
|
|
||||||
|
//TODO Use underscore for private methods
|
||||||
void traverseLeaves(const datanodestore::DataNode *root, uint32_t leafOffset, uint32_t beginIndex, uint32_t endIndex, std::function<void (const datanodestore::DataLeafNode*, uint32_t)> func) const;
|
void traverseLeaves(const datanodestore::DataNode *root, uint32_t leafOffset, uint32_t beginIndex, uint32_t endIndex, std::function<void (const datanodestore::DataLeafNode*, uint32_t)> func) const;
|
||||||
uint32_t leavesPerFullChild(const datanodestore::DataInnerNode &root) const;
|
uint32_t leavesPerFullChild(const datanodestore::DataInnerNode &root) const;
|
||||||
uint64_t numStoredBytes(const datanodestore::DataNode &root) const;
|
uint64_t _numStoredBytes() const;
|
||||||
|
uint64_t _numStoredBytes(const datanodestore::DataNode &root) 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);
|
std::unique_ptr<datanodestore::DataLeafNode> LastLeaf(std::unique_ptr<datanodestore::DataNode> root);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user