susumu.yata
null+****@clear*****
Thu May 16 16:26:10 JST 2013
susumu.yata 2013-05-16 16:26:10 +0900 (Thu, 16 May 2013) New Revision: 43d50c5ff7fa75e3df76e8af13640f1051be3898 https://github.com/groonga/grnxx/commit/43d50c5ff7fa75e3df76e8af13640f1051be3898 Message: Add a specialization for grnxx::Array<bool>. Modified files: lib/grnxx/array.hpp Modified: lib/grnxx/array.hpp (+115 -0) =================================================================== --- lib/grnxx/array.hpp 2013-05-16 14:59:23 +0900 (6fe4afe) +++ lib/grnxx/array.hpp 2013-05-16 16:26:10 +0900 (d7f8e56) @@ -441,6 +441,121 @@ class Array { } }; +// Bit array. +template <uint64_t PAGE_SIZE_IN_BITS, + uint64_t TABLE_SIZE, + uint64_t SECONDARY_TABLE_SIZE> +class Array<bool, PAGE_SIZE_IN_BITS, TABLE_SIZE, SECONDARY_TABLE_SIZE> { + public: + using Unit = uint8_t; + static constexpr uint64_t UNIT_SIZE = sizeof(Unit) * 8; + static constexpr uint64_t PAGE_SIZE = PAGE_SIZE_IN_BITS / UNIT_SIZE; + + private: + static_assert((PAGE_SIZE % UNIT_SIZE) == 0, "(PAGE_SIZE % UNIT_SIZE) != 0"); + using ArrayImpl = Array<Unit, PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE>; + + public: + using Value = typename Traits<bool>::Type; + using ValueArg = typename Traits<bool>::ArgumentType; + + Array() : impl_() {} + ~Array() {} + + // Return true iff the array is valid. + explicit operator bool() const { + return static_cast<bool>(impl_); + } + + // Create an array. + bool create(Storage *storage, uint32_t storage_node_id) { + return impl_.create(storage, storage_node_id); + } + + // Create an array with the default value. + bool create(Storage *storage, uint32_t storage_node_id, + ValueArg default_value) { + return impl_.create(storage, storage_node_id, default_value ? 0xFF : 0x00); + } + + // Open an array. + bool open(Storage *storage, uint32_t storage_node_id) { + return impl_.open(storage, storage_node_id); + } + + // Unlink an array. + static bool unlink(Storage *storage, uint32_t storage_node_id) { + return ArrayImpl::unlink(storage, storage_node_id); + } + + // Return the number of values in each page. + static constexpr uint64_t page_size() { + return PAGE_SIZE_IN_BITS; + } + // Return the number of pages in each table. + static constexpr uint64_t table_size() { + return TABLE_SIZE; + } + // Return the number of tables in each secondary table. + static constexpr uint64_t secondary_table_size() { + return SECONDARY_TABLE_SIZE; + } + // Return the number of values in Array. + static constexpr uint64_t size() { + return page_size() * table_size() * secondary_table_size(); + } + + // Return the storage node ID. + uint32_t storage_node_id() const { + return impl_.storage_node_id(); + } + + // Get a value. + // This function throws an exception on failure. + Value operator[](uint64_t value_id) { + return (impl_[value_id / UNIT_SIZE] & + (Unit(1) << (value_id % UNIT_SIZE))) != 0; + } + + // Get a value and return true on success. + // The value is assigned to "*value" iff "value" != nullptr. + bool get(uint64_t value_id, Value *value) { + const uint64_t unit_id = value_id / UNIT_SIZE; + const Unit * const page = get_page(unit_id / PAGE_SIZE); + if (!page) { + return false; + } + if (value) { + *value = (page[unit_id % PAGE_SIZE] & + (Unit(1) << (value_id % UNIT_SIZE))) != 0; + } + return true; + } + + // Set a value and return true on success. + bool set(uint64_t value_id, ValueArg value) { + const uint64_t unit_id = value_id / UNIT_SIZE; + Unit * const page = get_page(unit_id / PAGE_SIZE); + if (!page) { + return false; + } + if (value) { + page[unit_id % PAGE_SIZE] |= Unit(1) << (value_id % UNIT_SIZE); + } else { + page[unit_id % PAGE_SIZE] &= ~(Unit(1) << (value_id % UNIT_SIZE)); + } + return true; + } + + // Get a page and return its starting address on success. + Unit *get_page(uint64_t page_id) { + return impl_.get_page(page_id); + } + + private: + ArrayImpl impl_; +}; + } // namespace grnxx #endif // GRNXX_ARRAY_HPP -------------- next part -------------- HTML����������������������������... ダウンロード