susumu.yata
null+****@clear*****
Wed May 29 18:13:37 JST 2013
susumu.yata 2013-05-29 18:13:37 +0900 (Wed, 29 May 2013) New Revision: f20a188e2c346e65dbe4ceff0455922dc9a57071 https://github.com/groonga/grnxx/commit/f20a188e2c346e65dbe4ceff0455922dc9a57071 Message: Add gnrxx::map::BytesArray. Added files: lib/grnxx/map/bytes_array.cpp lib/grnxx/map/bytes_array.hpp Modified files: lib/grnxx/map/Makefile.am lib/grnxx/map/bytes_store.hpp Modified: lib/grnxx/map/Makefile.am (+2 -0) =================================================================== --- lib/grnxx/map/Makefile.am 2013-05-29 17:36:06 +0900 (76179d5) +++ lib/grnxx/map/Makefile.am 2013-05-29 18:13:37 +0900 (d6591bb) @@ -4,6 +4,7 @@ libgrnxx_map_la_LDFLAGS = @AM_LTLDFLAGS@ libgrnxx_map_la_SOURCES = \ array_map.cpp \ + bytes_array.cpp \ bytes_store.cpp \ cursor_impl.cpp \ scanner_impl.cpp @@ -11,6 +12,7 @@ libgrnxx_map_la_SOURCES = \ libgrnxx_map_includedir = ${includedir}/grnxx/map libgrnxx_map_include_HEADERS = \ array_map.hpp \ + bytes_array.hpp \ bytes_store.hpp \ cursor_impl.hpp \ header.hpp \ Added: lib/grnxx/map/bytes_array.cpp (+180 -0) 100644 =================================================================== --- /dev/null +++ lib/grnxx/map/bytes_array.cpp 2013-05-29 18:13:37 +0900 (3f0f98e) @@ -0,0 +1,180 @@ +/* + Copyright (C) 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/map/bytes_array.hpp" + +#include <cstring> +#include <new> + +#include "grnxx/logger.hpp" +#include "grnxx/storage.hpp" + +namespace grnxx { +namespace map { + +struct BytesArrayHeader { + uint64_t default_value_size; + uint32_t ids_storage_node_id; + uint32_t store_storage_node_id; + + BytesArrayHeader(); +}; + +BytesArrayHeader::BytesArrayHeader() + : default_value_size(0), + ids_storage_node_id(STORAGE_INVALID_NODE_ID), + store_storage_node_id(STORAGE_INVALID_NODE_ID) {} + +BytesArray::~BytesArray() {} + +BytesArray *BytesArray::create(Storage *storage, uint32_t storage_node_id) { + return create(storage, storage_node_id, ""); +} + +BytesArray *BytesArray::create(Storage *storage, uint32_t storage_node_id, + ValueArg default_value) { + if (!storage) { + GRNXX_ERROR() << "invalid argument: storage = nullptr"; + return nullptr; + } + std::unique_ptr<BytesArray> array(new (std::nothrow) BytesArray); + if (!array) { + GRNXX_ERROR() << "new grnxx::map::BytesArray failed"; + return nullptr; + } + if (!array->create_array(storage, storage_node_id, default_value)) { + return nullptr; + } + return array.release(); +} + +BytesArray *BytesArray::open(Storage *storage, uint32_t storage_node_id) { + if (!storage) { + GRNXX_ERROR() << "invalid argument: storage = nullptr"; + return nullptr; + } + std::unique_ptr<BytesArray> array(new (std::nothrow) BytesArray); + if (!array) { + GRNXX_ERROR() << "new grnxx::map::BytesArray failed"; + return nullptr; + } + if (!array->open_array(storage, storage_node_id)) { + return nullptr; + } + return array.release(); +} + +bool BytesArray::unlink(Storage *storage, uint32_t storage_node_id) { + std::unique_ptr<BytesArray> array(open(storage, storage_node_id)); + if (!array) { + return false; + } + return storage->unlink_node(storage_node_id); +} + +bool BytesArray::get(uint64_t value_id, Value *value) { + uint64_t bytes_id; + if (!ids_->get(value_id, &bytes_id)) { + return false; + } + if (value) { + if (bytes_id == BYTES_STORE_INVALID_BYTES_ID) { + *value = default_value_; + } else { + return store_->get(bytes_id, value); + } + } + return true; +} + +bool BytesArray::set(uint64_t value_id, ValueArg value) { + uint64_t src_bytes_id; + if (!ids_->get(value_id, &src_bytes_id)) { + return false; + } + uint64_t dest_bytes_id; + if (!store_->add(value, &dest_bytes_id)) { + return false; + } + if (src_bytes_id != BYTES_STORE_INVALID_BYTES_ID) { + if (!store_->unset(src_bytes_id)) { + // The following unset() may not fail due to the above add(). + store_->unset(dest_bytes_id); + return false; + } + } + // The following set() must not fail due to the above get(). + ids_->set(value_id, dest_bytes_id); + return true; +} + +BytesArray::BytesArray() + : storage_(nullptr), + storage_node_id_(STORAGE_INVALID_NODE_ID), + header_(nullptr), + default_value_(), + ids_(), + store_() {} + +// Create an array with the default value. +bool BytesArray::create_array(Storage *storage, uint32_t storage_node_id, + ValueArg default_value) { + storage_ = storage; + uint64_t storage_node_size = sizeof(BytesArrayHeader) + default_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<BytesArrayHeader *>(storage_node.body()); + *header_ = BytesArrayHeader(); + header_->default_value_size = default_value.size(); + std::memcpy(header_ + 1, default_value.ptr(), default_value.size()); + default_value_ = Value(header_ + 1, default_value.size()); + ids_.reset(IDArray::create(storage, storage_node_id_, + BYTES_STORE_INVALID_BYTES_ID)); + store_.reset(BytesStore::create(storage, storage_node_id_)); + if (!ids_ || !store_) { + storage->unlink_node(storage_node_id_); + return false; + } + header_->ids_storage_node_id = ids_->storage_node_id(); + header_->store_storage_node_id = store_->storage_node_id(); + return true; +} + +// Open an array. +bool BytesArray::open_array(Storage *storage, uint32_t storage_node_id) { + storage_ = storage; + StorageNode storage_node = storage->open_node(storage_node_id); + if (!storage_node) { + return false; + } + storage_node_id_ = storage_node.id(); + header_ = static_cast<BytesArrayHeader *>(storage_node.body()); + default_value_ = Value(header_ + 1, header_->default_value_size); + ids_.reset(IDArray::open(storage, header_->ids_storage_node_id)); + store_.reset(BytesStore::open(storage, header_->store_storage_node_id)); + if (!ids_ || !store_) { + return false; + } + return true; +} + +} // namespace map +} // namespace grnxx Added: lib/grnxx/map/bytes_array.hpp (+108 -0) 100644 =================================================================== --- /dev/null +++ lib/grnxx/map/bytes_array.hpp 2013-05-29 18:13:37 +0900 (e162389) @@ -0,0 +1,108 @@ +/* + Copyright (C) 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_MAP_BYTES_ARRAY_HPP +#define GRNXX_MAP_BYTES_ARRAY_HPP + +#include "grnxx/features.hpp" + +#include <memory> + +#include "grnxx/array.hpp" +#include "grnxx/bytes.hpp" +#include "grnxx/duration.hpp" +#include "grnxx/map/bytes_store.hpp" +#include "grnxx/traits.hpp" +#include "grnxx/types.hpp" + +namespace grnxx { + +class Storage; + +namespace map { + +struct BytesArrayHeader; + +class BytesArray { + public: + using Value = typename Traits<Bytes>::Type; + using ValueArg = typename Traits<Bytes>::ArgumentType; + + using IDArray = Array<uint64_t>; + + ~BytesArray(); + + // Create an array. + static BytesArray *create(Storage *storage, uint32_t storage_node_id); + // Create an array with the default value. + static BytesArray *create(Storage *storage, uint32_t storage_node_id, + ValueArg default_value); + // Open an array. + static BytesArray *open(Storage *storage, uint32_t storage_node_id); + + // Unlink an array. + static bool unlink(Storage *storage, uint32_t storage_node_id); + + // Return the number of values in each page. + static constexpr uint64_t page_size() { + return IDArray::page_size(); + } + // Return the number of pages in each table. + static constexpr uint64_t table_size() { + return IDArray::table_size(); + } + // Return the number of tables in each secondary table. + static constexpr uint64_t secondary_table_size() { + return IDArray::secondary_table_size(); + } + // Return the number of values in Array. + static constexpr uint64_t size() { + return IDArray::size(); + } + + // Return the storage node ID. + uint32_t storage_node_id() const { + return storage_node_id_; + } + + // 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); + // Set a value and return true on success. + bool set(uint64_t value_id, ValueArg value); + + private: + Storage *storage_; + uint32_t storage_node_id_; + BytesArrayHeader *header_; + Value default_value_; + std::unique_ptr<IDArray> ids_; + std::unique_ptr<BytesStore> store_; + + BytesArray(); + + // Create an array with the default value. + bool create_array(Storage *storage, uint32_t storage_node_id, + ValueArg default_value); + // Open an array. + bool open_array(Storage *storage, uint32_t storage_node_id); +}; + +} // namespace map +} // namespace grnxx + +#endif // GRNXX_MAP_BYTES_ARRAY_HPP Modified: lib/grnxx/map/bytes_store.hpp (+4 -1) =================================================================== --- lib/grnxx/map/bytes_store.hpp 2013-05-29 17:36:06 +0900 (a782418) +++ lib/grnxx/map/bytes_store.hpp 2013-05-29 18:13:37 +0900 (c648d85) @@ -32,9 +32,12 @@ class Storage; namespace map { +// TODO: Fix this value. +constexpr uint64_t BYTES_STORE_INVALID_BYTES_ID = 1ULL << 62; + class BytesStore { public: - using Value = Bytes; + using Value = typename Traits<Bytes>::Type; using ValueArg = typename Traits<Bytes>::ArgumentType; BytesStore(); -------------- next part -------------- HTML����������������������������...Download