#pragma once #ifndef BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_DATANODESTORE_DATANODEVIEW_H_ #define BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_DATANODESTORE_DATANODEVIEW_H_ #include "messmer/blockstore/interface/Block.h" #include "../BlobStoreOnBlocks.h" #include "messmer/cpp-utils/macros.h" #include #include namespace blobstore { namespace onblocks { namespace datanodestore { class DataNodeView { public: DataNodeView(std::unique_ptr block): _block(std::move(block)) { assert(_block->size() == BLOCKSIZE_BYTES); } virtual ~DataNodeView() {} DataNodeView(DataNodeView &&rhs) = default; //Total size of the header static constexpr unsigned int HEADERSIZE_BYTES = 8; //Where in the header is the depth field static constexpr unsigned int DEPTH_OFFSET_BYTES = 0; //Where in the header is the size field (for inner nodes: number of children, for leafs: content data size) static constexpr unsigned int SIZE_OFFSET_BYTES = 4; //How big is one blob in total (header + data) static constexpr unsigned int BLOCKSIZE_BYTES = BlobStoreOnBlocks::BLOCKSIZE; //How much space is there for data static constexpr unsigned int DATASIZE_BYTES = BLOCKSIZE_BYTES - HEADERSIZE_BYTES; const uint8_t *Depth() const { return GetOffset(); } uint8_t *Depth() { return const_cast(const_cast(this)->Depth()); } const uint32_t *Size() const { return GetOffset(); } uint32_t *Size() { return const_cast(const_cast(this)->Size()); } template const Entry *DataBegin() const { return GetOffset(); } template Entry *DataBegin() { return const_cast(const_cast(this)->DataBegin()); } template const Entry *DataEnd() const { constexpr unsigned int NUM_ENTRIES = DATASIZE_BYTES / sizeof(Entry); return DataBegin() + NUM_ENTRIES; } template Entry *DataEnd() { return const_cast(const_cast(this)->DataEnd()); } std::unique_ptr releaseBlock() { return std::move(_block); } const blockstore::Block &block() const { return *_block; } const blockstore::Key &key() const { return _block->key(); } void flush() const { _block->flush(); } private: template const Type *GetOffset() const { return (Type*)(((const int8_t*)_block->data())+offset); } std::unique_ptr _block; DISALLOW_COPY_AND_ASSIGN(DataNodeView); }; } } } #endif