susumu.yata
null+****@clear*****
Mon Dec 10 00:59:07 JST 2012
susumu.yata 2012-12-10 00:59:07 +0900 (Mon, 10 Dec 2012) New Revision: 67ebc4b58855959a26b79c8399f18003ec8ad59c https://github.com/groonga/grnxx/commit/67ebc4b58855959a26b79c8399f18003ec8ad59c Log: Simplify the implementation of grnxx::alpha::BlobVector. Modified files: lib/alpha/blob_vector.cpp lib/alpha/blob_vector.hpp Modified: lib/alpha/blob_vector.cpp (+72 -141) =================================================================== --- lib/alpha/blob_vector.cpp 2012-12-09 21:33:21 +0900 (0b3517a) +++ lib/alpha/blob_vector.cpp 2012-12-10 00:59:07 +0900 (8fc2c81) @@ -27,10 +27,10 @@ namespace alpha { BlobVectorCreate BLOB_VECTOR_CREATE; BlobVectorOpen BLOB_VECTOR_OPEN; -BlobVectorHeader::BlobVectorHeader(uint32_t cells_block_id) - : cells_block_id_(cells_block_id), +BlobVectorHeader::BlobVectorHeader(uint32_t table_block_id) + : table_block_id_(table_block_id), value_store_block_id_(io::BLOCK_INVALID_ID), - page_infos_block_id_(io::BLOCK_INVALID_ID), + index_store_block_id_(io::BLOCK_INVALID_ID), next_page_id_(0), next_value_offset_(0), latest_frozen_page_id_(BLOB_VECTOR_INVALID_PAGE_ID), @@ -42,9 +42,9 @@ StringBuilder &BlobVectorHeader::write_to(StringBuilder &builder) const { return builder; } - builder << "{ cells_block_id = " << cells_block_id_ + builder << "{ table_block_id = " << table_block_id_ << ", value_store_block_id = " << value_store_block_id_ - << ", page_infos_block_id = " << page_infos_block_id_ + << ", index_store_block_id = " << index_store_block_id_ << ", next_page_id = " << next_page_id_ << ", next_value_offset = " << next_value_offset_ << ", latest_large_value_block_id = " << latest_large_value_block_id_ @@ -52,41 +52,6 @@ StringBuilder &BlobVectorHeader::write_to(StringBuilder &builder) const { return builder << " }"; } -StringBuilder &operator<<(StringBuilder &builder, BlobVectorType type) { - switch (type) { - case BLOB_VECTOR_NULL: { - return builder << "BLOB_VECTOR_NULL"; - } - case BLOB_VECTOR_SMALL: { - return builder << "BLOB_VECTOR_SMALL"; - } - case BLOB_VECTOR_MEDIUM: { - return builder << "BLOB_VECTOR_MEDIUM"; - } - case BLOB_VECTOR_LARGE: { - return builder << "BLOB_VECTOR_LARGE"; - } - default: { - return builder << "n/a"; - } - } -} - -StringBuilder &operator<<(StringBuilder &builder, - BlobVectorAttribute attribute) { - switch (attribute) { - case BLOB_VECTOR_APPENDABLE: { - return builder << "BLOB_VECTOR_APPENDABLE"; - } - case BLOB_VECTOR_PREPENDABLE: { - return builder << "BLOB_VECTOR_PREPENDABLE"; - } - default: { - return builder << "n/a"; - } - } -} - std::unique_ptr<BlobVectorImpl> BlobVectorImpl::create(io::Pool pool) { std::unique_ptr<BlobVectorImpl> vector(new (std::nothrow) BlobVectorImpl); if (!vector) { @@ -109,13 +74,7 @@ std::unique_ptr<BlobVectorImpl> BlobVectorImpl::open(io::Pool pool, } const void *BlobVectorImpl::get_value(uint64_t id, uint64_t *length) { - if (id > BLOB_VECTOR_MAX_ID) { - GRNXX_ERROR() << "invalid argument: id = " << id - << ", max_id = " << BLOB_VECTOR_MAX_ID; - GRNXX_THROW(); - } - - const BlobVectorCell cell = cells_[id]; + const BlobVectorCell cell = table_[id]; switch (cell.type()) { case BLOB_VECTOR_NULL: { if (length) { @@ -125,30 +84,28 @@ const void *BlobVectorImpl::get_value(uint64_t id, uint64_t *length) { } case BLOB_VECTOR_SMALL: { if (length) { - *length = cell.small().length(); + *length = cell.small_length(); } // FIXME: The cell might be updated by other threads and processes. // This interface cannot solve this problem. - return cells_[id].small().value(); + return table_[id].value(); } case BLOB_VECTOR_MEDIUM: { if (!value_store_) { Lock lock(mutable_inter_thread_mutex()); if (!value_store_) { - value_store_ = BlobVectorValueStore( - VECTOR_OPEN, pool_, header_->value_store_block_id()); + value_store_.open(pool_, header_->value_store_block_id()); } } if (length) { - *length = cell.medium().length(); + *length = cell.medium_length(); } - return &value_store_[cell.medium().offset()] - + sizeof(BlobVectorMediumValueHeader); + return &value_store_[cell.offset()]; } case BLOB_VECTOR_LARGE: { - const BlobVectorLargeValueHeader *value_header = - static_cast<const BlobVectorLargeValueHeader *>( - pool_.get_block_address(cell.large().block_id())); + const BlobVectorValueHeader *value_header = + static_cast<const BlobVectorValueHeader *>( + pool_.get_block_address(cell.block_id())); if (length) { *length = value_header->length(); } @@ -161,28 +118,17 @@ const void *BlobVectorImpl::get_value(uint64_t id, uint64_t *length) { } } -void BlobVectorImpl::set_value(uint64_t id, const void *ptr, uint64_t length, - uint64_t capacity, - BlobVectorAttribute attribute) { - if (id > BLOB_VECTOR_MAX_ID) { - GRNXX_ERROR() << "invalid argument: id = " << id - << ", max_id = " << BLOB_VECTOR_MAX_ID; - GRNXX_THROW(); - } - +void BlobVectorImpl::set_value(uint64_t id, const void *ptr, uint64_t length) { BlobVectorCell new_cell; if (!ptr) { - new_cell = BlobVectorNullValue(attribute); + new_cell = BlobVectorCell::null_value_cell(); } else { - if (capacity < length) { - capacity = length; - } - if (capacity < BLOB_VECTOR_MEDIUM_VALUE_MIN_LENGTH) { - new_cell = BlobVectorSmallValue(ptr, length, attribute); - } else if (capacity < BLOB_VECTOR_LARGE_VALUE_MIN_LENGTH) { - new_cell = create_medium_value(id, ptr, length, capacity, attribute); + if (length < BLOB_VECTOR_MEDIUM_VALUE_MIN_LENGTH) { + new_cell = BlobVectorCell::small_value_cell(ptr, length); + } else if (length < BLOB_VECTOR_LARGE_VALUE_MIN_LENGTH) { + new_cell = create_medium_value(ptr, length); } else { - new_cell = create_large_value(id, ptr, length, capacity, attribute); + new_cell = create_large_value(ptr, length); } } @@ -190,8 +136,8 @@ void BlobVectorImpl::set_value(uint64_t id, const void *ptr, uint64_t length, BlobVectorCell old_cell; try { do { - old_cell = cells_[id]; - } while (!atomic_compare_and_swap(old_cell, new_cell, &cells_[id])); + old_cell = table_[id]; + } while (!atomic_compare_and_swap(old_cell, new_cell, &table_[id])); } catch (...) { free_value(new_cell); throw; @@ -218,14 +164,14 @@ void BlobVectorImpl::unlink(io::Pool pool, uint32_t block_id) { if (vector->header_->latest_large_value_block_id() != io::BLOCK_INVALID_ID) { uint32_t block_id = vector->header_->latest_large_value_block_id(); do { - auto value_header = static_cast<const BlobVectorLargeValueHeader *>( + auto value_header = static_cast<const BlobVectorValueHeader *>( pool.get_block_address(block_id)); const uint32_t prev_block_id = value_header->prev_value_block_id(); pool.free_block(block_id); block_id = prev_block_id; } while (block_id != vector->header_->latest_large_value_block_id()); } - Vector<BlobVectorCell>::unlink(pool, vector->header_->cells_block_id()); + BlobVectorTable::unlink(pool, vector->header_->table_block_id()); pool.free_block(vector->block_info_->id()); } @@ -234,9 +180,9 @@ BlobVectorImpl::BlobVectorImpl() block_info_(nullptr), header_(nullptr), recycler_(nullptr), - cells_(), + table_(), value_store_(), - page_infos_(), + index_store_(), inter_thread_mutex_(MUTEX_UNLOCKED) {} void BlobVectorImpl::create_vector(io::Pool pool) { @@ -244,7 +190,7 @@ void BlobVectorImpl::create_vector(io::Pool pool) { block_info_ = pool.create_block(sizeof(BlobVectorHeader)); try { - cells_ = Vector<BlobVectorCell>(VECTOR_CREATE, pool_, BlobVectorCell()); + table_.create(pool_, BlobVectorCell()); } catch (...) { pool_.free_block(*block_info_); throw; @@ -252,7 +198,7 @@ void BlobVectorImpl::create_vector(io::Pool pool) { void * const block_address = pool_.get_block_address(*block_info_); header_ = static_cast<BlobVectorHeader *>(block_address); - *header_ = BlobVectorHeader(cells_.block_id()); + *header_ = BlobVectorHeader(table_.block_id()); recycler_ = pool.mutable_recycler(); } @@ -274,50 +220,42 @@ void BlobVectorImpl::open_vector(io::Pool pool, uint32_t block_id) { recycler_ = pool.mutable_recycler(); // Open the core table. - cells_ = Vector<BlobVectorCell>(VECTOR_OPEN, pool, - header_->cells_block_id()); + table_.open(pool, header_->table_block_id()); } -BlobVectorMediumValue BlobVectorImpl::create_medium_value( - uint32_t id, const void *ptr, uint64_t length, uint64_t capacity, - BlobVectorAttribute attribute) { +BlobVectorCell BlobVectorImpl::create_medium_value(const void *ptr, + uint64_t length) { Lock lock(mutable_inter_thread_mutex()); if (!value_store_) { if (header_->value_store_block_id() == io::BLOCK_INVALID_ID) { Lock lock(mutable_inter_process_mutex()); if (header_->value_store_block_id() == io::BLOCK_INVALID_ID) { - value_store_ = BlobVectorValueStore(VECTOR_CREATE, pool_); + value_store_.create(pool_); header_->set_value_store_block_id(value_store_.block_id()); } } if (!value_store_) { - value_store_ = BlobVectorValueStore( - VECTOR_OPEN, pool_, header_->value_store_block_id()); + value_store_.open(pool_, header_->value_store_block_id()); } } - if (!page_infos_) { - if (header_->page_infos_block_id() == io::BLOCK_INVALID_ID) { + if (!index_store_) { + if (header_->index_store_block_id() == io::BLOCK_INVALID_ID) { Lock lock(mutable_inter_process_mutex()); - if (header_->page_infos_block_id() == io::BLOCK_INVALID_ID) { - page_infos_ = Vector<BlobVectorPageInfo>( - VECTOR_CREATE, pool_, BlobVectorPageInfo()); - header_->set_page_infos_block_id(page_infos_.block_id()); + if (header_->index_store_block_id() == io::BLOCK_INVALID_ID) { + index_store_.create(pool_, BlobVectorPageInfo()); + header_->set_index_store_block_id(index_store_.block_id()); } } - if (!page_infos_) { - page_infos_ = Vector<BlobVectorPageInfo>( - VECTOR_OPEN, pool_, header_->page_infos_block_id()); + if (!index_store_) { + index_store_.open(pool_, header_->index_store_block_id()); } } // Unfreeze the oldest frozen page for reuse. unfreeze_oldest_frozen_page(); - capacity = (capacity + (BLOB_VECTOR_UNIT_SIZE - 1)) & - ~(BLOB_VECTOR_UNIT_SIZE - 1); - uint64_t offset = header_->next_value_offset(); const uint64_t offset_in_page = ((offset - 1) & (BLOB_VECTOR_VALUE_STORE_PAGE_SIZE - 1)) + 1; @@ -325,14 +263,12 @@ BlobVectorMediumValue BlobVectorImpl::create_medium_value( BLOB_VECTOR_VALUE_STORE_PAGE_SIZE - offset_in_page; // Reserve a new page if there is not enough space in the current page. - const uint64_t required_size = - capacity + sizeof(BlobVectorMediumValueHeader); - if (required_size > size_left_in_page) { + if (length > size_left_in_page) { if (offset != 0) { // Freeze the current page if it is empty. const uint32_t page_id = static_cast<uint32_t>( (offset - 1) >> BLOB_VECTOR_VALUE_STORE_PAGE_SIZE_BITS); - if (page_infos_[page_id].num_values() == 0) { + if (index_store_[page_id].num_values() == 0) { freeze_page(page_id); } } @@ -340,40 +276,35 @@ BlobVectorMediumValue BlobVectorImpl::create_medium_value( const uint32_t page_id = header_->next_page_id(); offset = static_cast<uint64_t>( page_id << BLOB_VECTOR_VALUE_STORE_PAGE_SIZE_BITS); - if (page_infos_[page_id].next_page_id() != BLOB_VECTOR_INVALID_PAGE_ID) { - header_->set_next_page_id(page_infos_[page_id].next_page_id()); + if (index_store_[page_id].next_page_id() != BLOB_VECTOR_INVALID_PAGE_ID) { + header_->set_next_page_id(index_store_[page_id].next_page_id()); } else { header_->set_next_page_id(page_id + 1); } - page_infos_[page_id].set_num_values(0); + index_store_[page_id].set_num_values(0); } - header_->set_next_value_offset(offset + required_size); + header_->set_next_value_offset(offset + length); - auto value_header = reinterpret_cast<BlobVectorMediumValueHeader *>( - &value_store_[offset]); - value_header->set_value_id(id); - value_header->set_capacity(capacity); - std::memcpy(value_header + 1, ptr, length); + std::memcpy(&value_store_[offset], ptr, length); const uint32_t page_id = static_cast<uint32_t>( offset >> BLOB_VECTOR_VALUE_STORE_PAGE_SIZE_BITS); - page_infos_[page_id].set_num_values(page_infos_[page_id].num_values() + 1); + index_store_[page_id].set_num_values(index_store_[page_id].num_values() + 1); - return BlobVectorMediumValue(offset, length, attribute); + return BlobVectorCell::medium_value_cell(offset, length); } -BlobVectorLargeValue BlobVectorImpl::create_large_value( - uint32_t, const void *ptr, uint64_t length, uint64_t capacity, - BlobVectorAttribute attribute) { +BlobVectorCell BlobVectorImpl::create_large_value(const void *ptr, + uint64_t length) { const io::BlockInfo *block_info = - pool_.create_block(sizeof(BlobVectorLargeValueHeader) + capacity); - BlobVectorLargeValueHeader *value_header = - static_cast<BlobVectorLargeValueHeader *>( + pool_.create_block(sizeof(BlobVectorValueHeader) + length); + BlobVectorValueHeader *value_header = + static_cast<BlobVectorValueHeader *>( pool_.get_block_address(*block_info)); value_header->set_length(length); std::memcpy(value_header + 1, ptr, length); register_large_value(block_info->id(), value_header); - return BlobVectorLargeValue(block_info->id(), attribute); + return BlobVectorCell::large_value_cell(block_info->id()); } void BlobVectorImpl::free_value(BlobVectorCell cell) { @@ -386,10 +317,10 @@ void BlobVectorImpl::free_value(BlobVectorCell cell) { Lock lock(mutable_inter_thread_mutex()); const uint32_t page_id = static_cast<uint32_t>( - cell.medium().offset() >> BLOB_VECTOR_VALUE_STORE_PAGE_SIZE_BITS); - page_infos_[page_id].set_num_values( - page_infos_[page_id].num_values() - 1); - if (page_infos_[page_id].num_values() == 0) { + cell.offset() >> BLOB_VECTOR_VALUE_STORE_PAGE_SIZE_BITS); + index_store_[page_id].set_num_values( + index_store_[page_id].num_values() - 1); + if (index_store_[page_id].num_values() == 0) { const uint32_t current_page_id = static_cast<uint32_t>(header_->next_value_offset() >> BLOB_VECTOR_VALUE_STORE_PAGE_SIZE_BITS); @@ -401,9 +332,9 @@ void BlobVectorImpl::free_value(BlobVectorCell cell) { } case BLOB_VECTOR_LARGE: { const io::BlockInfo * const block_info = - pool_.get_block_info(cell.large().block_id()); + pool_.get_block_info(cell.block_id()); unregister_large_value(block_info->id(), - static_cast<BlobVectorLargeValueHeader *>( + static_cast<BlobVectorValueHeader *>( pool_.get_block_address(*block_info))); pool_.free_block(*block_info); break; @@ -412,17 +343,17 @@ void BlobVectorImpl::free_value(BlobVectorCell cell) { } void BlobVectorImpl::register_large_value(uint32_t block_id, - BlobVectorLargeValueHeader *value_header) { + BlobVectorValueHeader *value_header) { Lock lock(mutable_inter_process_mutex()); if (header_->latest_large_value_block_id() == io::BLOCK_INVALID_ID) { value_header->set_next_value_block_id(block_id); value_header->set_prev_value_block_id(block_id); } else { const uint32_t prev_id = header_->latest_large_value_block_id(); - auto prev_header = static_cast<BlobVectorLargeValueHeader *>( + auto prev_header = static_cast<BlobVectorValueHeader *>( pool_.get_block_address(prev_id)); const uint32_t next_id = prev_header->next_value_block_id(); - auto next_header = static_cast<BlobVectorLargeValueHeader *>( + auto next_header = static_cast<BlobVectorValueHeader *>( pool_.get_block_address(next_id)); value_header->set_next_value_block_id(next_id); value_header->set_prev_value_block_id(prev_id); @@ -433,13 +364,13 @@ void BlobVectorImpl::register_large_value(uint32_t block_id, } void BlobVectorImpl::unregister_large_value(uint32_t block_id, - BlobVectorLargeValueHeader *value_header) { + BlobVectorValueHeader *value_header) { Lock lock(mutable_inter_process_mutex()); const uint32_t next_id = value_header->next_value_block_id(); const uint32_t prev_id = value_header->prev_value_block_id(); - auto next_header = static_cast<BlobVectorLargeValueHeader *>( + auto next_header = static_cast<BlobVectorValueHeader *>( pool_.get_block_address(next_id)); - auto prev_header = static_cast<BlobVectorLargeValueHeader *>( + auto prev_header = static_cast<BlobVectorValueHeader *>( pool_.get_block_address(prev_id)); next_header->set_prev_value_block_id(prev_id); prev_header->set_next_value_block_id(next_id); @@ -449,10 +380,10 @@ void BlobVectorImpl::unregister_large_value(uint32_t block_id, } void BlobVectorImpl::freeze_page(uint32_t page_id) { - BlobVectorPageInfo &page_info = page_infos_[page_id]; + BlobVectorPageInfo &page_info = index_store_[page_id]; if (header_->latest_frozen_page_id() != BLOB_VECTOR_INVALID_PAGE_ID) { BlobVectorPageInfo &latest_frozen_page_info = - page_infos_[header_->latest_frozen_page_id()]; + index_store_[header_->latest_frozen_page_id()]; page_info.set_next_page_id(latest_frozen_page_info.next_page_id()); latest_frozen_page_info.set_next_page_id(page_id); } else { @@ -465,11 +396,11 @@ void BlobVectorImpl::freeze_page(uint32_t page_id) { void BlobVectorImpl::unfreeze_oldest_frozen_page() { if (header_->latest_frozen_page_id() != BLOB_VECTOR_INVALID_PAGE_ID) { BlobVectorPageInfo &latest_frozen_page_info = - page_infos_[header_->latest_frozen_page_id()]; + index_store_[header_->latest_frozen_page_id()]; const uint32_t oldest_frozen_page_id = latest_frozen_page_info.next_page_id(); BlobVectorPageInfo &oldest_frozen_page_info = - page_infos_[oldest_frozen_page_id]; + index_store_[oldest_frozen_page_id]; if (recycler_->check(oldest_frozen_page_info.stamp())) { latest_frozen_page_info.set_next_page_id( oldest_frozen_page_info.next_page_id()); Modified: lib/alpha/blob_vector.hpp (+68 -184) =================================================================== --- lib/alpha/blob_vector.hpp 2012-12-09 21:33:21 +0900 (5afed2d) +++ lib/alpha/blob_vector.hpp 2012-12-10 00:59:07 +0900 (e023e6c) @@ -54,26 +54,21 @@ const uint64_t BLOB_VECTOR_VALUE_STORE_TABLE_SIZE = const uint64_t BLOB_VECTOR_VALUE_STORE_SECONDARY_TABLE_SIZE = uint64_t(1) << BLOB_VECTOR_VALUE_STORE_SECONDARY_TABLE_SIZE_BITS; -typedef Vector<char, BLOB_VECTOR_VALUE_STORE_PAGE_SIZE, - BLOB_VECTOR_VALUE_STORE_TABLE_SIZE, - BLOB_VECTOR_VALUE_STORE_SECONDARY_TABLE_SIZE> -BlobVectorValueStore; - extern class BlobVectorCreate {} BLOB_VECTOR_CREATE; extern class BlobVectorOpen {} BLOB_VECTOR_OPEN; class BlobVectorHeader { public: - explicit BlobVectorHeader(uint32_t cells_block_id); + explicit BlobVectorHeader(uint32_t table_block_id); - uint32_t cells_block_id() const { - return cells_block_id_; + uint32_t table_block_id() const { + return table_block_id_; } uint32_t value_store_block_id() const { return value_store_block_id_; } - uint32_t page_infos_block_id() const { - return page_infos_block_id_; + uint32_t index_store_block_id() const { + return index_store_block_id_; } uint32_t next_page_id() const { return next_page_id_; @@ -91,8 +86,8 @@ class BlobVectorHeader { void set_value_store_block_id(uint32_t value) { value_store_block_id_ = value; } - void set_page_infos_block_id(uint32_t value) { - page_infos_block_id_ = value; + void set_index_store_block_id(uint32_t value) { + index_store_block_id_ = value; } void set_next_page_id(uint32_t value) { next_page_id_ = value; @@ -114,9 +109,9 @@ class BlobVectorHeader { StringBuilder &write_to(StringBuilder &builder) const; private: - uint32_t cells_block_id_; + uint32_t table_block_id_; uint32_t value_store_block_id_; - uint32_t page_infos_block_id_; + uint32_t index_store_block_id_; uint32_t next_page_id_; uint64_t next_value_offset_; uint32_t latest_frozen_page_id_; @@ -129,7 +124,7 @@ inline StringBuilder &operator<<(StringBuilder &builder, return header.write_to(builder); } -enum BlobVectorType : uint8_t { +enum BlobVectorValueType : uint8_t { BLOB_VECTOR_NULL = 0x00, BLOB_VECTOR_SMALL = 0x10, BLOB_VECTOR_MEDIUM = 0x20, @@ -138,8 +133,6 @@ enum BlobVectorType : uint8_t { const uint8_t BLOB_VECTOR_TYPE_MASK = 0x30; -StringBuilder &operator<<(StringBuilder &builder, BlobVectorType type); - class BlobVectorPageInfo { public: BlobVectorPageInfo() @@ -174,32 +167,7 @@ class BlobVectorPageInfo { uint16_t reserved_; }; -class BlobVectorMediumValueHeader { - public: - uint64_t value_id() const { - return dwords_[0] | (static_cast<uint64_t>(bytes_[4]) << 32); - } - uint64_t capacity() const { - return static_cast<uint64_t>(words_[3]) << BLOB_VECTOR_UNIT_SIZE_BITS; - } - - void set_value_id(uint64_t value) { - dwords_[0] = static_cast<uint32_t>(value); - bytes_[4] = static_cast<uint8_t>(value >> 32); - } - void set_capacity(uint64_t value) { - words_[3] = static_cast<uint16_t>(value >> BLOB_VECTOR_UNIT_SIZE_BITS); - } - - private: - union { - uint8_t bytes_[8]; - uint16_t words_[4]; - uint32_t dwords_[2]; - }; -}; - -class BlobVectorLargeValueHeader { +class BlobVectorValueHeader { public: uint64_t length() const { return length_; @@ -227,68 +195,52 @@ class BlobVectorLargeValueHeader { uint32_t prev_value_block_id_; }; -// TODO: Not implemented yet. -enum BlobVectorAttribute : uint8_t { - BLOB_VECTOR_APPENDABLE = 0x00, - BLOB_VECTOR_PREPENDABLE = 0x40 -}; - -const uint8_t BLOB_VECTOR_ATTRIBUTE_MASK = 0x40; - -StringBuilder &operator<<(StringBuilder &builder, - BlobVectorAttribute attribute); - const uint8_t BLOB_VECTOR_CELL_FLAGS_MASK = 0xF0; -class BlobVectorNullValue { +class BlobVectorCell { public: - explicit BlobVectorNullValue(BlobVectorAttribute attribute) - : qword_(0) { - bytes_[0] = BLOB_VECTOR_NULL | attribute; - } + constexpr BlobVectorCell() : qword_(0) {} - private: - union { - uint8_t bytes_[8]; - uint64_t qword_; - }; -}; + static constexpr BlobVectorCell null_value_cell() { + return BlobVectorCell(); + } + static BlobVectorCell small_value_cell(const void *ptr, uint64_t length) { + BlobVectorCell cell; + cell.bytes_[0] = BLOB_VECTOR_SMALL | static_cast<uint8_t>(length); + std::memcpy(&cell.bytes_[1], ptr, length); + return cell; + } + static BlobVectorCell medium_value_cell(uint64_t offset, uint64_t length) { + BlobVectorCell cell; + cell.bytes_[0] = BLOB_VECTOR_MEDIUM | static_cast<uint8_t>(offset >> 40); + cell.bytes_[1] = static_cast<uint8_t>(offset >> 32); + cell.words_[1] = static_cast<uint16_t>(length); + cell.dwords_[1] = static_cast<uint32_t>(offset); + return cell; + } + static BlobVectorCell large_value_cell(uint32_t block_id) { + BlobVectorCell cell; + cell.bytes_[0] = BLOB_VECTOR_LARGE; + cell.dwords_[1] = block_id; + return cell; + } -class BlobVectorSmallValue { - public: - BlobVectorSmallValue(const void *ptr, uint64_t length, - BlobVectorAttribute attribute) : qword_(0) { - bytes_[0] = BLOB_VECTOR_SMALL | attribute | - static_cast<uint8_t>(length); - std::memcpy(&bytes_[1], ptr, length); + BlobVectorValueType type() const { + Flags flags; + flags.byte = flags_.byte & BLOB_VECTOR_TYPE_MASK; + return flags.type; } - uint64_t length() const { + // Accessors to small values. + uint64_t small_length() const { return bytes_[0] & ~BLOB_VECTOR_CELL_FLAGS_MASK; } const void *value() const { return &bytes_[1]; } - private: - union { - uint8_t bytes_[8]; - uint64_t qword_; - }; -}; - -class BlobVectorMediumValue { - public: - BlobVectorMediumValue(uint64_t offset, uint64_t length, - BlobVectorAttribute attribute) : qword_(0) { - bytes_[0] = BLOB_VECTOR_MEDIUM | attribute | - static_cast<uint8_t>(offset >> 40); - bytes_[1] = static_cast<uint8_t>(offset >> 32); - words_[1] = static_cast<uint16_t>(length); - dwords_[1] = static_cast<uint32_t>(offset); - } - - uint64_t length() const { + // Accessors to medium values. + uint64_t medium_length() const { return words_[1]; } uint64_t offset() const { @@ -297,102 +249,41 @@ class BlobVectorMediumValue { (static_cast<uint64_t>(bytes_[1]) << 32) | dwords_[1]; } - private: - union { - uint8_t bytes_[8]; - uint16_t words_[4]; - uint32_t dwords_[2]; - uint64_t qword_; - }; -}; - -class BlobVectorLargeValue { - public: - BlobVectorLargeValue(uint32_t block_id, - BlobVectorAttribute attribute) : qword_(0) { - bytes_[0] = BLOB_VECTOR_LARGE | attribute; - dwords_[1] = block_id; - } - + // Accessors to large values. uint32_t block_id() const { return dwords_[1]; } private: - union { - uint8_t bytes_[8]; - uint32_t dwords_[2]; - uint64_t qword_; - }; -}; - -class BlobVectorCell { - public: - BlobVectorCell() : qword_(0) {} - - BlobVectorCell &operator=(const BlobVectorNullValue &rhs) { - null_value_ = rhs; - return *this; - } - BlobVectorCell &operator=(const BlobVectorSmallValue &rhs) { - small_value_ = rhs; - return *this; - } - BlobVectorCell &operator=(const BlobVectorMediumValue &rhs) { - medium_value_ = rhs; - return *this; - } - BlobVectorCell &operator=(const BlobVectorLargeValue &rhs) { - large_value_ = rhs; - return *this; - } - - BlobVectorType type() const { - Flags flags; - flags.byte = flags_.byte & BLOB_VECTOR_TYPE_MASK; - return flags.type; - } - BlobVectorAttribute attribute() const { - Flags flags; - flags.byte = flags_.byte & BLOB_VECTOR_ATTRIBUTE_MASK; - return flags.attribute; - }; - - const BlobVectorNullValue &null() const { - return null_value_; - } - const BlobVectorSmallValue &small() const { - return small_value_; - } - const BlobVectorMediumValue &medium() const { - return medium_value_; - } - const BlobVectorLargeValue &large() const { - return large_value_; - } - - StringBuilder &write_to(StringBuilder &builder) const; - - private: union Flags { uint8_t byte; - BlobVectorType type; - BlobVectorAttribute attribute; + BlobVectorValueType type; }; union { Flags flags_; + uint8_t bytes_[8]; + uint16_t words_[4]; + uint32_t dwords_[2]; uint64_t qword_; - BlobVectorNullValue null_value_; - BlobVectorSmallValue small_value_; - BlobVectorMediumValue medium_value_; - BlobVectorLargeValue large_value_; }; }; static_assert(sizeof(BlobVectorCell) == sizeof(uint64_t), "sizeof(BlobVectorCell) != sizeof(uint64_t)"); +typedef Vector<BlobVectorCell> BlobVectorTable; + +typedef Vector<char, BLOB_VECTOR_VALUE_STORE_PAGE_SIZE, + BLOB_VECTOR_VALUE_STORE_TABLE_SIZE, + BLOB_VECTOR_VALUE_STORE_SECONDARY_TABLE_SIZE> +BlobVectorValueStore; + +typedef Vector<BlobVectorPageInfo, + BLOB_VECTOR_VALUE_STORE_TABLE_SIZE, + BLOB_VECTOR_VALUE_STORE_SECONDARY_TABLE_SIZE> +BlobVectorIndexStore; + class BlobVectorImpl { public: static std::unique_ptr<BlobVectorImpl> create(io::Pool pool); @@ -400,10 +291,7 @@ class BlobVectorImpl { uint32_t block_id); const void *get_value(uint64_t id, uint64_t *length); - - void set_value(uint64_t id, const void *ptr, uint64_t length, - uint64_t capacity = 0, - BlobVectorAttribute attribute = BLOB_VECTOR_APPENDABLE); + void set_value(uint64_t id, const void *ptr, uint64_t length); // TODO @@ -420,9 +308,9 @@ class BlobVectorImpl { const io::BlockInfo *block_info_; BlobVectorHeader *header_; Recycler *recycler_; - Vector<BlobVectorCell> cells_; + BlobVectorTable table_; BlobVectorValueStore value_store_; - Vector<BlobVectorPageInfo> page_infos_; + BlobVectorIndexStore index_store_; Mutex inter_thread_mutex_; BlobVectorImpl(); @@ -430,19 +318,15 @@ class BlobVectorImpl { void create_vector(io::Pool pool); void open_vector(io::Pool pool, uint32_t block_id); - BlobVectorMediumValue create_medium_value( - uint32_t id, const void *ptr, uint64_t length, uint64_t capacity, - BlobVectorAttribute attribute); - BlobVectorLargeValue create_large_value( - uint32_t id, const void *ptr, uint64_t length, uint64_t capacity, - BlobVectorAttribute attribute); + BlobVectorCell create_medium_value(const void *ptr, uint64_t length); + BlobVectorCell create_large_value(const void *ptr, uint64_t length); void free_value(BlobVectorCell cell); void register_large_value(uint32_t block_id, - BlobVectorLargeValueHeader *value_header); + BlobVectorValueHeader *value_header); void unregister_large_value(uint32_t block_id, - BlobVectorLargeValueHeader *value_header); + BlobVectorValueHeader *value_header); void freeze_page(uint32_t page_id); void unfreeze_oldest_frozen_page(); -------------- next part -------------- HTML����������������������������...Download