susumu.yata
null+****@clear*****
Mon Dec 3 17:40:38 JST 2012
susumu.yata 2012-12-03 17:40:38 +0900 (Mon, 03 Dec 2012) New Revision: 92102334642df1462de058f25209de271e7cc037 https://github.com/groonga/grnxx/commit/92102334642df1462de058f25209de271e7cc037 Log: Implement grnxx::alpha::BlobVector::unlink(). Modified files: lib/alpha/blob_vector.cpp lib/alpha/blob_vector.hpp Modified: lib/alpha/blob_vector.cpp (+71 -10) =================================================================== --- lib/alpha/blob_vector.cpp 2012-12-01 18:21:16 +0900 (8448216) +++ lib/alpha/blob_vector.cpp 2012-12-03 17:40:38 +0900 (ba74a54) @@ -26,6 +26,7 @@ namespace alpha { BlobVectorHeader::BlobVectorHeader(uint32_t cells_block_id) : cells_block_id_(cells_block_id), + latest_large_value_block_id_(io::BLOCK_INVALID_ID), inter_process_mutex_() {} StringBuilder &operator<<(StringBuilder &builder, BlobVectorType type) { @@ -112,12 +113,13 @@ const void *BlobVectorImpl::get_value(uint64_t id, uint64_t *length) { return nullptr; } case BLOB_VECTOR_LARGE: { - void * const block_address = - pool_.get_block_address(cell.large().block_id()); + const BlobVectorLargeValueHeader *value_header = + static_cast<const BlobVectorLargeValueHeader *>( + pool_.get_block_address(cell.large().block_id())); if (length) { - *length = *static_cast<uint64_t *>(block_address); + *length = value_header->length(); } - return static_cast<uint64_t *>(block_address) + 1; + return value_header + 1; } default: { GRNXX_ERROR() << "invalid value type"; @@ -177,10 +179,13 @@ BlobVectorLargeValue BlobVectorImpl::create_large_value( const void *ptr, uint64_t length, uint64_t capacity, BlobVectorAttribute attribute) { const io::BlockInfo *block_info = - pool_.create_block(sizeof(uint64_t) + capacity); - void * const block_address = pool_.get_block_address(*block_info); - *static_cast<uint64_t *>(block_address) = length; - std::memcpy(static_cast<uint64_t *>(block_address) + 1, ptr, length); + pool_.create_block(sizeof(BlobVectorLargeValueHeader) + capacity); + BlobVectorLargeValueHeader *value_header = + static_cast<BlobVectorLargeValueHeader *>( + 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); } @@ -194,12 +199,54 @@ void BlobVectorImpl::free_value(BlobVectorCell cell) { break; } case BLOB_VECTOR_LARGE: { - pool_.free_block(cell.large().block_id()); + const io::BlockInfo * const block_info = + pool_.get_block_info(cell.large().block_id()); + unregister_large_value(block_info->id(), + static_cast<BlobVectorLargeValueHeader *>( + pool_.get_block_address(*block_info))); + pool_.free_block(*block_info); break; } } } +void BlobVectorImpl::register_large_value(uint32_t block_id, + BlobVectorLargeValueHeader *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 *>( + pool_.get_block_address(prev_id)); + const uint32_t next_id = prev_header->next_value_block_id(); + auto next_header = static_cast<BlobVectorLargeValueHeader *>( + pool_.get_block_address(next_id)); + value_header->set_next_value_block_id(next_id); + value_header->set_prev_value_block_id(prev_id); + prev_header->set_next_value_block_id(block_id); + next_header->set_prev_value_block_id(block_id); + } + header_->set_latest_large_value_block_id(block_id); +} + +void BlobVectorImpl::unregister_large_value(uint32_t block_id, + BlobVectorLargeValueHeader *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 *>( + pool_.get_block_address(next_id)); + auto prev_header = static_cast<BlobVectorLargeValueHeader *>( + pool_.get_block_address(prev_id)); + next_header->set_prev_value_block_id(prev_id); + prev_header->set_next_value_block_id(next_id); + if (block_id == header_->latest_large_value_block_id()) { + header_->set_latest_large_value_block_id(prev_id); + } +} + StringBuilder &BlobVectorImpl::write_to(StringBuilder &builder) const { if (!builder) { return builder; @@ -210,7 +257,21 @@ StringBuilder &BlobVectorImpl::write_to(StringBuilder &builder) const { } void BlobVectorImpl::unlink(io::Pool pool, uint32_t block_id) { - // TODO + 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() Modified: lib/alpha/blob_vector.hpp (+48 -0) =================================================================== --- lib/alpha/blob_vector.hpp 2012-12-01 18:21:16 +0900 (37f6d9c) +++ lib/alpha/blob_vector.hpp 2012-12-03 17:40:38 +0900 (e4c7109) @@ -64,6 +64,13 @@ class BlobVectorHeader { uint32_t cells_block_id() const { return cells_block_id_; } + uint32_t latest_large_value_block_id() const { + return latest_large_value_block_id_; + } + + void set_latest_large_value_block_id(uint32_t value) { + latest_large_value_block_id_ = value; + } Mutex *mutable_inter_process_mutex() { return &inter_process_mutex_; @@ -71,6 +78,7 @@ class BlobVectorHeader { private: uint32_t cells_block_id_; + uint32_t latest_large_value_block_id_; Mutex inter_process_mutex_; }; @@ -85,6 +93,34 @@ const uint8_t BLOB_VECTOR_TYPE_MASK = 0x30; StringBuilder &operator<<(StringBuilder &builder, BlobVectorType type); +class BlobVectorLargeValueHeader { + public: + uint64_t length() const { + return length_; + } + uint32_t next_value_block_id() const { + return next_value_block_id_; + } + uint32_t prev_value_block_id() const { + return prev_value_block_id_; + } + + void set_length(uint64_t value) { + length_ = value; + } + void set_next_value_block_id(uint32_t value) { + next_value_block_id_ = value; + } + void set_prev_value_block_id(uint32_t value) { + prev_value_block_id_ = value; + } + + private: + uint64_t length_; + uint32_t next_value_block_id_; + uint32_t prev_value_block_id_; +}; + // TODO: Not implemented yet. enum BlobVectorAttribute : uint8_t { BLOB_VECTOR_APPENDABLE = 0x00, @@ -294,6 +330,18 @@ class BlobVectorImpl { BlobVectorAttribute attribute); void free_value(BlobVectorCell cell); + + void register_large_value(uint32_t block_id, + BlobVectorLargeValueHeader *value_header); + void unregister_large_value(uint32_t block_id, + BlobVectorLargeValueHeader *value_header); + + Mutex *mutable_inter_thread_mutex() { + return &inter_thread_mutex_; + } + Mutex *mutable_inter_process_mutex() { + return header_->mutable_inter_process_mutex(); + } }; inline StringBuilder &operator<<(StringBuilder &builder, -------------- next part -------------- HTML����������������������������... ダウンロード