susumu.yata
null+****@clear*****
Mon May 13 18:42:27 JST 2013
susumu.yata 2013-05-13 18:42:27 +0900 (Mon, 13 May 2013) New Revision: 2f56c0699ef60729bf09c305d61566355071f5f2 https://github.com/groonga/grnxx/commit/2f56c0699ef60729bf09c305d61566355071f5f2 Message: Change the interface of grnxx::Array and update tests. Modified files: lib/grnxx/array.hpp lib/grnxx/array/array_1d.cpp lib/grnxx/array/array_1d.hpp lib/grnxx/array/array_2d.cpp lib/grnxx/array/array_2d.hpp lib/grnxx/array/array_3d.cpp lib/grnxx/array/array_3d.hpp test/test_array.cpp Modified: lib/grnxx/array.hpp (+102 -120) =================================================================== --- lib/grnxx/array.hpp 2013-05-13 17:59:31 +0900 (4c49d4f) +++ lib/grnxx/array.hpp 2013-05-13 18:42:27 +0900 (ed51bee) @@ -53,49 +53,47 @@ class Array<T, PAGE_SIZE, 1, 1> { using ValueArg = typename Traits<T>::ArgumentType; public: + Array() : impl_() {} ~Array() {} + // Return true iff the array is valid. + explicit operator bool() const { + return static_cast<bool>(impl_); + } + // Create an array. - static Array *create(Storage *storage, uint32_t storage_node_id) { - std::unique_ptr<Array> array(new (std::nothrow) Array); - if (!array) { - GRNXX_ERROR() << "new grnxx::Array failed: PAGE_SIZE = " << PAGE_SIZE; - return nullptr; - } - if (!array->impl_.create(storage, storage_node_id, sizeof(Value), - PAGE_SIZE)) { - return nullptr; + bool create(Storage *storage, uint32_t storage_node_id) { + std::unique_ptr<Array1D> impl( + Array1D::create(storage, storage_node_id, sizeof(Value), PAGE_SIZE)); + if (!impl) { + return false; } - return array.release(); + impl_ = std::move(impl); + return true; } // Create an array with the default value. - static Array *create(Storage *storage, uint32_t storage_node_id, + bool create(Storage *storage, uint32_t storage_node_id, ValueArg default_value) { - std::unique_ptr<Array> array(new (std::nothrow) Array); - if (!array) { - GRNXX_ERROR() << "new grnxx::Array failed: PAGE_SIZE = " << PAGE_SIZE; - return nullptr; - } - if (!array->impl_.create(storage, storage_node_id, sizeof(Value), - PAGE_SIZE, &default_value, fill_page)) { - return nullptr; + std::unique_ptr<Array1D> impl( + Array1D::create(storage, storage_node_id, sizeof(Value), PAGE_SIZE, + &default_value, fill_page)); + if (!impl) { + return false; } - return array.release(); + impl_ = std::move(impl); + return true; } // Open an array. - static Array *open(Storage *storage, uint32_t storage_node_id) { - std::unique_ptr<Array> array(new (std::nothrow) Array); - if (!array) { - GRNXX_ERROR() << "new grnxx::Array failed: PAGE_SIZE = " << PAGE_SIZE; - return nullptr; - } - if (!array->impl_.open(storage, storage_node_id, sizeof(Value), - PAGE_SIZE)) { - return nullptr; + bool open(Storage *storage, uint32_t storage_node_id) { + std::unique_ptr<Array1D> impl( + Array1D::open(storage, storage_node_id, sizeof(Value), PAGE_SIZE)); + if (!impl) { + return false; } - return array.release(); + impl_ = std::move(impl); + return true; } // Unlink an array. @@ -122,7 +120,7 @@ class Array<T, PAGE_SIZE, 1, 1> { // Return the storage node ID. uint32_t storage_node_id() const { - return impl_.storage_node_id(); + return impl_->storage_node_id(); } // Get a reference to a value. @@ -148,13 +146,11 @@ class Array<T, PAGE_SIZE, 1, 1> { // Get a page and return its starting address. Value *get_page(uint64_t) { - return impl_.get_page<Value>(); + return impl_->get_page<Value>(); } private: - Array1D impl_; - - Array() : impl_() {} + std::unique_ptr<Array1D> impl_; // This function is used to fill a new page with the default value. static void fill_page(void *page, const void *value) { @@ -176,53 +172,49 @@ class Array<T, PAGE_SIZE, TABLE_SIZE, 1> { using ValueArg = typename Traits<T>::ArgumentType; public: + Array() : impl_() {} ~Array() {} + // Return true iff the array is valid. + explicit operator bool() const { + return static_cast<bool>(impl_); + } + // Create an array. - static Array *create(Storage *storage, uint32_t storage_node_id) { - std::unique_ptr<Array> array(new (std::nothrow) Array); - if (!array) { - GRNXX_ERROR() << "new grnxx::Array failed: PAGE_SIZE = " << PAGE_SIZE - << ", TABLE_SIZE = " << TABLE_SIZE; - return nullptr; - } - if (!array->impl_.create(storage, storage_node_id, sizeof(Value), - PAGE_SIZE, TABLE_SIZE)) { - return nullptr; + bool create(Storage *storage, uint32_t storage_node_id) { + std::unique_ptr<Array2D> impl( + Array2D::create(storage, storage_node_id, sizeof(Value), PAGE_SIZE, + TABLE_SIZE)); + if (!impl) { + return false; } - return array.release(); + impl_ = std::move(impl); + return true; } // Create an array with the default value. - static Array *create(Storage *storage, uint32_t storage_node_id, + bool create(Storage *storage, uint32_t storage_node_id, ValueArg default_value) { - std::unique_ptr<Array> array(new (std::nothrow) Array); - if (!array) { - GRNXX_ERROR() << "new grnxx::Array failed: PAGE_SIZE = " << PAGE_SIZE - << ", TABLE_SIZE = " << TABLE_SIZE; - return nullptr; - } - if (!array->impl_.create(storage, storage_node_id, sizeof(Value), - PAGE_SIZE, TABLE_SIZE, - &default_value, fill_page)) { - return nullptr; + std::unique_ptr<Array2D> impl( + Array2D::create(storage, storage_node_id, sizeof(Value), PAGE_SIZE, + TABLE_SIZE, &default_value, fill_page)); + if (!impl) { + return false; } - return array.release(); + impl_ = std::move(impl); + return true; } // Open an array. - static Array *open(Storage *storage, uint32_t storage_node_id) { - std::unique_ptr<Array> array(new (std::nothrow) Array); - if (!array) { - GRNXX_ERROR() << "new grnxx::Array failed: PAGE_SIZE = " << PAGE_SIZE - << ", TABLE_SIZE = " << TABLE_SIZE; - return nullptr; - } - if (!array->impl_.open(storage, storage_node_id, sizeof(Value), - PAGE_SIZE, TABLE_SIZE)) { - return nullptr; + bool open(Storage *storage, uint32_t storage_node_id) { + std::unique_ptr<Array2D> impl( + Array2D::open(storage, storage_node_id, sizeof(Value), PAGE_SIZE, + TABLE_SIZE, fill_page)); + if (!impl) { + return false; } - return array.release(); + impl_ = std::move(impl); + return true; } // Unlink an array. @@ -250,14 +242,14 @@ class Array<T, PAGE_SIZE, TABLE_SIZE, 1> { // Return the storage node ID. uint32_t storage_node_id() const { - return impl_.storage_node_id(); + return impl_->storage_node_id(); } // Get a reference to a value. // This function throws an exception on failure. Value &operator[](uint64_t value_id) { Value * const page = - impl_.get_page<Value, TABLE_SIZE>(value_id / PAGE_SIZE); + impl_->get_page<Value, TABLE_SIZE>(value_id / PAGE_SIZE); return page[value_id % PAGE_SIZE]; } @@ -284,13 +276,11 @@ class Array<T, PAGE_SIZE, TABLE_SIZE, 1> { // Get a page and return its starting address on success. Value *get_page(uint64_t page_id) { - return impl_.get_page_nothrow<Value, TABLE_SIZE>(page_id); + return impl_->get_page_nothrow<Value, TABLE_SIZE>(page_id); } private: - Array2D impl_; - - Array() : impl_() {} + std::unique_ptr<Array2D> impl_; // This function is used to fill a new page with the default value. static void fill_page(void *page, const void *value) { @@ -317,56 +307,50 @@ class Array { using ValueArg = typename Traits<T>::ArgumentType; public: + Array() : impl_() {} ~Array() {} + // Return true iff the array is valid. + explicit operator bool() const { + return static_cast<bool>(impl_); + } + // Create an array. - static Array *create(Storage *storage, uint32_t storage_node_id) { - std::unique_ptr<Array> array(new (std::nothrow) Array); - if (!array) { - GRNXX_ERROR() << "new grnxx::Array failed: PAGE_SIZE = " << PAGE_SIZE - << ", TABLE_SIZE = " << TABLE_SIZE - << ", SECONDARY_TABLE_SIZE = " << SECONDARY_TABLE_SIZE; - return nullptr; - } - if (!array->impl_.create(storage, storage_node_id, sizeof(Value), - PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE)) { - return nullptr; + bool create(Storage *storage, uint32_t storage_node_id) { + std::unique_ptr<Array3D> impl( + Array3D::create(storage, storage_node_id, sizeof(Value), PAGE_SIZE, + TABLE_SIZE, SECONDARY_TABLE_SIZE)); + if (!impl) { + return false; } - return array.release(); + impl_ = std::move(impl); + return true; } // Create an array with the default value. - static Array *create(Storage *storage, uint32_t storage_node_id, + bool create(Storage *storage, uint32_t storage_node_id, ValueArg default_value) { - std::unique_ptr<Array> array(new (std::nothrow) Array); - if (!array) { - GRNXX_ERROR() << "new grnxx::Array failed: PAGE_SIZE = " << PAGE_SIZE - << ", TABLE_SIZE = " << TABLE_SIZE - << ", SECONDARY_TABLE_SIZE = " << SECONDARY_TABLE_SIZE; - return nullptr; - } - if (!array->impl_.create(storage, storage_node_id, sizeof(Value), - PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE, - &default_value, fill_page)) { - return nullptr; + std::unique_ptr<Array3D> impl( + Array3D::create(storage, storage_node_id, sizeof(Value), PAGE_SIZE, + TABLE_SIZE, SECONDARY_TABLE_SIZE, &default_value, + fill_page)); + if (!impl) { + return false; } - return array.release(); + impl_ = std::move(impl); + return true; } // Open an array. - static Array *open(Storage *storage, uint32_t storage_node_id) { - std::unique_ptr<Array> array(new (std::nothrow) Array); - if (!array) { - GRNXX_ERROR() << "new grnxx::Array failed: PAGE_SIZE = " << PAGE_SIZE - << ", TABLE_SIZE = " << TABLE_SIZE - << ", SECONDARY_TABLE_SIZE = " << SECONDARY_TABLE_SIZE; - return nullptr; - } - if (!array->impl_.open(storage, storage_node_id, sizeof(Value), - PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE)) { - return nullptr; + bool open(Storage *storage, uint32_t storage_node_id) { + std::unique_ptr<Array3D> impl( + Array3D::open(storage, storage_node_id, sizeof(Value), PAGE_SIZE, + TABLE_SIZE, SECONDARY_TABLE_SIZE, fill_page)); + if (!impl) { + return false; } - return array.release(); + impl_ = std::move(impl); + return true; } // Unlink an array. @@ -394,15 +378,15 @@ class Array { // Return the storage node ID. uint32_t storage_node_id() const { - return impl_.storage_node_id(); + return impl_->storage_node_id(); } // Get a reference to a value. // This function throws an exception on failure. Value &operator[](uint64_t value_id) { Value * const page = - impl_.get_page<Value, TABLE_SIZE, - SECONDARY_TABLE_SIZE>(value_id / PAGE_SIZE); + impl_->get_page<Value, TABLE_SIZE, + SECONDARY_TABLE_SIZE>(value_id / PAGE_SIZE); return page[value_id % PAGE_SIZE]; } @@ -429,14 +413,12 @@ class Array { // Get a page and return its starting address on success. Value *get_page(uint64_t page_id) { - return impl_.get_page_nothrow<Value, TABLE_SIZE, - SECONDARY_TABLE_SIZE>(page_id); + return impl_->get_page_nothrow<Value, TABLE_SIZE, + SECONDARY_TABLE_SIZE>(page_id); } private: - Array3D impl_; - - Array() : impl_() {} + std::unique_ptr<Array3D> impl_; // This function is used to fill a new page with the default value. static void fill_page(void *page, const void *value) { Modified: lib/grnxx/array/array_1d.cpp (+55 -18) =================================================================== --- lib/grnxx/array/array_1d.cpp 2013-05-13 17:59:31 +0900 (44fb14c) +++ lib/grnxx/array/array_1d.cpp 2013-05-13 18:42:27 +0900 (695ac78) @@ -17,6 +17,8 @@ */ #include "grnxx/array/array_1d.hpp" +#include <memory> + #include "grnxx/logger.hpp" namespace grnxx { @@ -41,13 +43,61 @@ Array1D::Array1D() Array1D::~Array1D() {} -bool Array1D::create(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - const void *default_value, FillPage fill_page) { +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) { storage_node_ = storage->create_node(storage_node_id, sizeof(Array1DHeader)); if (!storage_node_.is_valid()) { return false; @@ -68,12 +118,8 @@ bool Array1D::create(Storage *storage, uint32_t storage_node_id, return true; } -bool 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; - } +bool Array1D::open_array(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size) { storage_node_ = storage->open_node(storage_node_id); if (!storage_node_.is_valid()) { return false; @@ -97,13 +143,4 @@ bool Array1D::open(Storage *storage, uint32_t storage_node_id, return true; } -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); -} - } // namespace grnxx Modified: lib/grnxx/array/array_1d.hpp (+14 -6) =================================================================== --- lib/grnxx/array/array_1d.hpp 2013-05-13 17:59:31 +0900 (f4762c4) +++ lib/grnxx/array/array_1d.hpp 2013-05-13 18:42:27 +0900 (40d9039) @@ -32,12 +32,13 @@ class Array1D { Array1D(); ~Array1D(); - bool 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); - bool open(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size); + 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); @@ -55,6 +56,13 @@ class Array1D { StorageNode storage_node_; 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 Modified: lib/grnxx/array/array_2d.cpp (+64 -22) =================================================================== --- lib/grnxx/array/array_2d.cpp 2013-05-13 17:59:31 +0900 (47eddb1) +++ lib/grnxx/array/array_2d.cpp 2013-05-13 18:42:27 +0900 (0f8b2d0) @@ -60,14 +60,71 @@ Array2D::Array2D() Array2D::~Array2D() {} -bool 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) { +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) { @@ -107,13 +164,9 @@ bool Array2D::create(Storage *storage, uint32_t storage_node_id, return true; } -bool 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; - } +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; storage_node_ = storage->open_node(storage_node_id); if (!storage_node_.is_valid()) { @@ -153,17 +206,6 @@ bool Array2D::open(Storage *storage, uint32_t storage_node_id, return true; } -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); -} - void Array2D::initialize_page(uint64_t page_id) { if (!initialize_page_nothrow(page_id)) { GRNXX_ERROR() << "failed to initialize page: page_id = " << page_id; Modified: lib/grnxx/array/array_2d.hpp (+17 -7) =================================================================== --- lib/grnxx/array/array_2d.hpp 2013-05-13 17:59:31 +0900 (0cc8de8) +++ lib/grnxx/array/array_2d.hpp 2013-05-13 18:42:27 +0900 (c4e936f) @@ -33,13 +33,15 @@ class Array2D { Array2D(); ~Array2D(); - bool 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); - bool open(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, uint64_t table_size, - FillPage fill_page); + 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, @@ -77,6 +79,14 @@ class Array2D { 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); }; Modified: lib/grnxx/array/array_3d.cpp (+67 -23) =================================================================== --- lib/grnxx/array/array_3d.cpp 2013-05-13 17:59:31 +0900 (e07115e) +++ lib/grnxx/array/array_3d.cpp 2013-05-13 18:42:27 +0900 (00c209e) @@ -70,14 +70,73 @@ Array3D::Array3D() Array3D::~Array3D() {} -bool Array3D::create(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - uint64_t table_size, uint64_t secondary_table_size, - const void *default_value, FillPage fill_page) { +Array3D *Array3D::create(Storage *storage, uint32_t storage_node_id, + 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 (!storage) { + GRNXX_ERROR() << "invalid argument: storage = nullptr"; + return nullptr; + } + std::unique_ptr<Array3D> array(new (std::nothrow) Array3D); + if (!array) { + GRNXX_ERROR() << "new grnxx::Array3D failed: " + << "storage_node_id = " << storage_node_id + << ", value_size = " << value_size + << ", page_size = " << page_size + << ", table_size = " << table_size + << ", secondary_table_size = " << secondary_table_size + << ", has_default_value = " << (default_value != nullptr); + return nullptr; + } + if (!array->create_array(storage, storage_node_id, value_size, page_size, + table_size, secondary_table_size, + default_value, fill_page)) { + return nullptr; + } + return array.release(); +} + +Array3D *Array3D::open(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + uint64_t table_size, uint64_t secondary_table_size, + FillPage fill_page) { if (!storage) { GRNXX_ERROR() << "invalid argument: storage = nullptr"; return nullptr; } + std::unique_ptr<Array3D> array(new (std::nothrow) Array3D); + if (!array) { + GRNXX_ERROR() << "new grnxx::Array3D failed: " + << "storage_node_id = " << storage_node_id + << ", value_size = " << value_size + << ", page_size = " << page_size + << ", table_size = " << table_size + << ", secondary_table_size = " << secondary_table_size; + return nullptr; + } + if (!array->open_array(storage, storage_node_id, value_size, page_size, + table_size, secondary_table_size, fill_page)) { + return nullptr; + } + return array.release(); +} + +bool Array3D::unlink(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + uint64_t table_size, uint64_t secondary_table_size) { + Array3D array; + if (!array.open(storage, storage_node_id, value_size, page_size, + table_size, secondary_table_size, nullptr)) { + return false; + } + return storage->unlink_node(storage_node_id); +} + +bool Array3D::create_array(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + uint64_t table_size, uint64_t secondary_table_size, + const void *default_value, FillPage fill_page) { storage_ = storage; uint64_t storage_node_size = sizeof(Array3DHeader); if (default_value) { @@ -106,14 +165,10 @@ bool Array3D::create(Storage *storage, uint32_t storage_node_id, return true; } -bool Array3D::open(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - uint64_t table_size, uint64_t secondary_table_size, - FillPage fill_page) { - if (!storage) { - GRNXX_ERROR() << "invalid argument: storage = nullptr"; - return nullptr; - } +bool Array3D::open_array(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + uint64_t table_size, uint64_t secondary_table_size, + FillPage fill_page) { storage_ = storage; storage_node_ = storage->open_node(storage_node_id); if (!storage_node_.is_valid()) { @@ -154,17 +209,6 @@ bool Array3D::open(Storage *storage, uint32_t storage_node_id, return true; } -bool Array3D::unlink(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - uint64_t table_size, uint64_t secondary_table_size) { - Array3D array; - if (!array.open(storage, storage_node_id, value_size, page_size, - table_size, secondary_table_size, nullptr)) { - return false; - } - return storage->unlink_node(storage_node_id); -} - void Array3D::initialize_page(uint64_t table_id, uint64_t page_id) { if (!initialize_page_nothrow(table_id, page_id)) { GRNXX_ERROR() << "failed to initialize page: table_id = " << table_id Modified: lib/grnxx/array/array_3d.hpp (+19 -9) =================================================================== --- lib/grnxx/array/array_3d.hpp 2013-05-13 17:59:31 +0900 (0464bfe) +++ lib/grnxx/array/array_3d.hpp 2013-05-13 18:42:27 +0900 (120c83d) @@ -33,15 +33,16 @@ class Array3D { Array3D(); ~Array3D(); - bool create(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - uint64_t table_size, uint64_t secondary_table_size, - const void *default_value = nullptr, - FillPage fill_page = nullptr); - bool open(Storage *storage, uint32_t storage_node_id, - uint64_t value_size, uint64_t page_size, - uint64_t table_size, uint64_t secondary_table_size, - FillPage fill_page); + static Array3D *create(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + uint64_t table_size, uint64_t secondary_table_size, + const void *default_value = nullptr, + FillPage fill_page = nullptr); + + static Array3D *open(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + uint64_t table_size, uint64_t secondary_table_size, + FillPage fill_page); static bool unlink(Storage *storage, uint32_t storage_node_id, uint64_t value_size, uint64_t page_size, @@ -85,6 +86,15 @@ class Array3D { Mutex table_mutex_; Mutex secondary_table_mutex_; + bool create_array(Storage *storage, uint32_t storage_node_id, + uint64_t value_size, uint64_t page_size, + uint64_t table_size, uint64_t secondary_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, uint64_t secondary_table_size, + FillPage fill_page); + void initialize_page(uint64_t table_id, uint64_t page_id); bool initialize_page_nothrow(uint64_t table_id, uint64_t page_id); bool initialize_table(uint64_t table_id); Modified: test/test_array.cpp (+39 -40) =================================================================== --- test/test_array.cpp 2013-05-13 17:59:31 +0900 (fcdf0c9) +++ test/test_array.cpp 2013-05-13 18:42:27 +0900 (ddaeb70) @@ -29,34 +29,34 @@ void test_array1d() { GRNXX_NOTICE() << __PRETTY_FUNCTION__; std::unique_ptr<grnxx::Storage> storage(grnxx::Storage::create(nullptr)); - std::unique_ptr<grnxx::Array<int, PAGE_SIZE>> array; + grnxx::Array<int, PAGE_SIZE> array; - array.reset(array->create(storage.get(), grnxx::STORAGE_ROOT_NODE_ID)); + assert(array.create(storage.get(), grnxx::STORAGE_ROOT_NODE_ID)); assert(array); - assert(array->page_size() == PAGE_SIZE); - assert(array->table_size() == 1); - assert(array->secondary_table_size() == 1); - assert(array->size() == SIZE); + assert(array.page_size() == PAGE_SIZE); + assert(array.table_size() == 1); + assert(array.secondary_table_size() == 1); + assert(array.size() == SIZE); for (std::uint64_t i = 0; i < SIZE; ++i) { - assert(array->set(i, static_cast<int>(i))); + assert(array.set(i, static_cast<int>(i))); } for (std::uint64_t i = 0; i < SIZE; ++i) { int value; - assert(array->get(i, &value)); + assert(array.get(i, &value)); assert(value == static_cast<int>(i)); } for (std::uint64_t i = 0; i < (SIZE / PAGE_SIZE); ++i) { - assert(array->get_page(i)); + assert(array.get_page(i)); } - array.reset(array->create(storage.get(), grnxx::STORAGE_ROOT_NODE_ID, 1)); + assert(array.create(storage.get(), grnxx::STORAGE_ROOT_NODE_ID, 1)); assert(array); for (std::uint64_t i = 0; i < SIZE; ++i) { - assert((*array)[i] == 1); - (*array)[i] = static_cast<int>(i); + assert(array[i] == 1); + array[i] = static_cast<int>(i); } for (std::uint64_t i = 0; i < SIZE; ++i) { - assert((*array)[i] == static_cast<int>(i)); + assert(array[i] == static_cast<int>(i)); } } @@ -68,34 +68,34 @@ void test_array2d() { GRNXX_NOTICE() << __PRETTY_FUNCTION__; std::unique_ptr<grnxx::Storage> storage(grnxx::Storage::create(nullptr)); - std::unique_ptr<grnxx::Array<int, PAGE_SIZE, TABLE_SIZE>> array; + grnxx::Array<int, PAGE_SIZE, TABLE_SIZE> array; - array.reset(array->create(storage.get(), grnxx::STORAGE_ROOT_NODE_ID)); + assert(array.create(storage.get(), grnxx::STORAGE_ROOT_NODE_ID)); assert(array); - assert(array->page_size() == PAGE_SIZE); - assert(array->table_size() == TABLE_SIZE); - assert(array->secondary_table_size() == 1); - assert(array->size() == SIZE); + assert(array.page_size() == PAGE_SIZE); + assert(array.table_size() == TABLE_SIZE); + assert(array.secondary_table_size() == 1); + assert(array.size() == SIZE); for (std::uint64_t i = 0; i < SIZE; ++i) { - assert(array->set(i, static_cast<int>(i))); + assert(array.set(i, static_cast<int>(i))); } for (std::uint64_t i = 0; i < SIZE; ++i) { int value; - assert(array->get(i, &value)); + assert(array.get(i, &value)); assert(value == static_cast<int>(i)); } for (std::uint64_t i = 0; i < (SIZE / PAGE_SIZE); ++i) { - assert(array->get_page(i)); + assert(array.get_page(i)); } - array.reset(array->create(storage.get(), grnxx::STORAGE_ROOT_NODE_ID, 1)); + assert(array.create(storage.get(), grnxx::STORAGE_ROOT_NODE_ID, 1)); assert(array); for (std::uint64_t i = 0; i < SIZE; ++i) { - assert((*array)[i] == 1); - (*array)[i] = static_cast<int>(i); + assert(array[i] == 1); + array[i] = static_cast<int>(i); } for (std::uint64_t i = 0; i < SIZE; ++i) { - assert((*array)[i] == static_cast<int>(i)); + assert(array[i] == static_cast<int>(i)); } } @@ -109,35 +109,34 @@ void test_array3d() { GRNXX_NOTICE() << __PRETTY_FUNCTION__; std::unique_ptr<grnxx::Storage> storage(grnxx::Storage::create(nullptr)); - std::unique_ptr<grnxx::Array<int, PAGE_SIZE, TABLE_SIZE, - SECONDARY_TABLE_SIZE>> array; + grnxx::Array<int, PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE> array; - array.reset(array->create(storage.get(), grnxx::STORAGE_ROOT_NODE_ID)); + assert(array.create(storage.get(), grnxx::STORAGE_ROOT_NODE_ID)); assert(array); - assert(array->page_size() == PAGE_SIZE); - assert(array->table_size() == TABLE_SIZE); - assert(array->secondary_table_size() == SECONDARY_TABLE_SIZE); - assert(array->size() == SIZE); + assert(array.page_size() == PAGE_SIZE); + assert(array.table_size() == TABLE_SIZE); + assert(array.secondary_table_size() == SECONDARY_TABLE_SIZE); + assert(array.size() == SIZE); for (std::uint64_t i = 0; i < SIZE; ++i) { - assert(array->set(i, static_cast<int>(i))); + assert(array.set(i, static_cast<int>(i))); } for (std::uint64_t i = 0; i < SIZE; ++i) { int value; - assert(array->get(i, &value)); + assert(array.get(i, &value)); assert(value == static_cast<int>(i)); } for (std::uint64_t i = 0; i < (SIZE / PAGE_SIZE); ++i) { - assert(array->get_page(i)); + assert(array.get_page(i)); } - array.reset(array->create(storage.get(), grnxx::STORAGE_ROOT_NODE_ID, 1)); + assert(array.create(storage.get(), grnxx::STORAGE_ROOT_NODE_ID, 1)); assert(array); for (std::uint64_t i = 0; i < SIZE; ++i) { - assert((*array)[i] == 1); - (*array)[i] = static_cast<int>(i); + assert(array[i] == 1); + array[i] = static_cast<int>(i); } for (std::uint64_t i = 0; i < SIZE; ++i) { - assert((*array)[i] == static_cast<int>(i)); + assert(array[i] == static_cast<int>(i)); } } -------------- next part -------------- HTML����������������������������... Télécharger