2014-12-13 17:48:02 +01:00
|
|
|
#include <blobstore/implementations/onblocks/datanodestore/DataInnerNode.h>
|
|
|
|
#include <blobstore/implementations/onblocks/datanodestore/DataNodeStore.h>
|
2014-12-09 18:53:11 +01:00
|
|
|
|
2014-12-13 17:43:02 +01:00
|
|
|
|
2014-12-09 18:53:11 +01:00
|
|
|
using std::unique_ptr;
|
|
|
|
using blockstore::Block;
|
2014-12-10 16:48:00 +01:00
|
|
|
using blockstore::Data;
|
2014-12-13 19:17:08 +01:00
|
|
|
using blockstore::Key;
|
2014-12-09 18:53:11 +01:00
|
|
|
|
|
|
|
namespace blobstore {
|
|
|
|
namespace onblocks {
|
2014-12-13 19:17:08 +01:00
|
|
|
namespace datanodestore {
|
2014-12-09 18:53:11 +01:00
|
|
|
|
2014-12-13 17:43:02 +01:00
|
|
|
DataInnerNode::DataInnerNode(DataNodeView view, const Key &key, DataNodeStore *nodestorage)
|
|
|
|
: DataNode(std::move(view), key, nodestorage) {
|
2014-12-09 18:53:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DataInnerNode::~DataInnerNode() {
|
|
|
|
}
|
|
|
|
|
2014-12-13 17:43:02 +01:00
|
|
|
void DataInnerNode::InitializeNewNode(const DataNode &first_child) {
|
|
|
|
*node().Depth() = first_child.depth() + 1;
|
|
|
|
*node().Size() = 1;
|
|
|
|
first_child.key().ToBinary(ChildrenBegin()->key);
|
2014-12-10 16:48:00 +01:00
|
|
|
}
|
|
|
|
|
2014-12-11 00:24:50 +01:00
|
|
|
void DataInnerNode::read(off_t offset, size_t count, Data *result) const {
|
2014-12-10 16:48:00 +01:00
|
|
|
assert(count <= result->size());
|
|
|
|
const uint64_t end = offset + count;
|
|
|
|
assert(end <= numBytesInThisNode());
|
|
|
|
|
|
|
|
uint8_t *target = (uint8_t*)result->data();
|
|
|
|
|
2014-12-11 00:24:50 +01:00
|
|
|
const ChildEntry *child = ChildContainingFirstByteAfterOffset(offset);
|
2014-12-13 17:43:02 +01:00
|
|
|
uint32_t child_index = child-ChildrenBegin();
|
|
|
|
uint64_t child_first_byte_index = maxNumBytesPerChild() * child_index;
|
|
|
|
uint64_t next_child_first_byte_index = child_first_byte_index + maxNumBytesPerChild();
|
|
|
|
off_t childrelative_offset = offset - child_first_byte_index;
|
|
|
|
uint64_t already_read_bytes = readFromChild(child, childrelative_offset, count, target);
|
|
|
|
while(next_child_first_byte_index < end) { //TODO Write a test case that breaks when we're having <= instead of < here
|
2014-12-10 16:48:00 +01:00
|
|
|
++child;
|
|
|
|
already_read_bytes += readFromChild(child, 0, count, target + already_read_bytes);
|
|
|
|
};
|
|
|
|
assert(already_read_bytes == count);
|
|
|
|
}
|
|
|
|
|
2014-12-11 00:24:50 +01:00
|
|
|
uint64_t DataInnerNode::readFromChild(const ChildEntry *child, off_t inner_offset, size_t count, uint8_t *target) const {
|
2014-12-13 17:43:02 +01:00
|
|
|
//TODO This only works for non-rightmost children
|
|
|
|
uint64_t readable_bytes = std::min(count, maxNumBytesPerChild() - inner_offset);
|
2014-12-10 16:48:00 +01:00
|
|
|
|
|
|
|
//TODO READ...
|
|
|
|
|
|
|
|
return readable_bytes;
|
|
|
|
}
|
|
|
|
|
2014-12-11 00:24:50 +01:00
|
|
|
const DataInnerNode::ChildEntry *DataInnerNode::ChildContainingFirstByteAfterOffset(off_t offset) const {
|
2014-12-13 17:43:02 +01:00
|
|
|
uint8_t child_index = offset/maxNumBytesPerChild();
|
|
|
|
return ChildrenBegin()+child_index;
|
|
|
|
}
|
2014-12-10 16:48:00 +01:00
|
|
|
|
2014-12-13 17:43:02 +01:00
|
|
|
uint32_t DataInnerNode::maxNumDataBlocksPerChild() const {
|
|
|
|
return std::round(std::pow(MAX_STORED_CHILDREN, *node().Depth()));
|
2014-12-10 16:48:00 +01:00
|
|
|
}
|
|
|
|
|
2014-12-11 00:24:50 +01:00
|
|
|
uint64_t DataInnerNode::numBytesInThisNode() const {
|
2014-12-13 17:43:02 +01:00
|
|
|
return numBytesInNonRightmostChildrenSum() + numBytesInRightmostChild();
|
2014-12-10 16:48:00 +01:00
|
|
|
}
|
|
|
|
|
2014-12-13 17:43:02 +01:00
|
|
|
uint64_t DataInnerNode::numBytesInNonRightmostChildrenSum() const {
|
|
|
|
return maxNumBytesPerChild() * (numChildren()-1);
|
2014-12-10 16:48:00 +01:00
|
|
|
}
|
|
|
|
|
2014-12-13 17:43:02 +01:00
|
|
|
uint64_t DataInnerNode::numBytesInRightmostChild() const {
|
|
|
|
Key rightmost_child_key = Key::FromBinary(RightmostChild()->key);
|
|
|
|
auto rightmost_child = storage().load(rightmost_child_key);
|
|
|
|
return rightmost_child->numBytesInThisNode();
|
2014-12-10 16:48:00 +01:00
|
|
|
}
|
|
|
|
|
2014-12-13 17:43:02 +01:00
|
|
|
uint32_t DataInnerNode::numChildren() const {
|
|
|
|
return *node().Size();
|
2014-12-13 12:00:19 +01:00
|
|
|
}
|
|
|
|
|
2014-12-13 17:43:02 +01:00
|
|
|
//TODO This only works for non-rightmost children
|
|
|
|
uint64_t DataInnerNode::maxNumBytesPerChild() const {
|
|
|
|
return maxNumDataBlocksPerChild() * DataNodeView::DATASIZE_BYTES;
|
|
|
|
}
|
2014-12-13 12:00:19 +01:00
|
|
|
DataInnerNode::ChildEntry *DataInnerNode::ChildrenBegin() {
|
|
|
|
return const_cast<ChildEntry*>(const_cast<const DataInnerNode*>(this)->ChildrenBegin());
|
2014-12-10 16:48:00 +01:00
|
|
|
}
|
|
|
|
|
2014-12-11 00:24:50 +01:00
|
|
|
const DataInnerNode::ChildEntry *DataInnerNode::ChildrenBegin() const {
|
2014-12-13 17:43:02 +01:00
|
|
|
return node().DataBegin<ChildEntry>();
|
2014-12-10 16:48:00 +01:00
|
|
|
}
|
|
|
|
|
2014-12-11 00:24:50 +01:00
|
|
|
const DataInnerNode::ChildEntry *DataInnerNode::ChildrenEnd() const {
|
2014-12-13 17:43:02 +01:00
|
|
|
return ChildrenBegin() + *node().Size();
|
2014-12-10 16:48:00 +01:00
|
|
|
}
|
|
|
|
|
2014-12-13 17:43:02 +01:00
|
|
|
const DataInnerNode::ChildEntry *DataInnerNode::RightmostChild() const{
|
2014-12-10 16:48:00 +01:00
|
|
|
return ChildrenEnd()-1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DataInnerNode::write(off_t offset, size_t count, const Data &data) {
|
2014-12-10 23:34:36 +01:00
|
|
|
//TODO Implement
|
2014-12-10 16:48:00 +01:00
|
|
|
|
2014-12-09 18:53:11 +01:00
|
|
|
}
|
|
|
|
|
2014-12-10 23:34:36 +01:00
|
|
|
void DataInnerNode::resize(uint64_t newsize_bytes) {
|
|
|
|
//TODO Implement
|
|
|
|
}
|
|
|
|
|
2014-12-09 18:53:11 +01:00
|
|
|
}
|
|
|
|
}
|
2014-12-13 19:17:08 +01:00
|
|
|
}
|