susumu.yata
null+****@clear*****
Tue Dec 4 12:42:54 JST 2012
susumu.yata 2012-12-04 12:42:54 +0900 (Tue, 04 Dec 2012) New Revision: fde2a9b30d001eca5fe2cd32a1bb2aed6c316677 https://github.com/groonga/grnxx/commit/fde2a9b30d001eca5fe2cd32a1bb2aed6c316677 Log: Implement medium values of grnxx::alpha::BlobVector. Modified files: lib/alpha/blob_vector.cpp lib/alpha/blob_vector.hpp Modified: lib/alpha/blob_vector.cpp (+125 -84) =================================================================== --- lib/alpha/blob_vector.cpp 2012-12-04 11:24:13 +0900 (ba74a54) +++ lib/alpha/blob_vector.cpp 2012-12-04 12:42:54 +0900 (fa9ceb0) @@ -26,6 +26,8 @@ namespace alpha { BlobVectorHeader::BlobVectorHeader(uint32_t cells_block_id) : cells_block_id_(cells_block_id), + value_store_block_id_(io::BLOCK_INVALID_ID), + next_medium_value_offset_(0), latest_large_value_block_id_(io::BLOCK_INVALID_ID), inter_process_mutex_() {} @@ -109,8 +111,17 @@ const void *BlobVectorImpl::get_value(uint64_t id, uint64_t *length) { return cells_[id].small().value(); } case BLOB_VECTOR_MEDIUM: { - // TODO: Not implemented yet. - return nullptr; + if (!value_store_) { + Lock lock(mutable_inter_thread_mutex()); + if (!value_store_) { + value_store_ = BlobVectorValueStore( + VECTOR_OPEN, pool_, header_->value_store_block_id()); + } + } + if (length) { + *length = cell.medium().length(); + } + return &value_store_[cell.medium().offset()]; } case BLOB_VECTOR_LARGE: { const BlobVectorLargeValueHeader *value_header = @@ -147,9 +158,9 @@ void BlobVectorImpl::set_value(uint64_t id, const void *ptr, uint64_t 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(ptr, length, capacity, attribute); + new_cell = create_medium_value(id, ptr, length, capacity, attribute); } else { - new_cell = create_large_value(ptr, length, capacity, attribute); + new_cell = create_large_value(id, ptr, length, capacity, attribute); } } @@ -166,17 +177,121 @@ void BlobVectorImpl::set_value(uint64_t id, const void *ptr, uint64_t length, free_value(old_cell); } +StringBuilder &BlobVectorImpl::write_to(StringBuilder &builder) const { + if (!builder) { + return builder; + } + + // TODO + return builder; +} + +void BlobVectorImpl::unlink(io::Pool pool, uint32_t block_id) { + std::unique_ptr<BlobVectorImpl> vector = + BlobVectorImpl::open(pool, 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 *>( + 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()); + pool.free_block(vector->block_info_->id()); +} + +BlobVectorImpl::BlobVectorImpl() + : pool_(), + block_info_(nullptr), + header_(nullptr), + recycler_(nullptr), + cells_(), + value_store_(), + inter_thread_mutex_() {} + +void BlobVectorImpl::create_vector(io::Pool pool) { + pool_ = pool; + block_info_ = pool.create_block(sizeof(BlobVectorHeader)); + + try { + cells_ = Vector<BlobVectorCell>(VECTOR_CREATE, pool_, BlobVectorCell()); + } catch (...) { + pool_.free_block(*block_info_); + throw; + } + + void * const block_address = pool_.get_block_address(*block_info_); + header_ = static_cast<BlobVectorHeader *>(block_address); + *header_ = BlobVectorHeader(cells_.block_id()); + + recycler_ = pool.mutable_recycler(); +} + +void BlobVectorImpl::open_vector(io::Pool pool, uint32_t block_id) { + pool_ = pool; + block_info_ = pool.get_block_info(block_id); + if (block_info_->size() < sizeof(BlobVectorHeader)) { + GRNXX_ERROR() << "invalid argument: block_info = " << *block_info_ + << ", header_size = " << sizeof(BlobVectorHeader); + GRNXX_THROW(); + } + + void * const block_address = pool_.get_block_address(*block_info_); + header_ = static_cast<BlobVectorHeader *>(block_address); + + // TODO: Check the format! + + recycler_ = pool.mutable_recycler(); + + // Open the core table. + cells_ = Vector<BlobVectorCell>(VECTOR_OPEN, pool, + header_->cells_block_id()); +} + BlobVectorMediumValue BlobVectorImpl::create_medium_value( - const void *ptr, uint64_t length, uint64_t capacity, + uint32_t id, const void *ptr, uint64_t length, uint64_t capacity, BlobVectorAttribute attribute) { - // TODO: Not implemented yet. - capacity = (capacity + (BLOB_VECTOR_MEDIUM_VALUE_UNIT_SIZE - 1)) & - ~(BLOB_VECTOR_MEDIUM_VALUE_UNIT_SIZE - 1); - return BlobVectorMediumValue(0, length, attribute); + if (!value_store_) { + Lock lock(mutable_inter_thread_mutex()); + if (!value_store_) { + value_store_ = BlobVectorValueStore( + VECTOR_OPEN, pool_, header_->value_store_block_id()); + } + } + + // TODO: Lock. + + capacity = (capacity + (BLOB_VECTOR_UNIT_SIZE - 1)) & + ~(BLOB_VECTOR_UNIT_SIZE - 1); + + uint64_t offset = header_->next_medium_value_offset(); + const uint64_t offset_in_page = + offset & (BLOB_VECTOR_VALUE_STORE_PAGE_SIZE - 1); + const uint64_t size_left_in_page = + BLOB_VECTOR_VALUE_STORE_PAGE_SIZE - offset_in_page; + + const uint64_t required_size = + capacity + sizeof(BlobVectorMediumValueHeader); + if (required_size > size_left_in_page) { + offset += size_left_in_page; + } + header_->set_next_medium_value_offset(offset + required_size); + + 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); + + return BlobVectorMediumValue(offset, length, attribute); } BlobVectorLargeValue BlobVectorImpl::create_large_value( - const void *ptr, uint64_t length, uint64_t capacity, + uint32_t, const void *ptr, uint64_t length, uint64_t capacity, BlobVectorAttribute attribute) { const io::BlockInfo *block_info = pool_.create_block(sizeof(BlobVectorLargeValueHeader) + capacity); @@ -247,79 +362,5 @@ void BlobVectorImpl::unregister_large_value(uint32_t block_id, } } -StringBuilder &BlobVectorImpl::write_to(StringBuilder &builder) const { - if (!builder) { - return builder; - } - - // TODO - return builder; -} - -void BlobVectorImpl::unlink(io::Pool pool, uint32_t block_id) { - std::unique_ptr<BlobVectorImpl> vector = - BlobVectorImpl::open(pool, 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 *>( - 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()); - pool.free_block(vector->block_info_->id()); -} - -BlobVectorImpl::BlobVectorImpl() - : pool_(), - block_info_(nullptr), - header_(nullptr), - recycler_(nullptr), - cells_(), - inter_thread_mutex_() {} - -void BlobVectorImpl::create_vector(io::Pool pool) { - pool_ = pool; - block_info_ = pool.create_block(sizeof(BlobVectorHeader)); - - try { - cells_ = Vector<BlobVectorCell>(VECTOR_CREATE, pool_, BlobVectorCell()); - } catch (...) { - pool_.free_block(*block_info_); - throw; - } - - void * const block_address = pool_.get_block_address(*block_info_); - header_ = static_cast<BlobVectorHeader *>(block_address); - *header_ = BlobVectorHeader(cells_.block_id()); - - recycler_ = pool.mutable_recycler(); -} - -void BlobVectorImpl::open_vector(io::Pool pool, uint32_t block_id) { - pool_ = pool; - block_info_ = pool.get_block_info(block_id); - if (block_info_->size() < sizeof(BlobVectorHeader)) { - GRNXX_ERROR() << "invalid argument: block_info = " << *block_info_ - << ", header_size = " << sizeof(BlobVectorHeader); - GRNXX_THROW(); - } - - void * const block_address = pool_.get_block_address(*block_info_); - header_ = static_cast<BlobVectorHeader *>(block_address); - - // TODO: Check the format! - - recycler_ = pool.mutable_recycler(); - - // Open the core table. - cells_ = Vector<BlobVectorCell>(VECTOR_OPEN, pool, - header_->cells_block_id()); -} - } // namespace alpha } // namespace grnxx Modified: lib/alpha/blob_vector.hpp (+39 -26) =================================================================== --- lib/alpha/blob_vector.hpp 2012-12-04 11:24:13 +0900 (a7f8dd0) +++ lib/alpha/blob_vector.hpp 2012-12-04 12:42:54 +0900 (67de484) @@ -34,25 +34,25 @@ const uint64_t BLOB_VECTOR_MEDIUM_VALUE_MAX_LENGTH = 65535; const uint64_t BLOB_VECTOR_LARGE_VALUE_MIN_LENGTH = BLOB_VECTOR_MEDIUM_VALUE_MAX_LENGTH + 1; -const uint8_t BLOB_VECTOR_MEDIUM_VALUE_UNIT_SIZE_BITS = 3; -const uint64_t BLOB_VECTOR_MEDIUM_VALUE_UNIT_SIZE = - uint64_t(1) << BLOB_VECTOR_MEDIUM_VALUE_UNIT_SIZE_BITS; - -//const uint8_t BLOB_VECTOR_MEDIUM_VALUE_STORE_PAGE_SIZE_BITS = 19; -//const uint8_t BLOB_VECTOR_MEDIUM_VALUE_STORE_TABLE_SIZE_BITS = 12; -//const uint8_t BLOB_VECTOR_MEDIUM_VALUE_STORE_SECONDARY_TABLE_SIZE_BITS = 16; - -//const uint64_t BLOB_VECTOR_MEDIUM_VALUE_STORE_PAGE_SIZE = -// uint64_t(1) << BLOB_VECTOR_MEDIUM_VALUE_STORE_PAGE_SIZE_BITS; -//const uint64_t BLOB_VECTOR_MEDIUM_VALUE_STORE_TABLE_SIZE = -// uint64_t(1) << BLOB_VECTOR_MEDIUM_VALUE_STORE_TABLE_SIZE_BITS; -//const uint64_t BLOB_VECTOR_MEDIUM_VALUE_STORE_SECONDARY_TABLE_SIZE = -// uint64_t(1) << BLOB_VECTOR_MEDIUM_VALUE_STORE_SECONDARY_TABLE_SIZE_BITS; - -//typedef Vector<char, BLOB_VECTOR_MEDIUM_VALUE_STORE_PAGE_SIZE, -// BLOB_VECTOR_MEDIUM_VALUE_STORE_TABLE_SIZE, -// BLOB_VECTOR_MEDIUM_VALUE_STORE_SECONDARY_TABLE_SIZE> -//BlobVectorMediumValueStore; +const uint8_t BLOB_VECTOR_UNIT_SIZE_BITS = 3; +const uint64_t BLOB_VECTOR_UNIT_SIZE = + uint64_t(1) << BLOB_VECTOR_UNIT_SIZE_BITS; + +const uint8_t BLOB_VECTOR_VALUE_STORE_PAGE_SIZE_BITS = 19; +const uint8_t BLOB_VECTOR_VALUE_STORE_TABLE_SIZE_BITS = 12; +const uint8_t BLOB_VECTOR_VALUE_STORE_SECONDARY_TABLE_SIZE_BITS = 16; + +const uint64_t BLOB_VECTOR_VALUE_STORE_PAGE_SIZE = + uint64_t(1) << BLOB_VECTOR_VALUE_STORE_PAGE_SIZE_BITS; +const uint64_t BLOB_VECTOR_VALUE_STORE_TABLE_SIZE = + uint64_t(1) << BLOB_VECTOR_VALUE_STORE_TABLE_SIZE_BITS; +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; @@ -64,10 +64,22 @@ class BlobVectorHeader { uint32_t cells_block_id() const { return cells_block_id_; } + uint32_t value_store_block_id() const { + return value_store_block_id_; + } + uint64_t next_medium_value_offset() const { + return next_medium_value_offset_; + } uint32_t latest_large_value_block_id() const { return latest_large_value_block_id_; } + void set_value_store_block_id(uint32_t value) { + value_store_block_id_ = value; + } + void set_next_medium_value_offset(uint64_t value) { + next_medium_value_offset_ = value; + } void set_latest_large_value_block_id(uint32_t value) { latest_large_value_block_id_ = value; } @@ -78,6 +90,8 @@ class BlobVectorHeader { private: uint32_t cells_block_id_; + uint32_t value_store_block_id_; + uint64_t next_medium_value_offset_; uint32_t latest_large_value_block_id_; Mutex inter_process_mutex_; }; @@ -85,7 +99,7 @@ class BlobVectorHeader { enum BlobVectorType : uint8_t { BLOB_VECTOR_NULL = 0x00, BLOB_VECTOR_SMALL = 0x10, - BLOB_VECTOR_MEDIUM = 0x20, // TODO: Not implemented yet. + BLOB_VECTOR_MEDIUM = 0x20, BLOB_VECTOR_LARGE = 0x30 }; @@ -99,8 +113,7 @@ class BlobVectorMediumValueHeader { return dwords_[0] | (static_cast<uint64_t>(bytes_[4]) << 32); } uint64_t capacity() const { - return static_cast<uint64_t>(words_[3]) - << BLOB_VECTOR_MEDIUM_VALUE_UNIT_SIZE_BITS; + return static_cast<uint64_t>(words_[3]) << BLOB_VECTOR_UNIT_SIZE_BITS; } void set_value_id(uint64_t value) { @@ -108,8 +121,7 @@ class BlobVectorMediumValueHeader { bytes_[4] = static_cast<uint8_t>(value >> 32); } void set_capacity(uint64_t value) { - words_[3] = static_cast<uint16_t>( - value >> BLOB_VECTOR_MEDIUM_VALUE_UNIT_SIZE_BITS); + words_[3] = static_cast<uint16_t>(value >> BLOB_VECTOR_UNIT_SIZE_BITS); } private: @@ -342,6 +354,7 @@ class BlobVectorImpl { BlobVectorHeader *header_; Recycler *recycler_; Vector<BlobVectorCell> cells_; + BlobVectorValueStore value_store_; Mutex inter_thread_mutex_; BlobVectorImpl(); @@ -350,10 +363,10 @@ class BlobVectorImpl { void open_vector(io::Pool pool, uint32_t block_id); BlobVectorMediumValue create_medium_value( - const void *ptr, uint64_t length, uint64_t capacity, + uint32_t id, const void *ptr, uint64_t length, uint64_t capacity, BlobVectorAttribute attribute); BlobVectorLargeValue create_large_value( - const void *ptr, uint64_t length, uint64_t capacity, + uint32_t id, const void *ptr, uint64_t length, uint64_t capacity, BlobVectorAttribute attribute); void free_value(BlobVectorCell cell); -------------- next part -------------- HTML����������������������������... Download