[Groonga-commit] groonga/grnxx at f20a188 [master] Add gnrxx::map::BytesArray.

Back to archive index

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 



More information about the Groonga-commit mailing list
Back to archive index