susumu.yata
null+****@clear*****
Fri May 24 20:28:33 JST 2013
susumu.yata 2013-05-24 20:28:33 +0900 (Fri, 24 May 2013) New Revision: be87e02b9925e44f0e8bb04843b87795f8ab15f0 https://github.com/groonga/grnxx/commit/be87e02b9925e44f0e8bb04843b87795f8ab15f0 Message: Move contents of lib/grnxx/array/* to lib/grnxx/array_impl.*. Removed files: lib/grnxx/array/Makefile.am lib/grnxx/array/array_1d.cpp lib/grnxx/array/array_1d.hpp lib/grnxx/array/array_2d.cpp lib/grnxx/array/array_2d.hpp Modified files: configure.ac lib/grnxx/Makefile.am lib/grnxx/array.hpp Renamed files: lib/grnxx/array_impl.cpp (from lib/grnxx/array/array_3d.cpp) lib/grnxx/array_impl.hpp (from lib/grnxx/array/array_3d.hpp) Modified: configure.ac (+0 -1) =================================================================== --- configure.ac 2013-05-24 20:09:55 +0900 (3f7efad) +++ configure.ac 2013-05-24 20:28:33 +0900 (40bb496) @@ -62,7 +62,6 @@ AC_CONFIG_FILES([Makefile lib/grnxx/Makefile lib/grnxx/alpha/Makefile lib/grnxx/alpha/map/Makefile - lib/grnxx/array/Makefile lib/grnxx/charset/Makefile lib/grnxx/db/Makefile lib/grnxx/io/Makefile Modified: lib/grnxx/Makefile.am (+2 -2) =================================================================== --- lib/grnxx/Makefile.am 2013-05-24 20:09:55 +0900 (c266667) +++ lib/grnxx/Makefile.am 2013-05-24 20:28:33 +0900 (759da75) @@ -1,6 +1,5 @@ SUBDIRS = \ alpha \ - array \ charset \ db \ io \ @@ -11,7 +10,6 @@ lib_LTLIBRARIES = libgrnxx.la libgrnxx_la_LIBADD = \ alpha/libgrnxx_alpha.la \ - array/libgrnxx_array.la \ charset/libgrnxx_charset.la \ db/libgrnxx_db.la \ io/libgrnxx_io.la \ @@ -21,6 +19,7 @@ libgrnxx_la_LIBADD = \ libgrnxx_la_LDFLAGS = @AM_LTLDFLAGS@ libgrnxx_la_SOURCES = \ + array_impl.cpp \ backtrace.cpp \ broken_down_time.cpp \ bytes.cpp \ @@ -47,6 +46,7 @@ libgrnxx_la_SOURCES = \ libgrnxx_includedir = ${includedir}/grnxx libgrnxx_include_HEADERS = \ array.hpp \ + array_impl.hpp \ backtrace.hpp \ basic.hpp \ broken_down_time.hpp \ Modified: lib/grnxx/array.hpp (+1 -3) =================================================================== --- lib/grnxx/array.hpp 2013-05-24 20:09:55 +0900 (8dbc784) +++ lib/grnxx/array.hpp 2013-05-24 20:28:33 +0900 (6068680) @@ -23,9 +23,7 @@ #include <cstring> #include <memory> -#include "grnxx/array/array_1d.hpp" -#include "grnxx/array/array_2d.hpp" -#include "grnxx/array/array_3d.hpp" +#include "grnxx/array_impl.hpp" #include "grnxx/traits.hpp" #include "grnxx/types.hpp" Deleted: lib/grnxx/array/Makefile.am (+0 -14) 100644 =================================================================== --- lib/grnxx/array/Makefile.am 2013-05-24 20:09:55 +0900 (ac0c4bd) +++ /dev/null @@ -1,14 +0,0 @@ -noinst_LTLIBRARIES = libgrnxx_array.la - -libgrnxx_array_la_LDFLAGS = @AM_LTLDFLAGS@ - -libgrnxx_array_la_SOURCES = \ - array_1d.cpp \ - array_2d.cpp \ - array_3d.cpp - -libgrnxx_array_includedir = ${includedir}/grnxx/array -libgrnxx_array_include_HEADERS = \ - array_1d.hpp \ - array_2d.hpp \ - array_3d.hpp Deleted: lib/grnxx/array/array_1d.cpp (+0 -156) 100644 =================================================================== --- lib/grnxx/array/array_1d.cpp 2013-05-24 20:09:55 +0900 (ef67d7d) +++ /dev/null @@ -1,156 +0,0 @@ -/* - Copyright (C) 2012-2013 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 "grnxx/array/array_1d.hpp" - -#include <memory> -#include <new> - -#include "grnxx/logger.hpp" -#include "grnxx/storage.hpp" - -namespace grnxx { - -struct Array1DHeader { - uint64_t value_size; - uint64_t page_size; - uint32_t page_storage_node_id; - - Array1DHeader(uint64_t value_size, uint64_t page_size); -}; - -Array1DHeader::Array1DHeader(uint64_t value_size, uint64_t page_size) - : value_size(value_size), - page_size(page_size), - page_storage_node_id(STORAGE_INVALID_NODE_ID) {} - -Array1D::Array1D() - : storage_node_id_(STORAGE_INVALID_NODE_ID), - header_(nullptr), - page_(nullptr) {} - -Array1D::~Array1D() {} - -Array1D *Array1D::create(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - const void *default_value, FillPage fill_page) { - if (!storage) { - GRNXX_ERROR() << "invalid argument: storage = nullptr"; - return nullptr; - } - std::unique_ptr<Array1D> array(new (std::nothrow) Array1D); - if (!array) { - GRNXX_ERROR() << "new grnxx::Array1D failed: " - << "storage_node_id = " << storage_node_id - << ", value_size = " << value_size - << ", page_size = " << page_size - << ", has_default_value = " << (default_value != nullptr); - return nullptr; - } - if (!array->create_array(storage, storage_node_id, value_size, page_size, - default_value, fill_page)) { - return nullptr; - } - return array.release(); -} - -Array1D *Array1D::open(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size) { - if (!storage) { - GRNXX_ERROR() << "invalid argument: storage = nullptr"; - return nullptr; - } - std::unique_ptr<Array1D> array(new (std::nothrow) Array1D); - if (!array) { - GRNXX_ERROR() << "new grnxx::Array1D failed: " - << "storage_node_id = " << storage_node_id - << ", value_size = " << value_size - << ", page_size = " << page_size; - return nullptr; - } - if (!array->open_array(storage, storage_node_id, value_size, page_size)) { - return nullptr; - } - return array.release(); -} - -bool Array1D::unlink(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size) { - Array1D array; - if (!array.open(storage, storage_node_id, value_size, page_size)) { - return false; - } - return storage->unlink_node(storage_node_id); -} - -bool Array1D::create_array(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - const void *default_value, FillPage fill_page) { - StorageNode storage_node = - storage->create_node(storage_node_id, sizeof(Array1DHeader)); - if (!storage_node) { - return false; - } - storage_node_id_ = storage_node.id(); - header_ = static_cast<Array1DHeader *>(storage_node.body()); - *header_ = Array1DHeader(value_size, page_size); - StorageNode page_node = - storage->create_node(storage_node_id_, value_size * page_size); - if (!page_node) { - storage->unlink_node(storage_node_id_); - return false; - } - header_->page_storage_node_id = page_node.id(); - page_ = page_node.body(); - if (default_value) { - fill_page(page_, default_value); - } - return true; -} - -bool Array1D::open_array(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size) { - StorageNode storage_node = storage->open_node(storage_node_id); - if (!storage_node) { - return false; - } - if (storage_node.size() < sizeof(Array1DHeader)) { - GRNXX_ERROR() << "invalid format: node_size = " << storage_node.size() - << ", header_size = " << sizeof(Array1DHeader); - return false; - } - storage_node_id_ = storage_node.id(); - header_ = static_cast<Array1DHeader *>(storage_node.body()); - if (header_->value_size != value_size) { - GRNXX_ERROR() << "parameter conflict: value_size = " << value_size - << ", stored_value_size = " << header_->value_size; - return false; - } - if (header_->page_size != page_size) { - GRNXX_ERROR() << "parameter conflict: page_size = " << page_size - << ", stored_page_size = " << header_->page_size; - return false; - } - StorageNode page_node = storage->open_node(header_->page_storage_node_id); - if (!page_node) { - return false; - } - page_ = page_node.body(); - return true; -} - -} // namespace grnxx Deleted: lib/grnxx/array/array_1d.hpp (+0 -72) 100644 =================================================================== --- lib/grnxx/array/array_1d.hpp 2013-05-24 20:09:55 +0900 (793c151) +++ /dev/null @@ -1,72 +0,0 @@ -/* - Copyright (C) 2012-2013 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_ARRAY_ARRAY_1D_HPP -#define GRNXX_ARRAY_ARRAY_1D_HPP - -#include "grnxx/features.hpp" -#include "grnxx/types.hpp" - -namespace grnxx { - -class Storage; - -struct Array1DHeader; - -class Array1D { - using FillPage = void (*)(void *page, const void *value); - - public: - Array1D(); - ~Array1D(); - - static Array1D *create(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - const void *default_value = nullptr, - FillPage fill_page = nullptr); - - static Array1D *open(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size); - - static bool unlink(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size); - - uint32_t storage_node_id() const { - return storage_node_id_; - } - - template <typename T> - T *get_page() { - return static_cast<T *>(page_); - } - - private: - uint32_t storage_node_id_; - Array1DHeader *header_; - void *page_; - - bool create_array(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - const void *default_value, FillPage fill_page); - bool open_array(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size); - -}; - -} // namespace grnxx - -#endif // GRNXX_ARRAY_ARRAY_1D_HPP Deleted: lib/grnxx/array/array_2d.cpp (+0 -254) 100644 =================================================================== --- lib/grnxx/array/array_2d.cpp 2013-05-24 20:09:55 +0900 (f21a550) +++ /dev/null @@ -1,254 +0,0 @@ -/* - Copyright (C) 2012-2013 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 "grnxx/array/array_2d.hpp" - -#include <cstring> -#include <new> - -#include "grnxx/exception.hpp" -#include "grnxx/lock.hpp" -#include "grnxx/logger.hpp" -#include "grnxx/storage.hpp" - -namespace grnxx { - -struct Array2DHeader { - uint64_t value_size; - uint64_t page_size; - uint64_t table_size; - uint32_t has_default_value; - uint32_t table_storage_node_id; - Mutex mutex; - - Array2DHeader(uint64_t value_size, uint64_t page_size, - uint64_t table_size, bool has_default_value); -}; - -Array2DHeader::Array2DHeader(uint64_t value_size, uint64_t page_size, - uint64_t table_size, bool has_default_value) - : value_size(value_size), - page_size(page_size), - table_size(table_size), - has_default_value(has_default_value ? 1 : 0), - table_storage_node_id(STORAGE_INVALID_NODE_ID), - mutex(MUTEX_UNLOCKED) {} - -Array2D::Array2D() - : storage_(nullptr), - storage_node_id_(STORAGE_INVALID_NODE_ID), - header_(nullptr), - default_value_(nullptr), - fill_page_(nullptr), - table_(nullptr), - table_cache_(), - mutex_(MUTEX_UNLOCKED) {} - -Array2D::~Array2D() {} - -Array2D *Array2D::create(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - uint64_t table_size, - const void *default_value, FillPage fill_page) { - if (!storage) { - GRNXX_ERROR() << "invalid argument: storage = nullptr"; - return nullptr; - } - std::unique_ptr<Array2D> array(new (std::nothrow) Array2D); - if (!array) { - GRNXX_ERROR() << "new grnxx::Array2D failed: " - << "storage_node_id = " << storage_node_id - << ", value_size = " << value_size - << ", page_size = " << page_size - << ", table_size = " << table_size - << ", has_default_value = " << (default_value != nullptr); - return nullptr; - } - if (!array->create_array(storage, storage_node_id, - value_size, page_size, table_size, - default_value, fill_page)) { - return nullptr; - } - return array.release(); -} - -Array2D *Array2D::open(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - uint64_t table_size, FillPage fill_page) { - if (!storage) { - GRNXX_ERROR() << "invalid argument: storage = nullptr"; - return nullptr; - } - std::unique_ptr<Array2D> array(new (std::nothrow) Array2D); - if (!array) { - GRNXX_ERROR() << "new grnxx::Array2D failed: " - << "storage_node_id = " << storage_node_id - << ", value_size = " << value_size - << ", page_size = " << page_size - << ", table_size = " << table_size; - return nullptr; - } - if (!array->open_array(storage, storage_node_id, - value_size, page_size, table_size, - fill_page)) { - return nullptr; - } - return array.release(); -} - -bool Array2D::unlink(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - uint64_t table_size) { - Array2D array; - if (!array.open(storage, storage_node_id, - value_size, page_size, table_size, nullptr)) { - return false; - } - return storage->unlink_node(storage_node_id); -} - -bool Array2D::create_array(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - uint64_t table_size, - const void *default_value, FillPage fill_page) { - storage_ = storage; - uint64_t storage_node_size = sizeof(Array2DHeader); - if (default_value) { - storage_node_size += value_size; - } - StorageNode storage_node = - storage->create_node(storage_node_id, storage_node_size); - if (!storage_node) { - return false; - } - storage_node_id_ = storage_node.id(); - header_ = static_cast<Array2DHeader *>(storage_node.body()); - *header_ = Array2DHeader(value_size, page_size, table_size, default_value); - if (default_value) { - default_value_ = header_ + 1; - std::memcpy(default_value_, default_value, value_size); - fill_page_ = fill_page; - } - StorageNode table_node = - storage->create_node(storage_node_id_, sizeof(uint32_t) * table_size); - if (!table_node) { - storage->unlink_node(storage_node_id_); - return false; - } - header_->table_storage_node_id = table_node.id(); - table_ = static_cast<uint32_t *>(table_node.body()); - for (uint64_t i = 0; i < table_size; ++i) { - table_[i] = STORAGE_INVALID_NODE_ID; - } - table_cache_.reset(new (std::nothrow) void *[table_size]); - if (!table_cache_) { - GRNXX_ERROR() << "new void *[] failed: size = " << table_size; - storage->unlink_node(storage_node_id_); - return false; - } - for (uint64_t i = 0; i < table_size; ++i) { - table_cache_[i] = nullptr; - } - return true; -} - -bool Array2D::open_array(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - uint64_t table_size, FillPage fill_page) { - storage_ = storage; - StorageNode storage_node = storage->open_node(storage_node_id); - if (!storage_node) { - return false; - } - if (storage_node.size() < sizeof(Array2DHeader)) { - GRNXX_ERROR() << "invalid format: node_size = " << storage_node.size() - << ", header_size = " << sizeof(Array2DHeader); - return false; - } - storage_node_id_ = storage_node.id(); - header_ = static_cast<Array2DHeader *>(storage_node.body()); - if (header_->value_size != value_size) { - GRNXX_ERROR() << "parameter conflict: value_size = " << value_size - << ", stored_value_size = " << header_->value_size; - return false; - } - if (header_->page_size != page_size) { - GRNXX_ERROR() << "parameter conflict: page_size = " << page_size - << ", stored_page_size = " << header_->page_size; - return false; - } - if (header_->table_size != table_size) { - GRNXX_ERROR() << "parameter conflict: table_size = " << table_size - << ", stored_table_size = " << header_->table_size; - return false; - } - default_value_ = header_ + 1; - fill_page_ = fill_page; - StorageNode table_node = storage->open_node(header_->table_storage_node_id); - if (!table_node) { - return false; - } - table_ = static_cast<uint32_t *>(table_node.body()); - table_cache_.reset(new (std::nothrow) void *[table_size]); - if (!table_cache_) { - GRNXX_ERROR() << "new void *[] failed: size = " << table_size; - return false; - } - for (uint64_t i = 0; i < table_size; ++i) { - table_cache_[i] = nullptr; - } - return true; -} - -void Array2D::initialize_page(uint64_t page_id) { - if (!initialize_page_nothrow(page_id)) { - GRNXX_ERROR() << "failed to initialize page: page_id = " << page_id; - GRNXX_THROW(); - } -} - -bool Array2D::initialize_page_nothrow(uint64_t page_id) { - Lock inter_thread_lock(&mutex_); - if (!table_cache_[page_id]) { - StorageNode page_node; - if (table_[page_id] == STORAGE_INVALID_NODE_ID) { - Lock inter_process_lock(&header_->mutex); - if (table_[page_id] == STORAGE_INVALID_NODE_ID) { - page_node = - storage_->create_node(header_->table_storage_node_id, - header_->value_size * header_->page_size); - if (!page_node) { - return false; - } - if (default_value_) { - fill_page_(page_node.body(), default_value_); - } - table_[page_id] = page_node.id(); - table_cache_[page_id] = page_node.body(); - return true; - } - } - page_node = storage_->open_node(table_[page_id]); - if (!page_node) { - return false; - } - table_cache_[page_id] = page_node.body(); - } - return true; -} - -} // namespace grnxx Deleted: lib/grnxx/array/array_2d.hpp (+0 -101) 100644 =================================================================== --- lib/grnxx/array/array_2d.hpp 2013-05-24 20:09:55 +0900 (8778f9b) +++ /dev/null @@ -1,101 +0,0 @@ -/* - Copyright (C) 2012-2013 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_ARRAY_ARRAY_2D_HPP -#define GRNXX_ARRAY_ARRAY_2D_HPP - -#include "grnxx/features.hpp" - -#include <memory> - -#include "grnxx/mutex.hpp" -#include "grnxx/types.hpp" - -namespace grnxx { - -class Storage; - -struct Array2DHeader; - -class Array2D { - using FillPage = void (*)(void *page, const void *value); - - public: - Array2D(); - ~Array2D(); - - static Array2D *create(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - uint64_t table_size, - const void *default_value = nullptr, - FillPage fill_page = nullptr); - - static Array2D *open(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - uint64_t table_size, FillPage fill_page); - - static bool unlink(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - uint64_t table_size); - - uint32_t storage_node_id() const { - return storage_node_id_; - } - - template <typename T, uint64_t TABLE_SIZE> - T *get_page(uint64_t page_id) { - if (!table_cache_[page_id]) { - initialize_page(page_id); - } - return static_cast<T *>(table_cache_[page_id]); - } - - template <typename T, uint64_t TABLE_SIZE> - T *get_page_nothrow(uint64_t page_id) { - if (!table_cache_[page_id]) { - if (!initialize_page_nothrow(page_id)) { - return nullptr; - } - } - return static_cast<T *>(table_cache_[page_id]); - } - - private: - Storage *storage_; - uint32_t storage_node_id_; - Array2DHeader *header_; - void *default_value_; - FillPage fill_page_; - uint32_t *table_; - std::unique_ptr<void *[]> table_cache_; - Mutex mutex_; - - bool create_array(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - uint64_t table_size, - const void *default_value, FillPage fill_page); - bool open_array(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, uint64_t table_size, - FillPage fill_page); - - void initialize_page(uint64_t page_id); - bool initialize_page_nothrow(uint64_t page_id); -}; - -} // namespace grnxx - -#endif // GRNXX_ARRAY_ARRAY_2D_HPP Renamed: lib/grnxx/array_impl.cpp (+353 -1) 50% =================================================================== --- lib/grnxx/array/array_3d.cpp 2013-05-24 20:09:55 +0900 (c15c587) +++ lib/grnxx/array_impl.cpp 2013-05-24 20:28:33 +0900 (9276522) @@ -15,7 +15,7 @@ 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 "grnxx/array/array_3d.hpp" +#include "grnxx/array_impl.hpp" #include <cstring> #include <new> @@ -27,6 +27,40 @@ namespace grnxx { +struct Array1DHeader { + uint64_t value_size; + uint64_t page_size; + uint32_t page_storage_node_id; + + Array1DHeader(uint64_t value_size, uint64_t page_size); +}; + +Array1DHeader::Array1DHeader(uint64_t value_size, uint64_t page_size) + : value_size(value_size), + page_size(page_size), + page_storage_node_id(STORAGE_INVALID_NODE_ID) {} + +struct Array2DHeader { + uint64_t value_size; + uint64_t page_size; + uint64_t table_size; + uint32_t has_default_value; + uint32_t table_storage_node_id; + Mutex mutex; + + Array2DHeader(uint64_t value_size, uint64_t page_size, + uint64_t table_size, bool has_default_value); +}; + +Array2DHeader::Array2DHeader(uint64_t value_size, uint64_t page_size, + uint64_t table_size, bool has_default_value) + : value_size(value_size), + page_size(page_size), + table_size(table_size), + has_default_value(has_default_value ? 1 : 0), + table_storage_node_id(STORAGE_INVALID_NODE_ID), + mutex(MUTEX_UNLOCKED) {} + struct Array3DHeader { uint64_t value_size; uint64_t page_size; @@ -56,6 +90,324 @@ Array3DHeader::Array3DHeader(uint64_t value_size, uint64_t page_size, table_mutex(MUTEX_UNLOCKED), secondary_table_mutex(MUTEX_UNLOCKED) {} +Array1D::Array1D() + : storage_node_id_(STORAGE_INVALID_NODE_ID), + header_(nullptr), + page_(nullptr) {} + +Array1D::~Array1D() {} + +Array1D *Array1D::create(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + const void *default_value, FillPage fill_page) { + if (!storage) { + GRNXX_ERROR() << "invalid argument: storage = nullptr"; + return nullptr; + } + std::unique_ptr<Array1D> array(new (std::nothrow) Array1D); + if (!array) { + GRNXX_ERROR() << "new grnxx::Array1D failed: " + << "storage_node_id = " << storage_node_id + << ", value_size = " << value_size + << ", page_size = " << page_size + << ", has_default_value = " << (default_value != nullptr); + return nullptr; + } + if (!array->create_array(storage, storage_node_id, value_size, page_size, + default_value, fill_page)) { + return nullptr; + } + return array.release(); +} + +Array1D *Array1D::open(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size) { + if (!storage) { + GRNXX_ERROR() << "invalid argument: storage = nullptr"; + return nullptr; + } + std::unique_ptr<Array1D> array(new (std::nothrow) Array1D); + if (!array) { + GRNXX_ERROR() << "new grnxx::Array1D failed: " + << "storage_node_id = " << storage_node_id + << ", value_size = " << value_size + << ", page_size = " << page_size; + return nullptr; + } + if (!array->open_array(storage, storage_node_id, value_size, page_size)) { + return nullptr; + } + return array.release(); +} + +bool Array1D::unlink(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size) { + Array1D array; + if (!array.open(storage, storage_node_id, value_size, page_size)) { + return false; + } + return storage->unlink_node(storage_node_id); +} + +bool Array1D::create_array(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + const void *default_value, FillPage fill_page) { + StorageNode storage_node = + storage->create_node(storage_node_id, sizeof(Array1DHeader)); + if (!storage_node) { + return false; + } + storage_node_id_ = storage_node.id(); + header_ = static_cast<Array1DHeader *>(storage_node.body()); + *header_ = Array1DHeader(value_size, page_size); + StorageNode page_node = + storage->create_node(storage_node_id_, value_size * page_size); + if (!page_node) { + storage->unlink_node(storage_node_id_); + return false; + } + header_->page_storage_node_id = page_node.id(); + page_ = page_node.body(); + if (default_value) { + fill_page(page_, default_value); + } + return true; +} + +bool Array1D::open_array(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size) { + StorageNode storage_node = storage->open_node(storage_node_id); + if (!storage_node) { + return false; + } + if (storage_node.size() < sizeof(Array1DHeader)) { + GRNXX_ERROR() << "invalid format: node_size = " << storage_node.size() + << ", header_size = " << sizeof(Array1DHeader); + return false; + } + storage_node_id_ = storage_node.id(); + header_ = static_cast<Array1DHeader *>(storage_node.body()); + if (header_->value_size != value_size) { + GRNXX_ERROR() << "parameter conflict: value_size = " << value_size + << ", stored_value_size = " << header_->value_size; + return false; + } + if (header_->page_size != page_size) { + GRNXX_ERROR() << "parameter conflict: page_size = " << page_size + << ", stored_page_size = " << header_->page_size; + return false; + } + StorageNode page_node = storage->open_node(header_->page_storage_node_id); + if (!page_node) { + return false; + } + page_ = page_node.body(); + return true; +} + +Array2D::Array2D() + : storage_(nullptr), + storage_node_id_(STORAGE_INVALID_NODE_ID), + header_(nullptr), + default_value_(nullptr), + fill_page_(nullptr), + table_(nullptr), + table_cache_(), + mutex_(MUTEX_UNLOCKED) {} + +Array2D::~Array2D() {} + +Array2D *Array2D::create(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + uint64_t table_size, + const void *default_value, FillPage fill_page) { + if (!storage) { + GRNXX_ERROR() << "invalid argument: storage = nullptr"; + return nullptr; + } + std::unique_ptr<Array2D> array(new (std::nothrow) Array2D); + if (!array) { + GRNXX_ERROR() << "new grnxx::Array2D failed: " + << "storage_node_id = " << storage_node_id + << ", value_size = " << value_size + << ", page_size = " << page_size + << ", table_size = " << table_size + << ", has_default_value = " << (default_value != nullptr); + return nullptr; + } + if (!array->create_array(storage, storage_node_id, + value_size, page_size, table_size, + default_value, fill_page)) { + return nullptr; + } + return array.release(); +} + +Array2D *Array2D::open(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + uint64_t table_size, FillPage fill_page) { + if (!storage) { + GRNXX_ERROR() << "invalid argument: storage = nullptr"; + return nullptr; + } + std::unique_ptr<Array2D> array(new (std::nothrow) Array2D); + if (!array) { + GRNXX_ERROR() << "new grnxx::Array2D failed: " + << "storage_node_id = " << storage_node_id + << ", value_size = " << value_size + << ", page_size = " << page_size + << ", table_size = " << table_size; + return nullptr; + } + if (!array->open_array(storage, storage_node_id, + value_size, page_size, table_size, + fill_page)) { + return nullptr; + } + return array.release(); +} + +bool Array2D::unlink(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + uint64_t table_size) { + Array2D array; + if (!array.open(storage, storage_node_id, + value_size, page_size, table_size, nullptr)) { + return false; + } + return storage->unlink_node(storage_node_id); +} + +bool Array2D::create_array(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + uint64_t table_size, + const void *default_value, FillPage fill_page) { + storage_ = storage; + uint64_t storage_node_size = sizeof(Array2DHeader); + if (default_value) { + storage_node_size += value_size; + } + StorageNode storage_node = + storage->create_node(storage_node_id, storage_node_size); + if (!storage_node) { + return false; + } + storage_node_id_ = storage_node.id(); + header_ = static_cast<Array2DHeader *>(storage_node.body()); + *header_ = Array2DHeader(value_size, page_size, table_size, default_value); + if (default_value) { + default_value_ = header_ + 1; + std::memcpy(default_value_, default_value, value_size); + fill_page_ = fill_page; + } + StorageNode table_node = + storage->create_node(storage_node_id_, sizeof(uint32_t) * table_size); + if (!table_node) { + storage->unlink_node(storage_node_id_); + return false; + } + header_->table_storage_node_id = table_node.id(); + table_ = static_cast<uint32_t *>(table_node.body()); + for (uint64_t i = 0; i < table_size; ++i) { + table_[i] = STORAGE_INVALID_NODE_ID; + } + table_cache_.reset(new (std::nothrow) void *[table_size]); + if (!table_cache_) { + GRNXX_ERROR() << "new void *[] failed: size = " << table_size; + storage->unlink_node(storage_node_id_); + return false; + } + for (uint64_t i = 0; i < table_size; ++i) { + table_cache_[i] = nullptr; + } + return true; +} + +bool Array2D::open_array(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + uint64_t table_size, FillPage fill_page) { + storage_ = storage; + StorageNode storage_node = storage->open_node(storage_node_id); + if (!storage_node) { + return false; + } + if (storage_node.size() < sizeof(Array2DHeader)) { + GRNXX_ERROR() << "invalid format: node_size = " << storage_node.size() + << ", header_size = " << sizeof(Array2DHeader); + return false; + } + storage_node_id_ = storage_node.id(); + header_ = static_cast<Array2DHeader *>(storage_node.body()); + if (header_->value_size != value_size) { + GRNXX_ERROR() << "parameter conflict: value_size = " << value_size + << ", stored_value_size = " << header_->value_size; + return false; + } + if (header_->page_size != page_size) { + GRNXX_ERROR() << "parameter conflict: page_size = " << page_size + << ", stored_page_size = " << header_->page_size; + return false; + } + if (header_->table_size != table_size) { + GRNXX_ERROR() << "parameter conflict: table_size = " << table_size + << ", stored_table_size = " << header_->table_size; + return false; + } + default_value_ = header_ + 1; + fill_page_ = fill_page; + StorageNode table_node = storage->open_node(header_->table_storage_node_id); + if (!table_node) { + return false; + } + table_ = static_cast<uint32_t *>(table_node.body()); + table_cache_.reset(new (std::nothrow) void *[table_size]); + if (!table_cache_) { + GRNXX_ERROR() << "new void *[] failed: size = " << table_size; + return false; + } + for (uint64_t i = 0; i < table_size; ++i) { + table_cache_[i] = nullptr; + } + return true; +} + +void Array2D::initialize_page(uint64_t page_id) { + if (!initialize_page_nothrow(page_id)) { + GRNXX_ERROR() << "failed to initialize page: page_id = " << page_id; + GRNXX_THROW(); + } +} + +bool Array2D::initialize_page_nothrow(uint64_t page_id) { + Lock inter_thread_lock(&mutex_); + if (!table_cache_[page_id]) { + StorageNode page_node; + if (table_[page_id] == STORAGE_INVALID_NODE_ID) { + Lock inter_process_lock(&header_->mutex); + if (table_[page_id] == STORAGE_INVALID_NODE_ID) { + page_node = + storage_->create_node(header_->table_storage_node_id, + header_->value_size * header_->page_size); + if (!page_node) { + return false; + } + if (default_value_) { + fill_page_(page_node.body(), default_value_); + } + table_[page_id] = page_node.id(); + table_cache_[page_id] = page_node.body(); + return true; + } + } + page_node = storage_->open_node(table_[page_id]); + if (!page_node) { + return false; + } + table_cache_[page_id] = page_node.body(); + } + return true; +} + Array3D::Array3D() : storage_(nullptr), storage_node_id_(STORAGE_INVALID_NODE_ID), Renamed: lib/grnxx/array_impl.hpp (+110 -3) 52% =================================================================== --- lib/grnxx/array/array_3d.hpp 2013-05-24 20:09:55 +0900 (0852efa) +++ lib/grnxx/array_impl.hpp 2013-05-24 20:28:33 +0900 (e623075) @@ -15,8 +15,8 @@ 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_ARRAY_ARRAY_3D_HPP -#define GRNXX_ARRAY_ARRAY_3D_HPP +#ifndef GRNXX_ARRAY_IMPL_HPP +#define GRNXX_ARRAY_IMPL_HPP #include "grnxx/features.hpp" @@ -29,8 +29,115 @@ namespace grnxx { class Storage; +struct Array1DHeader; +struct Array2DHeader; struct Array3DHeader; +class Array1D { + using FillPage = void (*)(void *page, const void *value); + + public: + Array1D(); + ~Array1D(); + + static Array1D *create(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + const void *default_value = nullptr, + FillPage fill_page = nullptr); + + static Array1D *open(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size); + + static bool unlink(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size); + + uint32_t storage_node_id() const { + return storage_node_id_; + } + + template <typename T> + T *get_page() { + return static_cast<T *>(page_); + } + + private: + uint32_t storage_node_id_; + Array1DHeader *header_; + void *page_; + + bool create_array(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + const void *default_value, FillPage fill_page); + bool open_array(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size); + +}; + +class Array2D { + using FillPage = void (*)(void *page, const void *value); + + public: + Array2D(); + ~Array2D(); + + static Array2D *create(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + uint64_t table_size, + const void *default_value = nullptr, + FillPage fill_page = nullptr); + + static Array2D *open(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + uint64_t table_size, FillPage fill_page); + + static bool unlink(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + uint64_t table_size); + + uint32_t storage_node_id() const { + return storage_node_id_; + } + + template <typename T, uint64_t TABLE_SIZE> + T *get_page(uint64_t page_id) { + if (!table_cache_[page_id]) { + initialize_page(page_id); + } + return static_cast<T *>(table_cache_[page_id]); + } + + template <typename T, uint64_t TABLE_SIZE> + T *get_page_nothrow(uint64_t page_id) { + if (!table_cache_[page_id]) { + if (!initialize_page_nothrow(page_id)) { + return nullptr; + } + } + return static_cast<T *>(table_cache_[page_id]); + } + + private: + Storage *storage_; + uint32_t storage_node_id_; + Array2DHeader *header_; + void *default_value_; + FillPage fill_page_; + uint32_t *table_; + std::unique_ptr<void *[]> table_cache_; + Mutex mutex_; + + bool create_array(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + uint64_t table_size, + const void *default_value, FillPage fill_page); + bool open_array(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, uint64_t table_size, + FillPage fill_page); + + void initialize_page(uint64_t page_id); + bool initialize_page_nothrow(uint64_t page_id); +}; + class Array3D { using FillPage = void (*)(void *page, const void *value); @@ -108,4 +215,4 @@ class Array3D { } // namespace grnxx -#endif // GRNXX_ARRAY_ARRAY_3D_HPP +#endif // GRNXX_ARRAY_IMPL_HPP -------------- next part -------------- HTML����������������������������...Download