susumu.yata
null+****@clear*****
Mon Dec 17 13:41:12 JST 2012
susumu.yata 2012-12-17 13:41:12 +0900 (Mon, 17 Dec 2012) New Revision: 2e213d0b0d34824332721eb435d8c3b70f481300 https://github.com/groonga/grnxx/commit/2e213d0b0d34824332721eb435d8c3b70f481300 Log: Add grnxx::db::Vector::scan(). Modified files: lib/db/vector.cpp lib/db/vector.hpp Modified: lib/db/vector.cpp (+62 -0) =================================================================== --- lib/db/vector.cpp 2012-12-15 12:37:04 +0900 (e318e0c) +++ lib/db/vector.cpp 2012-12-17 13:41:12 +0900 (d7f4fbb) @@ -93,6 +93,68 @@ std::unique_ptr<VectorImpl> VectorImpl::open(io::Pool pool, return vector; } +bool VectorImpl::scan_pages(bool (*callback)(uint64_t page_id, + void *page_address, + void *argument), + void *argument) { + for (uint64_t page_id = 0; page_id < header_->table_size(); ++page_id) { + if (!first_table_cache_[page_id]) { + if (first_table_[page_id] == io::BLOCK_INVALID_ID) { + continue; + } + first_table_cache_[page_id] = + pool_.get_block_address(first_table_[page_id]); + } + if (!callback(page_id, first_table_cache_[page_id], argument)) { + return false; + } + } + + if (header_->secondary_table_block_id() == io::BLOCK_INVALID_ID) { + return true; + } + + if (!tables_cache_) { + if (!secondary_table_cache_) { + if (!secondary_table_) { + secondary_table_ = static_cast<uint32_t *>( + pool_.get_block_address(header_->secondary_table_block_id())); + } + initialize_secondary_table_cache(); + } + initialize_tables_cache(); + } + + for (uint64_t table_id = 0; table_id < header_->secondary_table_size(); + ++table_id) { + std::unique_ptr<void *[]> &table_cache = tables_cache_[table_id]; + if (!table_cache) { + if (secondary_table_[table_id] == io::BLOCK_INVALID_ID) { + continue; + } + secondary_table_cache_[table_id] = static_cast<uint32_t *>( + pool_.get_block_address(secondary_table_[table_id])); + initialize_table_cache(&table_cache); + } + + const uint64_t offset = table_id << table_size_bits_; + for (uint64_t page_id = 0; page_id < header_->table_size(); ++page_id) { + if (!table_cache[page_id]) { + uint32_t * const table = secondary_table_cache_[table_id]; + if (table[page_id] == io::BLOCK_INVALID_ID) { + continue; + } + table_cache[page_id] = pool_.get_block_address(table[page_id]); + } + if (!callback(offset + page_id, table_cache[page_id], argument)) { + return false; + } + } + } + + return true; +} + StringBuilder &VectorImpl::write_to(StringBuilder &builder) const { if (!builder) { return builder; Modified: lib/db/vector.hpp (+20 -0) =================================================================== --- lib/db/vector.hpp 2012-12-15 12:37:04 +0900 (20cddad) +++ lib/db/vector.hpp 2012-12-17 13:41:12 +0900 (c0210b1) @@ -136,6 +136,10 @@ class VectorImpl { return get_page_address_on_failure(page_id); } + bool scan_pages(bool (*callback)(uint64_t page_id, void *page_address, + void *argument), + void *argument); + uint32_t block_id() const { return block_info_->id(); } @@ -265,6 +269,22 @@ class Vector { return static_cast<T *>(page_address)[id % PAGE_SIZE]; } + // bool (*callback)(uint64_t id, Value *value); + template <typename Callback> + bool scan(Callback callback) { + return impl_->scan_pages( + [](uint64_t page_id, void *page_address, void *argument) -> bool { + const uint64_t offset = page_id * PAGE_SIZE; + for (uint64_t id = 0; id < PAGE_SIZE; ++id) { + if (!(*static_cast<Callback *>(argument))( + offset + id, &static_cast<Value *>(page_address)[id])) { + return false; + } + } + return true; + }, &callback); + } + uint32_t block_id() const { return impl_->block_id(); } -------------- next part -------------- HTML����������������������������...Download