susumu.yata
null+****@clear*****
Thu Dec 6 21:29:51 JST 2012
susumu.yata 2012-12-06 21:29:51 +0900 (Thu, 06 Dec 2012) New Revision: 4d49d307af145e4985ded8259f2cb2338f6e5355 https://github.com/groonga/grnxx/commit/4d49d307af145e4985ded8259f2cb2338f6e5355 Log: Update the implementation of grnxx::db::Vector. Removed files: lib/db/vector_base.cpp lib/db/vector_base.hpp Modified files: lib/db/Makefile.am lib/db/blob_vector.cpp lib/db/blob_vector.hpp lib/db/vector.hpp test/test_db_vector.cpp Modified: lib/db/Makefile.am (+2 -3) =================================================================== --- lib/db/Makefile.am 2012-12-06 20:37:22 +0900 (fdb9606) +++ lib/db/Makefile.am 2012-12-06 21:29:51 +0900 (f60574e) @@ -3,11 +3,10 @@ noinst_LTLIBRARIES = libgrnxx_db.la libgrnxx_db_la_SOURCES = \ array.cpp \ blob_vector.cpp \ - vector_base.cpp + vector.cpp libgrnxx_db_includedir = ${includedir}/grnxx/db libgrnxx_db_include_HEADERS = \ array.hpp \ blob_vector.hpp \ - vector.hpp \ - vector_base.hpp + vector.hpp Modified: lib/db/blob_vector.cpp (+19 -17) =================================================================== --- lib/db/blob_vector.cpp 2012-12-06 20:37:22 +0900 (f762202) +++ lib/db/blob_vector.cpp 2012-12-06 21:29:51 +0900 (09a4875) @@ -19,6 +19,8 @@ #include <ostream> +#include "../exception.hpp" +#include "../logger.hpp" #include "../lock.hpp" namespace grnxx { @@ -129,7 +131,7 @@ const void *BlobVector::get_value_address(uint64_t id, uint64_t *length) { const uint8_t store_id = cell.medium_value_cell().store_id(); const uint64_t offset = cell.medium_value_cell().offset(); BlobVectorMediumValueStore &store = medium_value_stores_[store_id]; - if (!store.is_open()) { + if (!store) { open_medium_value_store(store_id); } return &store[offset]; @@ -139,7 +141,7 @@ const void *BlobVector::get_value_address(uint64_t id, uint64_t *length) { *length = cell.large_value_cell().length(); } const uint64_t offset = cell.large_value_cell().offset(); - if (!large_value_store_.is_open()) { + if (!large_value_store_) { open_large_value_store(); } return get_large_value_header(offset)->value(); @@ -220,7 +222,7 @@ void BlobVector::create_vector(io::Pool pool) { block_info_ = pool.create_block(sizeof(BlobVectorHeader)); try { - cells_.create(&pool_, BlobVectorCell()); + cells_.create(pool_, BlobVectorCell()); } catch (...) { pool_.free_block(*block_info_); throw; @@ -250,7 +252,7 @@ void BlobVector::open_vector(io::Pool pool, uint32_t block_id) { recycler_ = pool.mutable_recycler(); // Open the core table. - cells_.open(&pool, header_->cells_block_id()); + cells_.open(pool, header_->cells_block_id()); } BlobVectorSmallValueCell BlobVector::create_small_value_cell( @@ -262,7 +264,7 @@ BlobVectorMediumValueCell BlobVector::create_medium_value_cell( const void *ptr, uint64_t length) { const uint8_t store_id = get_store_id(length); BlobVectorMediumValueStore &store = medium_value_stores_[store_id]; - if (!store.is_open()) { + if (!store) { open_medium_value_store(store_id); } @@ -273,9 +275,9 @@ BlobVectorMediumValueCell BlobVector::create_medium_value_cell( // TODO: Reuse. offset = header_->medium_value_store_next_offsets(store_id); - if (offset > store.id_max()) { + if (offset > store.max_id()) { GRNXX_ERROR() << "store is full: offset = " << offset - << ", id_max = " << store.id_max(); + << ", max_id = " << store.max_id(); GRNXX_THROW(); } header_->set_medium_value_store_next_offsets(store_id, @@ -290,7 +292,7 @@ BlobVectorLargeValueCell BlobVector::create_large_value_cell( const void *ptr, uint64_t length) { typedef BlobVectorLargeValueHeader ValueHeader; - if (!large_value_store_.is_open()) { + if (!large_value_store_) { open_large_value_store(); } @@ -390,7 +392,7 @@ void BlobVector::free_value(BlobVectorCell cell) { case BLOB_VECTOR_LARGE_VALUE: { typedef BlobVectorLargeValueHeader ValueHeader; Lock lock(header_->mutable_large_value_store_mutex()); - if (!large_value_store_.is_open()) { + if (!large_value_store_) { open_large_value_store(); } const uint64_t offset = cell.large_value_cell().offset(); @@ -420,34 +422,34 @@ void BlobVector::free_value(BlobVectorCell cell) { void BlobVector::open_medium_value_store(uint8_t store_id) { Lock inter_thread_lock(&inter_thread_mutex_); BlobVectorMediumValueStore &store = medium_value_stores_[store_id]; - if (!store.is_open()) { + if (!store) { if (header_->medium_value_store_block_ids(store_id) == io::BLOCK_INVALID_ID) { Lock inter_process_lock(header_->mutable_inter_process_mutex()); if (header_->medium_value_store_block_ids(store_id) == io::BLOCK_INVALID_ID) { - store.create(&pool_); + store.create(pool_); header_->set_medium_value_store_block_ids(store_id, store.block_id()); } } - if (!store.is_open()) { - store.open(&pool_, header_->medium_value_store_block_ids(store_id)); + if (!store) { + store.open(pool_, header_->medium_value_store_block_ids(store_id)); } } } void BlobVector::open_large_value_store() { Lock inter_thread_lock(&inter_thread_mutex_); - if (!large_value_store_.is_open()) { + if (!large_value_store_) { if (header_->large_value_store_block_id() == io::BLOCK_INVALID_ID) { Lock inter_process_lock(header_->mutable_inter_process_mutex()); if (header_->large_value_store_block_id() == io::BLOCK_INVALID_ID) { - large_value_store_.create(&pool_); + large_value_store_.create(pool_); header_->set_large_value_store_block_id(large_value_store_.block_id()); } } - if (!large_value_store_.is_open()) { - large_value_store_.open(&pool_, header_->large_value_store_block_id()); + if (!large_value_store_) { + large_value_store_.open(pool_, header_->large_value_store_block_id()); } } } Modified: lib/db/blob_vector.hpp (+1 -1) =================================================================== --- lib/db/blob_vector.hpp 2012-12-06 20:37:22 +0900 (6bddced) +++ lib/db/blob_vector.hpp 2012-12-06 21:29:51 +0900 (861ea53) @@ -458,7 +458,7 @@ class BlobVector { return is_open() ? block_info_->id() : io::BLOCK_INVALID_ID; } uint64_t id_max() const { - return cells_.id_max(); + return cells_.max_id(); } void swap(BlobVector &rhs); Modified: lib/db/vector.hpp (+235 -74) =================================================================== --- lib/db/vector.hpp 2012-12-06 20:37:22 +0900 (f26b0cd) +++ lib/db/vector.hpp 2012-12-06 21:29:51 +0900 (a6b5172) @@ -18,130 +18,288 @@ #ifndef GRNXX_DB_VECTOR_HPP #define GRNXX_DB_VECTOR_HPP -#include "vector_base.hpp" +#include "../io/pool.hpp" namespace grnxx { namespace db { -const uint64_t VECTOR_PAGE_SIZE_MIN = uint64_t(1) << 0; -const uint64_t VECTOR_PAGE_SIZE_MAX = uint64_t(1) << 20; -const uint64_t VECTOR_PAGE_SIZE_DEFAULT = uint64_t(1) << 16; +const uint64_t VECTOR_MIN_PAGE_SIZE = uint64_t(1) << 0; +const uint64_t VECTOR_MAX_PAGE_SIZE = uint64_t(1) << 20; +const uint64_t VECTOR_DEFAULT_PAGE_SIZE = uint64_t(1) << 16; -const uint64_t VECTOR_TABLE_SIZE_MIN = uint64_t(1) << 10; -const uint64_t VECTOR_TABLE_SIZE_MAX = uint64_t(1) << 20; -const uint64_t VECTOR_TABLE_SIZE_DEFAULT = uint64_t(1) << 12; +const uint64_t VECTOR_MIN_TABLE_SIZE = uint64_t(1) << 10; +const uint64_t VECTOR_MAX_TABLE_SIZE = uint64_t(1) << 20; +const uint64_t VECTOR_DEFAULT_TABLE_SIZE = uint64_t(1) << 12; -const uint64_t VECTOR_SECONDARY_TABLE_SIZE_MIN = uint64_t(1) << 10; -const uint64_t VECTOR_SECONDARY_TABLE_SIZE_MAX = uint64_t(1) << 20; -const uint64_t VECTOR_SECONDARY_TABLE_SIZE_DEFAULT = uint64_t(1) << 12; +const uint64_t VECTOR_MIN_SECONDARY_TABLE_SIZE = uint64_t(1) << 10; +const uint64_t VECTOR_MAX_SECONDARY_TABLE_SIZE = uint64_t(1) << 20; +const uint64_t VECTOR_DEFAULT_SECONDARY_TABLE_SIZE = uint64_t(1) << 12; -template <typename T, - uint64_t PAGE_SIZE = VECTOR_PAGE_SIZE_DEFAULT, - uint64_t TABLE_SIZE = VECTOR_TABLE_SIZE_DEFAULT, - uint64_t SECONDARY_TABLE_SIZE = VECTOR_SECONDARY_TABLE_SIZE_DEFAULT> -class Vector { +extern class VectorCreate {} VECTOR_CREATE; +extern class VectorOpen {} VECTOR_OPEN; + +class VectorHeader { public: - typedef T Value; + VectorHeader(const void *default_value, + uint64_t value_size, + uint64_t page_size, + uint64_t table_size, + uint64_t secondary_table_size); - static_assert(PAGE_SIZE >= VECTOR_PAGE_SIZE_MIN, "too small PAGE_SIZE"); - static_assert(PAGE_SIZE <= VECTOR_PAGE_SIZE_MAX, "too large PAGE_SIZE"); + uint64_t value_size() const { + return value_size_; + } + uint64_t page_size() const { + return page_size_; + } + uint64_t table_size() const { + return table_size_; + } + uint64_t secondary_table_size() const { + return secondary_table_size_; + } + bool has_default_value() const { + return has_default_value_ != 0; + } + uint32_t first_table_block_id() const { + return first_table_block_id_; + } + uint32_t secondary_table_block_id() const { + return secondary_table_block_id_; + } - static_assert(TABLE_SIZE >= VECTOR_TABLE_SIZE_MIN, "too small TABLE_SIZE"); - static_assert(TABLE_SIZE <= VECTOR_TABLE_SIZE_MAX, "too large TABLE_SIZE"); + void set_first_table_block_id(uint32_t value) { + first_table_block_id_ = value; + } + void set_secondary_table_block_id(uint32_t value) { + secondary_table_block_id_ = value; + } - static_assert(SECONDARY_TABLE_SIZE >= VECTOR_SECONDARY_TABLE_SIZE_MIN, - "too small SECONDARY_TABLE_SIZE"); - static_assert(SECONDARY_TABLE_SIZE <= VECTOR_SECONDARY_TABLE_SIZE_MAX, - "too large SECONDARY_TABLE_SIZE"); + Mutex *mutable_inter_process_mutex() { + return &inter_process_mutex_; + } + StringBuilder &write_to(StringBuilder &builder) const; + + private: + uint64_t value_size_; + uint64_t page_size_; + uint64_t table_size_; + uint64_t secondary_table_size_; + uint32_t has_default_value_; + uint32_t first_table_block_id_; + uint32_t secondary_table_block_id_; + Mutex inter_process_mutex_; +}; + +inline StringBuilder &operator<<(StringBuilder &builder, + const VectorHeader &header) { + return header.write_to(builder); +} + +class VectorImpl { + typedef void (*FillPage)(void *page_address, const void *value); + + public: + static std::unique_ptr<VectorImpl> create(io::Pool pool, + const void *default_value, + uint64_t value_size, + uint64_t page_size, + uint64_t table_size, + uint64_t secondary_table_size, + FillPage fill_page); + static std::unique_ptr<VectorImpl> open(io::Pool pool, + uint32_t block_id, + uint64_t value_size, + uint64_t page_size, + uint64_t table_size, + uint64_t secondary_table_size, + FillPage fill_page); + + template <uint64_t PAGE_SIZE, + uint64_t TABLE_SIZE, + uint64_t SECONDARY_TABLE_SIZE> + void *get_page_address(uint64_t page_id) { + if ((page_id < TABLE_SIZE) && first_table_cache_[page_id]) { + return first_table_cache_[page_id]; + } + if ((page_id < (TABLE_SIZE * SECONDARY_TABLE_SIZE)) && tables_cache_) { + const uint64_t table_id = page_id / TABLE_SIZE; + const std::unique_ptr<void *[]> &table_cache = tables_cache_[table_id]; + if (table_cache) { + const uint64_t local_page_id = page_id % TABLE_SIZE; + if (table_cache[local_page_id]) { + return table_cache[local_page_id]; + } + } + } + return get_page_address_on_failure(page_id); + } + + uint32_t block_id() const { + return block_info_->id(); + } + + StringBuilder &write_to(StringBuilder &builder) const; + + static void unlink(io::Pool pool, + uint32_t block_id, + uint64_t value_size, + uint64_t page_size, + uint64_t table_size, + uint64_t secondary_table_size); + + private: + io::Pool pool_; + FillPage fill_page_; + const io::BlockInfo *block_info_; + VectorHeader *header_; + void *default_value_; + uint8_t table_size_bits_; + uint64_t table_size_mask_; + uint64_t max_page_id_; + uint32_t *first_table_; + uint32_t *secondary_table_; + std::unique_ptr<uint32_t *[]> secondary_table_cache_; + std::unique_ptr<void *[]> first_table_cache_; + std::unique_ptr<std::unique_ptr<void *[]>[]> tables_cache_; + Mutex inter_thread_mutex_; + + VectorImpl(); + + void create_vector(io::Pool pool, + const void *default_value, + uint64_t value_size, + uint64_t page_size, + uint64_t table_size, + uint64_t secondary_table_size, + FillPage fill_page); + void open_vector(io::Pool pool, + uint32_t block_id, + uint64_t value_size, + uint64_t page_size, + uint64_t table_size, + uint64_t secondary_table_size, + FillPage fill_page); + void restore_from_header(); + + void *get_page_address_on_failure(uint64_t page_id); + + void initialize_secondary_table(); + void initialize_table(uint32_t *table_block_id); + void initialize_page(uint32_t *page_block_id); + void initialize_secondary_table_cache(); + void initialize_table_cache(std::unique_ptr<void *[]> *table_cache); + void initialize_tables_cache(); + + Mutex *mutable_inter_process_mutex() { + return header_->mutable_inter_process_mutex(); + } + Mutex *mutable_inter_thread_mutex() { + return &inter_thread_mutex_; + } +}; + +inline StringBuilder &operator<<(StringBuilder &builder, + const VectorImpl &vector) { + return vector.write_to(builder); +} + +template <typename T, + uint64_t PAGE_SIZE = VECTOR_DEFAULT_PAGE_SIZE, + uint64_t TABLE_SIZE = VECTOR_DEFAULT_TABLE_SIZE, + uint64_t SECONDARY_TABLE_SIZE = VECTOR_DEFAULT_SECONDARY_TABLE_SIZE> +class Vector { + static_assert(PAGE_SIZE >= VECTOR_MIN_PAGE_SIZE, "too small PAGE_SIZE"); + static_assert(PAGE_SIZE <= VECTOR_MAX_PAGE_SIZE, "too large PAGE_SIZE"); static_assert((PAGE_SIZE & (PAGE_SIZE - 1)) == 0, "PAGE_SIZE must be a power of two"); + + static_assert(TABLE_SIZE >= VECTOR_MIN_TABLE_SIZE, "too small TABLE_SIZE"); + static_assert(TABLE_SIZE <= VECTOR_MAX_TABLE_SIZE, "too large TABLE_SIZE"); static_assert((TABLE_SIZE & (TABLE_SIZE - 1)) == 0, "TABLE_SIZE must be a power of two"); + + static_assert(SECONDARY_TABLE_SIZE >= VECTOR_MIN_SECONDARY_TABLE_SIZE, + "too small SECONDARY_TABLE_SIZE"); + static_assert(SECONDARY_TABLE_SIZE <= VECTOR_MAX_SECONDARY_TABLE_SIZE, + "too large SECONDARY_TABLE_SIZE"); static_assert((SECONDARY_TABLE_SIZE & (SECONDARY_TABLE_SIZE - 1)) == 0, "SECONDARY_TABLE_SIZE must be a power of two"); - Vector() : base_() {} - ~Vector() {} - - Vector(Vector &&vector) : base_(std::move(vector.base_)) {} - Vector &operator=(Vector &&vector) { - base_ = std::move(vector.base_); - return *this; - } + public: + typedef T Value; - bool is_open() const { - return base_.is_open(); - } + Vector() = default; + Vector(const VectorCreate &, io::Pool pool) + : impl_(VectorImpl::create(pool, nullptr, sizeof(Value), PAGE_SIZE, + TABLE_SIZE, SECONDARY_TABLE_SIZE, fill_page)) {} + Vector(const VectorCreate &, io::Pool pool, const Value &default_value) + : impl_(VectorImpl::create(pool, &default_value, sizeof(Value), PAGE_SIZE, + TABLE_SIZE, SECONDARY_TABLE_SIZE, fill_page)) {} + Vector(const VectorOpen &, io::Pool pool, uint32_t block_id) + : impl_(VectorImpl::open(pool, block_id, sizeof(Value), PAGE_SIZE, + TABLE_SIZE, SECONDARY_TABLE_SIZE, fill_page)) {} - void create(io::Pool *pool) { - base_.create(pool, sizeof(Value), - PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE, - nullptr, fill_page); + void create(io::Pool pool) { + *this = Vector(VECTOR_CREATE, pool); } - void create(io::Pool *pool, const Value &default_value) { - base_.create(pool, sizeof(Value), - PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE, - &default_value, fill_page); + void create(io::Pool pool, const Value &default_value) { + *this = Vector(VECTOR_CREATE, pool, default_value); } - void open(io::Pool *pool, uint32_t block_id) { - base_.open(pool, block_id, sizeof(Value), - PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE, fill_page); + void open(io::Pool pool, uint32_t block_id) { + *this = Vector(VECTOR_OPEN, pool, block_id); } void close() { - if (!is_open()) { - GRNXX_ERROR() << "failed to close vector"; - GRNXX_THROW(); - } - base_ = VectorBase(); + *this = Vector(); } - Value *get_value_address(uint64_t id) { - return base_.get_value_address<Value, PAGE_SIZE, TABLE_SIZE, - SECONDARY_TABLE_SIZE>(id); - } - Value &get_value(uint64_t id) { - return *get_value_address(id); + explicit operator bool() const { + return static_cast<bool>(impl_); } + Value &operator[](uint64_t id) { - return get_value(id); + void * const page_address = + impl_->get_page_address<PAGE_SIZE, TABLE_SIZE, + SECONDARY_TABLE_SIZE>(id / PAGE_SIZE); + return static_cast<T *>(page_address)[id % PAGE_SIZE]; } uint32_t block_id() const { - return base_.block_id(); + return impl_->block_id(); } - void swap(Vector &vector) { - base_.swap(vector.base_); + void swap(Vector &rhs) { + impl_.swap(rhs.impl_); } StringBuilder &write_to(StringBuilder &builder) const { - return base_.write_to(builder); + return impl_ ? impl_->write_to(builder) : (builder << "n/a"); } - static uint64_t value_size() { + static constexpr uint64_t value_size() { return sizeof(Value); } - static uint64_t page_size() { + static constexpr uint64_t page_size() { return PAGE_SIZE; } - static uint64_t table_size() { + static constexpr uint64_t table_size() { return TABLE_SIZE; } - static uint64_t secondary_table_size() { + static constexpr uint64_t secondary_table_size() { return SECONDARY_TABLE_SIZE; } - static uint64_t id_max() { + static constexpr uint64_t max_id() { return (PAGE_SIZE * TABLE_SIZE * SECONDARY_TABLE_SIZE) - 1; } - static void unlink(io::Pool *pool, uint32_t block_id) { - VectorBase::unlink(pool, block_id, sizeof(Value), + static void unlink(io::Pool pool, uint32_t block_id) { + VectorImpl::unlink(pool, block_id, sizeof(Value), PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE); } private: - VectorBase base_; + std::shared_ptr<VectorImpl> impl_; static void fill_page(void *page_address, const void *value) { Value *values = static_cast<Value *>(page_address); @@ -151,14 +309,17 @@ class Vector { } }; -template <typename T> -inline void swap(Vector<T> &lhs, Vector<T> &rhs) { +template <typename T, uint64_t PAGE_SIZE, uint64_t TABLE_SIZE, + uint64_t SECONDARY_TABLE_SIZE> +inline void swap(Vector<T, PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE> &lhs, + Vector<T, PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE> &rhs) { lhs.swap(rhs); } -template <typename T> +template <typename T, uint64_t PAGE_SIZE, uint64_t TABLE_SIZE, + uint64_t SECONDARY_TABLE_SIZE> inline StringBuilder &operator<<(StringBuilder &builder, - const Vector<T> &vector) { + const Vector<T, PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE> &vector) { return vector.write_to(builder); } Deleted: lib/db/vector_base.cpp (+0 -512) 100644 =================================================================== --- lib/db/vector_base.cpp 2012-12-06 20:37:22 +0900 (bf47347) +++ /dev/null @@ -1,512 +0,0 @@ -/* - Copyright (C) 2012 Brazil, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#include "vector_base.hpp" - -#include <vector> - -#include "../lock.hpp" -#include "../logger.hpp" - -namespace grnxx { -namespace db { - -void VectorHeader::initialize(uint64_t value_size, - uint64_t page_size, - uint64_t table_size, - uint64_t secondary_table_size, - const void *default_value) { - std::memset(this, 0, sizeof(*this)); - - value_size_ = value_size; - page_size_ = page_size; - table_size_ = table_size; - secondary_table_size_ = secondary_table_size; - has_default_value_ = default_value ? 1 : 0; - - first_table_block_id_ = io::BLOCK_INVALID_ID; - secondary_table_block_id_ = io::BLOCK_INVALID_ID; - - mutex_.unlock(); -} - -VectorBase::VectorBase() - : pool_(), - block_info_(nullptr), - header_(nullptr), - default_value_(nullptr), - fill_page_(nullptr), - table_size_bits_(0), - table_size_mask_(0), - page_id_max_(0), - first_table_(nullptr), - secondary_table_(nullptr), - secondary_table_cache_(), - first_table_cache_(), - tables_cache_(), - mutex_(MUTEX_UNLOCKED) {} - -VectorBase::~VectorBase() {} - -VectorBase::VectorBase(VectorBase &&rhs) - : pool_(std::move(rhs.pool_)), - block_info_(std::move(rhs.block_info_)), - header_(std::move(rhs.header_)), - default_value_(std::move(rhs.default_value_)), - fill_page_(std::move(rhs.fill_page_)), - table_size_bits_(std::move(rhs.table_size_bits_)), - table_size_mask_(std::move(rhs.table_size_mask_)), - page_id_max_(std::move(rhs.page_id_max_)), - first_table_(std::move(rhs.first_table_)), - secondary_table_(std::move(rhs.secondary_table_)), - secondary_table_cache_(std::move(rhs.secondary_table_cache_)), - first_table_cache_(std::move(rhs.first_table_cache_)), - tables_cache_(std::move(rhs.tables_cache_)), - mutex_(std::move(rhs.mutex_)) {} - -VectorBase &VectorBase::operator=(VectorBase &&rhs) { - pool_ = std::move(rhs.pool_); - block_info_ = std::move(rhs.block_info_); - header_ = std::move(rhs.header_); - default_value_ = std::move(rhs.default_value_); - fill_page_ = std::move(rhs.fill_page_); - table_size_bits_ = std::move(rhs.table_size_bits_); - table_size_mask_ = std::move(rhs.table_size_mask_); - page_id_max_ = std::move(rhs.page_id_max_); - first_table_ = std::move(rhs.first_table_); - secondary_table_ = std::move(rhs.secondary_table_); - secondary_table_cache_ = std::move(rhs.secondary_table_cache_); - first_table_cache_ = std::move(rhs.first_table_cache_); - tables_cache_ = std::move(rhs.tables_cache_); - mutex_ = std::move(rhs.mutex_); - return *this; -} - -void VectorBase::create(io::Pool *pool, - uint64_t value_size, - uint64_t page_size, - uint64_t table_size, - uint64_t secondary_table_size, - const void *default_value, - FillPage fill_page) { - if (!pool) { - GRNXX_ERROR() << "invalid argument: pool = " << pool; - GRNXX_THROW(); - } else if (!*pool) { - GRNXX_ERROR() << "invalid_argument: pool = " << *pool; - GRNXX_THROW(); - } - - VectorBase new_vector; - new_vector.create_vector(pool, value_size, page_size, table_size, - secondary_table_size, default_value, fill_page); - *this = std::move(new_vector); -} - -void VectorBase::open(io::Pool *pool, - uint32_t block_id, - uint64_t value_size, - uint64_t page_size, - uint64_t table_size, - uint64_t secondary_table_size, - FillPage fill_page) { - if (!pool) { - GRNXX_ERROR() << "invalid argument: pool = " << pool; - GRNXX_THROW(); - } else if (!*pool) { - GRNXX_ERROR() << "invalid_argument: pool = " << *pool; - GRNXX_THROW(); - } - - VectorBase new_vector; - new_vector.open_vector(pool, block_id, value_size, page_size, table_size, - secondary_table_size, fill_page); - *this = std::move(new_vector); -} - -void VectorBase::swap(VectorBase &rhs) { - using std::swap; - swap(pool_, rhs.pool_); - swap(block_info_, rhs.block_info_); - swap(header_, rhs.header_); - swap(default_value_, rhs.default_value_); - swap(fill_page_, rhs.fill_page_); - swap(table_size_bits_, rhs.table_size_bits_); - swap(table_size_mask_, rhs.table_size_mask_); - swap(page_id_max_, rhs.page_id_max_); - swap(first_table_, rhs.first_table_); - swap(secondary_table_, rhs.secondary_table_); - swap(secondary_table_cache_, rhs.secondary_table_cache_); - swap(first_table_cache_, rhs.first_table_cache_); - swap(tables_cache_, rhs.tables_cache_); - swap(mutex_, rhs.mutex_); -} - -void VectorBase::unlink(io::Pool *pool, - uint32_t block_id, - uint64_t value_size, - uint64_t page_size, - uint64_t table_size, - uint64_t secondary_table_size) try { - std::vector<uint32_t> block_ids; - - { - VectorBase vector; - vector.open(pool, block_id, value_size, - page_size, table_size, secondary_table_size, nullptr); - const VectorHeader * const header = vector.header_; - - block_ids.push_back(block_id); - - block_ids.push_back(header->first_table_block_id()); - for (uint64_t i = 0; i < header->table_size(); ++i) { - if (vector.first_table_[i] != io::BLOCK_INVALID_ID) { - block_ids.push_back(vector.first_table_[i]); - } - } - - if (header->secondary_table_block_id() != io::BLOCK_INVALID_ID) { - block_ids.push_back(header->secondary_table_block_id()); - uint32_t * const secondary_table = static_cast<uint32_t *>( - pool->get_block_address(header->secondary_table_block_id())); - for (uint64_t i = 0; i < header->secondary_table_size(); ++i) { - if (secondary_table[i] != io::BLOCK_INVALID_ID) { - block_ids.push_back(secondary_table[i]); - uint32_t * const table = static_cast<uint32_t *>( - pool->get_block_address(secondary_table[i])); - for (uint64_t j = 0; j < header->table_size(); ++j) { - if (table[j] != io::BLOCK_INVALID_ID) { - block_ids.push_back(table[j]); - } - } - } - } - } - } - - for (size_t i = 0; i < block_ids.size(); ++i) { - pool->free_block(block_ids[i]); - } -} catch (const std::exception &exception) { - GRNXX_ERROR() << exception; - GRNXX_THROW(); -} - -void VectorBase::create_vector(io::Pool *pool, - uint64_t value_size, - uint64_t page_size, - uint64_t table_size, - uint64_t secondary_table_size, - const void *default_value, - FillPage fill_page) { - pool_ = *pool; - - std::unique_ptr<void *[]> first_table_cache( - new (std::nothrow) void *[table_size]); - if (!first_table_cache) { - GRNXX_ERROR() << "new void *[" << table_size << "] failed"; - GRNXX_THROW(); - } - - uint64_t header_block_size = sizeof(VectorHeader); - if (default_value) { - header_block_size += value_size; - } - block_info_ = pool_.create_block(header_block_size); - - const io::BlockInfo *first_table_block_info; - try { - first_table_block_info = pool_.create_block(sizeof(uint32_t) * table_size); - } catch (...) { - pool_.free_block(*block_info_); - throw; - } - - void * const block_address = pool_.get_block_address(*block_info_); - header_ = static_cast<VectorHeader *>(block_address); - header_->initialize(value_size, page_size, table_size, - secondary_table_size, default_value); - restore_from_header(); - - if (default_value_) { - std::memcpy(default_value_, default_value, - static_cast<size_t>(value_size)); - fill_page_ = fill_page; - } - - header_->set_first_table_block_id(first_table_block_info->id()); - first_table_ = static_cast<uint32_t *>( - pool_.get_block_address(*first_table_block_info)); - first_table_cache_ = std::move(first_table_cache); - for (uint64_t i = 0; i < header_->table_size(); ++i) { - first_table_[i] = io::BLOCK_INVALID_ID; - first_table_cache_[i] = nullptr; - } -} - -void VectorBase::open_vector(io::Pool *pool, - uint32_t block_id, - uint64_t value_size, - uint64_t page_size, - uint64_t table_size, - uint64_t secondary_table_size, - FillPage fill_page) { - pool_ = *pool; - block_info_ = pool_.get_block_info(block_id); - if (block_info_->size() < sizeof(VectorHeader)) { - GRNXX_ERROR() << "invalid argument: block_info = " << *block_info_ - << ", header_size = " << sizeof(VectorHeader); - GRNXX_THROW(); - } - - void * const block_address = pool_.get_block_address(*block_info_); - header_ = static_cast<VectorHeader *>(block_address); - restore_from_header(); - - if (default_value_) { - const uint64_t header_size = sizeof(VectorHeader) + value_size; - if (block_info_->size() < header_size) { - GRNXX_ERROR() << "invalid argument: block_info = " << *block_info_ - << ", header_size = " << header_size; - GRNXX_THROW(); - } - fill_page_ = fill_page; - } - - if (value_size != header_->value_size()) { - GRNXX_ERROR() << "invalid value size: actual = " << header_->value_size() - << ", expected = " << value_size; - GRNXX_THROW(); - } - if (page_size != header_->page_size()) { - GRNXX_ERROR() << "invalid page size: actual = " << header_->page_size() - << ", expected = " << page_size; - GRNXX_THROW(); - } - if (table_size != header_->table_size()) { - GRNXX_ERROR() << "invalid table size: actual = " << header_->table_size() - << ", expected = " << table_size; - GRNXX_THROW(); - } - if (secondary_table_size != header_->secondary_table_size()) { - GRNXX_ERROR() << "invalid secondary table size: actual = " - << header_->secondary_table_size() - << ", expected = " << secondary_table_size; - GRNXX_THROW(); - } - - first_table_ = static_cast<uint32_t *>( - pool_.get_block_address(header_->first_table_block_id())); - - first_table_cache_.reset(new (std::nothrow) void *[header_->table_size()]); - if (!first_table_cache_) { - GRNXX_ERROR() << "new void *[" << header_->table_size() << "] failed"; - GRNXX_THROW(); - } - for (uint64_t i = 0; i < header_->table_size(); ++i) { - first_table_cache_[i] = nullptr; - } -} - -void VectorBase::restore_from_header() { - if (header_->has_default_value()) { - default_value_ = header_ + 1; - } - - table_size_bits_ = bit_scan_reverse(header_->table_size()); - table_size_mask_ = header_->table_size() - 1; - page_id_max_ = header_->table_size() * header_->secondary_table_size() - 1; -} - -void VectorBase::initialize_secondary_table() { - Lock lock(inter_process_mutex()); - if (header_->secondary_table_block_id() == io::BLOCK_INVALID_ID) { - const auto block_info = pool_.create_block( - sizeof(uint32_t) * header_->secondary_table_size()); - uint32_t * const body = static_cast<uint32_t *>( - pool_.get_block_address(*block_info)); - for (uint64_t i = 0; i < header_->secondary_table_size(); ++i) { - body[i] = io::BLOCK_INVALID_ID; - } - header_->set_secondary_table_block_id(block_info->id()); - } -} - -void *VectorBase::get_page_address_on_failure(uint64_t page_id) { - if (page_id < header_->table_size()) { - if (!first_table_cache_[page_id]) { - if (first_table_[page_id] == io::BLOCK_INVALID_ID) { - initialize_page(&first_table_[page_id]); - } - first_table_cache_[page_id] = - pool_.get_block_address(first_table_[page_id]); - } - return first_table_cache_[page_id]; - } - - if (page_id <= page_id_max_) { - if (!tables_cache_) { - if (!secondary_table_cache_) { - if (!secondary_table_) { - if (header_->secondary_table_block_id() == io::BLOCK_INVALID_ID) { - initialize_secondary_table(); - } - secondary_table_ = static_cast<uint32_t *>( - pool_.get_block_address(header_->secondary_table_block_id())); - } - initialize_secondary_table_cache(); - } - initialize_tables_cache(); - } - - const uint64_t table_id = page_id >> table_size_bits_; - std::unique_ptr<void *[]> &table_cache = tables_cache_[table_id]; - if (!table_cache) { - if (secondary_table_[table_id] == io::BLOCK_INVALID_ID) { - initialize_table(&secondary_table_[table_id]); - } - secondary_table_cache_[table_id] = static_cast<uint32_t *>( - pool_.get_block_address(secondary_table_[table_id])); - initialize_table_cache(&table_cache); - } - - page_id &= table_size_mask_; - if (!table_cache[page_id]) { - uint32_t * const table = secondary_table_cache_[table_id]; - if (table[page_id] == io::BLOCK_INVALID_ID) { - initialize_page(&table[page_id]); - } - table_cache[page_id] = pool_.get_block_address(table[page_id]); - } - return table_cache[page_id]; - } - - GRNXX_ERROR() << "invalid argument: page_id = " << page_id - << ": [0, " << page_id_max_ <<']'; - GRNXX_THROW(); -} - -void VectorBase::initialize_table(uint32_t *table_block_id) { - Lock lock(inter_process_mutex()); - if (*table_block_id == io::BLOCK_INVALID_ID) { - const auto block_info = pool_.create_block( - sizeof(uint32_t) * header_->table_size()); - uint32_t * const body = static_cast<uint32_t *>( - pool_.get_block_address(*block_info)); - for (uint64_t i = 0; i < header_->table_size(); ++i) { - body[i] = io::BLOCK_INVALID_ID; - } - *table_block_id = block_info->id(); - } -} - -void VectorBase::initialize_page(uint32_t *page_block_id) { - Lock lock(inter_process_mutex()); - if (*page_block_id == io::BLOCK_INVALID_ID) { - const io::BlockInfo *block_info = pool_.create_block( - header_->value_size() * header_->page_size()); - if (fill_page_) { - fill_page_(pool_.get_block_address(*block_info), default_value_); - } - *page_block_id = block_info->id(); - } -} - -void VectorBase::initialize_secondary_table_cache() { - Lock lock(inter_thread_mutex()); - if (!secondary_table_cache_) { - std::unique_ptr<uint32_t *[]> tables( - new (std::nothrow) uint32_t *[header_->secondary_table_size()]); - if (!tables) { - GRNXX_ERROR() << "new grnxx::uint32_t *[" - << header_->secondary_table_size() << "] failed"; - GRNXX_THROW(); - } - for (uint64_t i = 0; i < header_->secondary_table_size(); ++i) { - tables[i] = nullptr; - } - secondary_table_cache_ = std::move(tables); - } -} - -void VectorBase::initialize_table_cache( - std::unique_ptr<void *[]> *table_cache) { - Lock lock(inter_thread_mutex()); - if (!*table_cache) { - std::unique_ptr<void *[]> cache( - new (std::nothrow) void *[header_->table_size()]); - if (!cache) { - GRNXX_ERROR() << "new void *[" << header_->table_size() << "] failed"; - GRNXX_THROW(); - } - for (uint64_t i = 0; i < header_->table_size(); ++i) { - cache[i] = nullptr; - } - *table_cache = std::move(cache); - } -} - -void VectorBase::initialize_tables_cache() { - Lock lock(inter_thread_mutex()); - if (!tables_cache_) { - std::unique_ptr<std::unique_ptr<void *[]>[]> cache(new (std::nothrow) - std::unique_ptr<void *[]>[header_->secondary_table_size()]); - for (uint64_t i = 0; i < header_->secondary_table_size(); ++i) { - cache[i] = nullptr; - } - tables_cache_ = std::move(cache); - } -} - -StringBuilder &VectorHeader::write_to(StringBuilder &builder) const { - if (!builder) { - return builder; - } - - return builder << "{ value_size = " << value_size_ - << ", page_size = " << page_size_ - << ", table_size = " << table_size_ - << ", secondary_table_size = " << secondary_table_size_ - << ", has_default_value = " << has_default_value_ - << ", first_table_block_id = " << first_table_block_id_ - << ", secondary_table_block_id = " << secondary_table_block_id_ - << ", mutex = " << mutex_ << " }"; -} - -StringBuilder &VectorBase::write_to(StringBuilder &builder) const { - if (!builder) { - return builder; - } - - if (!is_open()) { - return builder << "n/a"; - } - - builder << "{ pool = " << pool_.path() - << ", block_info = " << *block_info_ - << ", header = "; - if (header_) { - builder << *header_; - } else { - builder << "n/a"; - } - return builder << ", page_id_max = " << page_id_max_ - << ", mutex = " << mutex_ << " }"; -} - -} // namespace db -} // namespace grnxx Deleted: lib/db/vector_base.hpp (+0 -247) 100644 =================================================================== --- lib/db/vector_base.hpp 2012-12-06 20:37:22 +0900 (2cbac41) +++ /dev/null @@ -1,247 +0,0 @@ -/* - Copyright (C) 2012 Brazil, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#ifndef GRNXX_DB_VECTOR_BASE_HPP -#define GRNXX_DB_VECTOR_BASE_HPP - -#include "../exception.hpp" -#include "../logger.hpp" -#include "../io/pool.hpp" - -namespace grnxx { -namespace db { - -class VectorHeader { - public: - void initialize(uint64_t value_size, - uint64_t page_size, - uint64_t table_size, - uint64_t secondary_table_size, - const void *default_value); - - uint64_t value_size() const { - return value_size_; - } - uint64_t page_size() const { - return page_size_; - } - uint64_t table_size() const { - return table_size_; - } - uint64_t secondary_table_size() const { - return secondary_table_size_; - } - bool has_default_value() const { - return has_default_value_ != 0; - } - uint32_t first_table_block_id() const { - return first_table_block_id_; - } - uint32_t secondary_table_block_id() const { - return secondary_table_block_id_; - } - - void set_first_table_block_id(uint32_t value) { - first_table_block_id_ = value; - } - void set_secondary_table_block_id(uint32_t value) { - secondary_table_block_id_ = value; - } - - Mutex *mutex() { - return &mutex_; - } - - StringBuilder &write_to(StringBuilder &builder) const; - - private: - uint64_t value_size_; - uint64_t page_size_; - uint64_t table_size_; - uint64_t secondary_table_size_; - uint8_t has_default_value_; - uint32_t first_table_block_id_; - uint32_t secondary_table_block_id_; - Mutex mutex_; - - VectorHeader(); - ~VectorHeader(); - - VectorHeader(const VectorHeader &); - VectorHeader &operator=(const VectorHeader &); -}; - -class VectorBase { - public: - typedef void (*FillPage)(void *page_address, const void *value); - - VectorBase(); - ~VectorBase(); - - VectorBase(VectorBase &&rhs); - VectorBase &operator=(VectorBase &&rhs); - - bool is_open() const { - return static_cast<bool>(pool_); - } - - void create(io::Pool *pool, - uint64_t value_size, - uint64_t page_size, - uint64_t table_size, - uint64_t secondary_table_size, - const void *default_value, - FillPage fill_page); - - void open(io::Pool *pool, - uint32_t block_id, - uint64_t value_size, - uint64_t page_size, - uint64_t table_size, - uint64_t secondary_table_size, - FillPage fill_page); - - template <typename T, - uint64_t PAGE_SIZE, - uint64_t TABLE_SIZE, - uint64_t SECONDARY_TABLE_SIZE> - T *get_value_address(uint64_t id) { - void * const page_address = - get_page_address<PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE>( - id / PAGE_SIZE); - return static_cast<T *>(page_address) + (id % PAGE_SIZE); - } - - template <uint64_t PAGE_SIZE, - uint64_t TABLE_SIZE, - uint64_t SECONDARY_TABLE_SIZE> - void *get_page_address(uint64_t page_id) { - if ((page_id < TABLE_SIZE) && first_table_cache_[page_id]) { - return first_table_cache_[page_id]; - } - if ((page_id < (TABLE_SIZE * SECONDARY_TABLE_SIZE)) && tables_cache_) { - const uint64_t table_id = page_id / TABLE_SIZE; - const std::unique_ptr<void *[]> &table_cache = tables_cache_[table_id]; - if (table_cache) { - const uint64_t local_page_id = page_id % TABLE_SIZE; - if (table_cache[local_page_id]) { - return table_cache[local_page_id]; - } - } - } - return get_page_address_on_failure(page_id); - } - - uint32_t block_id() const { - return is_open() ? block_info_->id() : io::BLOCK_INVALID_ID; - } - uint64_t value_size() const { - return is_open() ? header_->value_size() : 0; - } - uint64_t page_size() const { - return is_open() ? header_->page_size() : 0; - } - uint64_t table_size() const { - return is_open() ? header_->table_size() : 0; - } - uint64_t secondary_table_size() const { - return is_open() ? header_->secondary_table_size() : 0; - } - uint64_t id_max() const { - return (page_size() * table_size() * secondary_table_size()) - 1; - } - - void swap(VectorBase &rhs); - - StringBuilder &write_to(StringBuilder &builder) const; - - static void unlink(io::Pool *pool, - uint32_t block_id, - uint64_t value_size, - uint64_t page_size, - uint64_t table_size, - uint64_t secondary_table_size); - - private: - io::Pool pool_; - const io::BlockInfo *block_info_; - VectorHeader *header_; - void *default_value_; - FillPage fill_page_; - uint8_t table_size_bits_; - uint64_t table_size_mask_; - uint64_t page_id_max_; - uint32_t *first_table_; - uint32_t *secondary_table_; - std::unique_ptr<uint32_t *[]> secondary_table_cache_; - std::unique_ptr<void *[]> first_table_cache_; - std::unique_ptr<std::unique_ptr<void *[]>[]> tables_cache_; - Mutex mutex_; - - void create_vector(io::Pool *pool, - uint64_t value_size, - uint64_t page_size, - uint64_t table_size, - uint64_t secondary_table_size, - const void *default_value, - FillPage fill_page); - void open_vector(io::Pool *pool, - uint32_t block_id, - uint64_t value_size, - uint64_t page_size, - uint64_t table_size, - uint64_t secondary_table_size, - FillPage fill_page); - - void restore_from_header(); - uint64_t header_size() const; - - void *get_page_address_on_failure(uint64_t page_id); - - void initialize_secondary_table(); - void initialize_table(uint32_t *table_block_id); - void initialize_page(uint32_t *page_block_id); - - void initialize_secondary_table_cache(); - void initialize_table_cache( - std::unique_ptr<void *[]> *table_cache); - void initialize_tables_cache(); - - Mutex *inter_thread_mutex() { - return &mutex_; - } - Mutex *inter_process_mutex() { - return header_->mutex(); - } - - VectorBase(const VectorBase &); - VectorBase &operator=(const VectorBase &); -}; - -inline StringBuilder &operator<<(StringBuilder &builder, - const VectorHeader &header) { - return header.write_to(builder); -} -inline StringBuilder &operator<<(StringBuilder &builder, - const VectorBase &vector) { - return vector.write_to(builder); -} - -} // namespace db -} // namespace grnxx - -#endif // GRNXX_DB_VECTOR_BASE_HPP Modified: test/test_db_vector.cpp (+26 -30) =================================================================== --- test/test_db_vector.cpp 2012-12-06 20:37:22 +0900 (b9945d9) +++ test/test_db_vector.cpp 2012-12-06 21:29:51 +0900 (9e845b2) @@ -34,14 +34,14 @@ void test_basics() { grnxx::io::Pool pool(grnxx::io::POOL_CREATE, "temp.grn"); - grnxx::db::Vector<std::uint32_t> vector; - vector.create(&pool); + grnxx::db::Vector<std::uint32_t> vector(grnxx::db::VECTOR_CREATE, pool); + assert(vector.block_id() == 0); assert(vector.value_size() == sizeof(std::uint32_t)); - assert(vector.page_size() == grnxx::db::VECTOR_PAGE_SIZE_DEFAULT); - assert(vector.table_size() == grnxx::db::VECTOR_TABLE_SIZE_DEFAULT); + assert(vector.page_size() == grnxx::db::VECTOR_DEFAULT_PAGE_SIZE); + assert(vector.table_size() == grnxx::db::VECTOR_DEFAULT_TABLE_SIZE); assert(vector.secondary_table_size() == - grnxx::db::VECTOR_SECONDARY_TABLE_SIZE_DEFAULT); + grnxx::db::VECTOR_DEFAULT_SECONDARY_TABLE_SIZE); GRNXX_NOTICE() << "vector = " << vector; @@ -57,14 +57,14 @@ void test_basics() { vector[1000000] = 100; vector[1000000000] = 1000; vector[1000000000000ULL] = 10000; - vector[vector.id_max()] = 100000; + vector[vector.max_id()] = 100000; assert(vector[0] == 1); assert(vector[1000] == 10); assert(vector[1000000] == 100); assert(vector[1000000000] == 1000); assert(vector[1000000000000ULL] == 10000); - assert(vector[vector.id_max()] == 100000); + assert(vector[vector.max_id()] == 100000); const std::uint32_t block_id = vector.block_id(); @@ -73,14 +73,14 @@ void test_basics() { pool.open(grnxx::io::POOL_OPEN, "temp.grn"); - vector.open(&pool, block_id); + vector.open(pool, block_id); assert(vector[0] == 1); assert(vector[1000] == 10); assert(vector[1000000] == 100); assert(vector[1000000000] == 1000); assert(vector[1000000000000ULL] == 10000); - assert(vector[vector.id_max()] == 100000); + assert(vector[vector.max_id()] == 100000); assert(grnxx::atomic_fetch_and_add(1, &vector[0]) == 1); assert(vector[0] == 2); @@ -88,14 +88,14 @@ void test_basics() { assert(grnxx::atomic_fetch_and_add(10, &vector[0]) == 2); assert(vector[0] == 12); - vector.create(&pool, 56789); + vector.create(pool, 56789); assert(vector[0] == 56789); assert(vector[1000] == 56789); assert(vector[1000000] == 56789); assert(vector[1000000000] == 56789); assert(vector[1000000000000ULL] == 56789); - assert(vector[vector.id_max()] == 56789); + assert(vector[vector.max_id()] == 56789); assert(grnxx::atomic_compare_and_swap( std::uint32_t(56789), std::uint32_t(98765), &vector[0])); @@ -107,8 +107,9 @@ void test_basics() { vector.close(); - grnxx::db::Vector<float> float_vector; - float_vector.create(&pool); + grnxx::db::Vector<std::uint32_t>::unlink(pool, 0); + + grnxx::db::Vector<float> float_vector(grnxx::db::VECTOR_CREATE, pool); float_vector[0] = 1.0F; assert(float_vector[0] == 1.0F); @@ -117,8 +118,7 @@ void test_basics() { float_vector.close(); - grnxx::db::Vector<double> double_vector; - double_vector.create(&pool); + grnxx::db::Vector<double> double_vector(grnxx::db::VECTOR_CREATE, pool); double_vector[0] = 1.0; assert(double_vector[0] == 1.0); @@ -127,8 +127,7 @@ void test_basics() { double_vector.close(); - grnxx::db::Vector<Point> point_vector; - point_vector.create(&pool); + grnxx::db::Vector<Point> point_vector(grnxx::db::VECTOR_CREATE, pool); point_vector[0].x = 123; point_vector[0].y = 456; @@ -141,8 +140,8 @@ void test_basics() { assert(point_vector[1 << 30].y == 654); point_vector.close(); - pool.close(); + pool.close(); grnxx::io::Pool::unlink_if_exists("temp.grn"); } @@ -152,8 +151,7 @@ void test_times() { grnxx::io::Pool pool(grnxx::io::POOL_TEMPORARY, "temp.grn"); - grnxx::db::Vector<T> vector; - vector.create(&pool); + grnxx::db::Vector<T> vector(grnxx::db::VECTOR_CREATE, pool); grnxx::Time start, end; @@ -182,24 +180,24 @@ void test_times() { start = grnxx::Time::now(); - for (std::uint64_t id = vector.id_max() - VECTOR_SIZE + 1; - id <= vector.id_max(); ++id) { + for (std::uint64_t id = vector.max_id() - VECTOR_SIZE + 1; + id <= vector.max_id(); ++id) { vector[id] = T(0); } end = grnxx::Time::now(); double ex_set_1st_elapsed = 1.0 * (end - start).nanoseconds() / VECTOR_SIZE; start = grnxx::Time::now(); - for (std::uint64_t id = vector.id_max() - VECTOR_SIZE + 1; - id <= vector.id_max(); ++id) { + for (std::uint64_t id = vector.max_id() - VECTOR_SIZE + 1; + id <= vector.max_id(); ++id) { vector[id] = T(1); } end = grnxx::Time::now(); double ex_set_2nd_elapsed = 1.0 * (end - start).nanoseconds() / VECTOR_SIZE; start = grnxx::Time::now(); - for (std::uint64_t id = vector.id_max() - VECTOR_SIZE + 1; - id <= vector.id_max(); ++id) { + for (std::uint64_t id = vector.max_id() - VECTOR_SIZE + 1; + id <= vector.max_id(); ++id) { total += vector[id]; } end = grnxx::Time::now(); @@ -248,14 +246,12 @@ void test_times() { const std::uint32_t block_id = vector.block_id(); vector.close(); - start = grnxx::Time::now(); - grnxx::db::Vector<T>::unlink(&pool, block_id); + grnxx::db::Vector<T>::unlink(pool, block_id); end = grnxx::Time::now(); double unlink_elapsed = (end - start).nanoseconds(); - - vector.create(&pool, 0); + vector.create(pool, 0); start = grnxx::Time::now(); for (std::uint64_t id = 0; id < VECTOR_SIZE; ++id) { -------------- next part -------------- HTML����������������������������...Download