2015-02-17 00:40:34 +01:00
|
|
|
#include "BlobOnBlocks.h"
|
2014-12-09 17:45:33 +01:00
|
|
|
|
2015-02-25 22:48:39 +01:00
|
|
|
#include "datatreestore/DataTree.h"
|
2015-02-26 20:19:12 +01:00
|
|
|
#include "datanodestore/DataLeafNode.h"
|
|
|
|
#include "utils/Math.h"
|
|
|
|
#include <cmath>
|
2014-12-13 19:17:08 +01:00
|
|
|
|
2014-12-09 17:56:48 +01:00
|
|
|
using std::unique_ptr;
|
2015-02-26 20:19:12 +01:00
|
|
|
using std::function;
|
|
|
|
using blobstore::onblocks::datanodestore::DataLeafNode;
|
|
|
|
using blobstore::onblocks::datanodestore::DataNodeLayout;
|
2015-02-27 00:18:26 +01:00
|
|
|
using blockstore::Key;
|
2014-12-09 17:56:48 +01:00
|
|
|
|
2014-12-09 17:45:33 +01:00
|
|
|
namespace blobstore {
|
|
|
|
namespace onblocks {
|
|
|
|
|
2015-02-25 22:48:39 +01:00
|
|
|
using datatreestore::DataTree;
|
2014-12-09 17:45:33 +01:00
|
|
|
|
2015-02-25 22:48:39 +01:00
|
|
|
BlobOnBlocks::BlobOnBlocks(unique_ptr<DataTree> datatree)
|
|
|
|
: _datatree(std::move(datatree)) {
|
2014-12-09 17:56:48 +01:00
|
|
|
}
|
|
|
|
|
2014-12-13 19:17:08 +01:00
|
|
|
BlobOnBlocks::~BlobOnBlocks() {
|
2014-12-09 17:56:48 +01:00
|
|
|
}
|
|
|
|
|
2015-02-26 17:33:47 +01:00
|
|
|
uint64_t BlobOnBlocks::size() const {
|
2015-02-25 23:09:48 +01:00
|
|
|
return _datatree->numStoredBytes();
|
2014-12-09 17:56:48 +01:00
|
|
|
}
|
|
|
|
|
2015-02-26 17:33:47 +01:00
|
|
|
void BlobOnBlocks::resize(uint64_t numBytes) {
|
|
|
|
_datatree->resizeNumBytes(numBytes);
|
|
|
|
}
|
|
|
|
|
2015-01-28 01:02:32 +01:00
|
|
|
void BlobOnBlocks::flush() const {
|
2015-02-25 22:48:39 +01:00
|
|
|
_datatree->flush();
|
2015-01-28 01:02:32 +01:00
|
|
|
}
|
|
|
|
|
2015-02-26 20:23:37 +01:00
|
|
|
void BlobOnBlocks::traverseLeaves(uint64_t beginByte, uint64_t sizeBytes, function<void (uint64_t, void *, uint32_t)> func) const {
|
2015-02-26 20:19:12 +01:00
|
|
|
uint64_t endByte = beginByte + sizeBytes;
|
|
|
|
assert(endByte <= size());
|
|
|
|
uint32_t firstLeaf = beginByte / _datatree->maxBytesPerLeaf();
|
|
|
|
uint32_t endLeaf = utils::ceilDivision(endByte, _datatree->maxBytesPerLeaf());
|
|
|
|
_datatree->traverseLeaves(firstLeaf, endLeaf, [&func, beginByte, endByte](DataLeafNode *leaf, uint32_t leafIndex) {
|
|
|
|
uint64_t indexOfFirstLeafByte = leafIndex * leaf->maxStoreableBytes();
|
|
|
|
uint32_t dataBegin = utils::maxZeroSubtraction(beginByte, indexOfFirstLeafByte);
|
|
|
|
uint32_t dataSize = std::min((uint64_t)leaf->maxStoreableBytes(), endByte - indexOfFirstLeafByte);
|
2015-02-26 20:23:37 +01:00
|
|
|
func(indexOfFirstLeafByte, (uint8_t*)leaf->data() + dataBegin, dataSize);
|
2015-02-26 20:19:12 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
void BlobOnBlocks::read(void *target, uint64_t offset, uint64_t size) const {
|
2015-02-26 20:23:37 +01:00
|
|
|
traverseLeaves(offset, size, [target] (uint64_t indexOfFirstLeafByte, void *leafDataBegin, uint32_t leafDataSize) {
|
|
|
|
std::memcpy(target, leafDataBegin, leafDataSize);
|
2015-02-26 20:19:12 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
void BlobOnBlocks::write(const void *source, uint64_t offset, uint64_t size) {
|
2015-02-26 20:23:37 +01:00
|
|
|
traverseLeaves(offset, size, [source] (uint64_t indexOfFirstLeafByte, void *leafDataBegin, uint32_t leafDataSize) {
|
|
|
|
std::memcpy(leafDataBegin, source, leafDataSize);
|
2015-02-26 20:19:12 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-02-27 00:18:26 +01:00
|
|
|
Key BlobOnBlocks::key() const {
|
|
|
|
return _datatree->key();
|
|
|
|
}
|
|
|
|
|
2014-12-09 17:45:33 +01:00
|
|
|
}
|
|
|
|
}
|