[Groonga-commit] groonga/grnxx [master] Update the implementation of grnxx::db::Vector.

Back to archive index

susumu.yata null+****@clear*****
Thu Dec 6 21:29:51 JST 2012


susumu.yata	2012-12-06 21:29:51 +0900 (Thu, 06 Dec 2012)

  New Revision: 4d49d307af145e4985ded8259f2cb2338f6e5355
  https://github.com/groonga/grnxx/commit/4d49d307af145e4985ded8259f2cb2338f6e5355

  Log:
    Update the implementation of grnxx::db::Vector.

  Removed files:
    lib/db/vector_base.cpp
    lib/db/vector_base.hpp
  Modified files:
    lib/db/Makefile.am
    lib/db/blob_vector.cpp
    lib/db/blob_vector.hpp
    lib/db/vector.hpp
    test/test_db_vector.cpp

  Modified: lib/db/Makefile.am (+2 -3)
===================================================================
--- lib/db/Makefile.am    2012-12-06 20:37:22 +0900 (fdb9606)
+++ lib/db/Makefile.am    2012-12-06 21:29:51 +0900 (f60574e)
@@ -3,11 +3,10 @@ noinst_LTLIBRARIES = libgrnxx_db.la
 libgrnxx_db_la_SOURCES =	\
 	array.cpp		\
 	blob_vector.cpp		\
-	vector_base.cpp
+	vector.cpp
 
 libgrnxx_db_includedir = ${includedir}/grnxx/db
 libgrnxx_db_include_HEADERS =	\
 	array.hpp		\
 	blob_vector.hpp		\
-	vector.hpp		\
-	vector_base.hpp
+	vector.hpp

  Modified: lib/db/blob_vector.cpp (+19 -17)
===================================================================
--- lib/db/blob_vector.cpp    2012-12-06 20:37:22 +0900 (f762202)
+++ lib/db/blob_vector.cpp    2012-12-06 21:29:51 +0900 (09a4875)
@@ -19,6 +19,8 @@
 
 #include <ostream>
 
+#include "../exception.hpp"
+#include "../logger.hpp"
 #include "../lock.hpp"
 
 namespace grnxx {
@@ -129,7 +131,7 @@ const void *BlobVector::get_value_address(uint64_t id, uint64_t *length) {
       const uint8_t store_id = cell.medium_value_cell().store_id();
       const uint64_t offset = cell.medium_value_cell().offset();
       BlobVectorMediumValueStore &store = medium_value_stores_[store_id];
-      if (!store.is_open()) {
+      if (!store) {
         open_medium_value_store(store_id);
       }
       return &store[offset];
@@ -139,7 +141,7 @@ const void *BlobVector::get_value_address(uint64_t id, uint64_t *length) {
         *length = cell.large_value_cell().length();
       }
       const uint64_t offset = cell.large_value_cell().offset();
-      if (!large_value_store_.is_open()) {
+      if (!large_value_store_) {
         open_large_value_store();
       }
       return get_large_value_header(offset)->value();
@@ -220,7 +222,7 @@ void BlobVector::create_vector(io::Pool pool) {
   block_info_ = pool.create_block(sizeof(BlobVectorHeader));
 
   try {
-    cells_.create(&pool_, BlobVectorCell());
+    cells_.create(pool_, BlobVectorCell());
   } catch (...) {
     pool_.free_block(*block_info_);
     throw;
@@ -250,7 +252,7 @@ void BlobVector::open_vector(io::Pool pool, uint32_t block_id) {
   recycler_ = pool.mutable_recycler();
 
   // Open the core table.
-  cells_.open(&pool, header_->cells_block_id());
+  cells_.open(pool, header_->cells_block_id());
 }
 
 BlobVectorSmallValueCell BlobVector::create_small_value_cell(
@@ -262,7 +264,7 @@ BlobVectorMediumValueCell BlobVector::create_medium_value_cell(
     const void *ptr, uint64_t length) {
   const uint8_t store_id = get_store_id(length);
   BlobVectorMediumValueStore &store = medium_value_stores_[store_id];
-  if (!store.is_open()) {
+  if (!store) {
     open_medium_value_store(store_id);
   }
 
@@ -273,9 +275,9 @@ BlobVectorMediumValueCell BlobVector::create_medium_value_cell(
     // TODO: Reuse.
 
     offset = header_->medium_value_store_next_offsets(store_id);
-    if (offset > store.id_max()) {
+    if (offset > store.max_id()) {
       GRNXX_ERROR() << "store is full: offset = " << offset
-                    << ", id_max = " << store.id_max();
+                    << ", max_id = " << store.max_id();
       GRNXX_THROW();
     }
     header_->set_medium_value_store_next_offsets(store_id,
@@ -290,7 +292,7 @@ BlobVectorLargeValueCell BlobVector::create_large_value_cell(
     const void *ptr, uint64_t length) {
   typedef BlobVectorLargeValueHeader ValueHeader;
 
-  if (!large_value_store_.is_open()) {
+  if (!large_value_store_) {
     open_large_value_store();
   }
 
@@ -390,7 +392,7 @@ void BlobVector::free_value(BlobVectorCell cell) {
     case BLOB_VECTOR_LARGE_VALUE: {
       typedef BlobVectorLargeValueHeader ValueHeader;
       Lock lock(header_->mutable_large_value_store_mutex());
-      if (!large_value_store_.is_open()) {
+      if (!large_value_store_) {
         open_large_value_store();
       }
       const uint64_t offset = cell.large_value_cell().offset();
@@ -420,34 +422,34 @@ void BlobVector::free_value(BlobVectorCell cell) {
 void BlobVector::open_medium_value_store(uint8_t store_id) {
   Lock inter_thread_lock(&inter_thread_mutex_);
   BlobVectorMediumValueStore &store = medium_value_stores_[store_id];
-  if (!store.is_open()) {
+  if (!store) {
     if (header_->medium_value_store_block_ids(store_id) ==
         io::BLOCK_INVALID_ID) {
       Lock inter_process_lock(header_->mutable_inter_process_mutex());
       if (header_->medium_value_store_block_ids(store_id) ==
           io::BLOCK_INVALID_ID) {
-        store.create(&pool_);
+        store.create(pool_);
         header_->set_medium_value_store_block_ids(store_id, store.block_id());
       }
     }
-    if (!store.is_open()) {
-      store.open(&pool_, header_->medium_value_store_block_ids(store_id));
+    if (!store) {
+      store.open(pool_, header_->medium_value_store_block_ids(store_id));
     }
   }
 }
 
 void BlobVector::open_large_value_store() {
   Lock inter_thread_lock(&inter_thread_mutex_);
-  if (!large_value_store_.is_open()) {
+  if (!large_value_store_) {
     if (header_->large_value_store_block_id() == io::BLOCK_INVALID_ID) {
       Lock inter_process_lock(header_->mutable_inter_process_mutex());
       if (header_->large_value_store_block_id() == io::BLOCK_INVALID_ID) {
-        large_value_store_.create(&pool_);
+        large_value_store_.create(pool_);
         header_->set_large_value_store_block_id(large_value_store_.block_id());
       }
     }
-    if (!large_value_store_.is_open()) {
-      large_value_store_.open(&pool_, header_->large_value_store_block_id());
+    if (!large_value_store_) {
+      large_value_store_.open(pool_, header_->large_value_store_block_id());
     }
   }
 }

  Modified: lib/db/blob_vector.hpp (+1 -1)
===================================================================
--- lib/db/blob_vector.hpp    2012-12-06 20:37:22 +0900 (6bddced)
+++ lib/db/blob_vector.hpp    2012-12-06 21:29:51 +0900 (861ea53)
@@ -458,7 +458,7 @@ class BlobVector {
     return is_open() ? block_info_->id() : io::BLOCK_INVALID_ID;
   }
   uint64_t id_max() const {
-    return cells_.id_max();
+    return cells_.max_id();
   }
 
   void swap(BlobVector &rhs);

  Modified: lib/db/vector.hpp (+235 -74)
===================================================================
--- lib/db/vector.hpp    2012-12-06 20:37:22 +0900 (f26b0cd)
+++ lib/db/vector.hpp    2012-12-06 21:29:51 +0900 (a6b5172)
@@ -18,130 +18,288 @@
 #ifndef GRNXX_DB_VECTOR_HPP
 #define GRNXX_DB_VECTOR_HPP
 
-#include "vector_base.hpp"
+#include "../io/pool.hpp"
 
 namespace grnxx {
 namespace db {
 
-const uint64_t VECTOR_PAGE_SIZE_MIN     = uint64_t(1) << 0;
-const uint64_t VECTOR_PAGE_SIZE_MAX     = uint64_t(1) << 20;
-const uint64_t VECTOR_PAGE_SIZE_DEFAULT = uint64_t(1) << 16;
+const uint64_t VECTOR_MIN_PAGE_SIZE     = uint64_t(1) << 0;
+const uint64_t VECTOR_MAX_PAGE_SIZE     = uint64_t(1) << 20;
+const uint64_t VECTOR_DEFAULT_PAGE_SIZE = uint64_t(1) << 16;
 
-const uint64_t VECTOR_TABLE_SIZE_MIN     = uint64_t(1) << 10;
-const uint64_t VECTOR_TABLE_SIZE_MAX     = uint64_t(1) << 20;
-const uint64_t VECTOR_TABLE_SIZE_DEFAULT = uint64_t(1) << 12;
+const uint64_t VECTOR_MIN_TABLE_SIZE     = uint64_t(1) << 10;
+const uint64_t VECTOR_MAX_TABLE_SIZE     = uint64_t(1) << 20;
+const uint64_t VECTOR_DEFAULT_TABLE_SIZE = uint64_t(1) << 12;
 
-const uint64_t VECTOR_SECONDARY_TABLE_SIZE_MIN     = uint64_t(1) << 10;
-const uint64_t VECTOR_SECONDARY_TABLE_SIZE_MAX     = uint64_t(1) << 20;
-const uint64_t VECTOR_SECONDARY_TABLE_SIZE_DEFAULT = uint64_t(1) << 12;
+const uint64_t VECTOR_MIN_SECONDARY_TABLE_SIZE     = uint64_t(1) << 10;
+const uint64_t VECTOR_MAX_SECONDARY_TABLE_SIZE     = uint64_t(1) << 20;
+const uint64_t VECTOR_DEFAULT_SECONDARY_TABLE_SIZE = uint64_t(1) << 12;
 
-template <typename T,
-          uint64_t PAGE_SIZE = VECTOR_PAGE_SIZE_DEFAULT,
-          uint64_t TABLE_SIZE = VECTOR_TABLE_SIZE_DEFAULT,
-          uint64_t SECONDARY_TABLE_SIZE = VECTOR_SECONDARY_TABLE_SIZE_DEFAULT>
-class Vector {
+extern class VectorCreate {} VECTOR_CREATE;
+extern class VectorOpen {} VECTOR_OPEN;
+
+class VectorHeader {
  public:
-  typedef T Value;
+  VectorHeader(const void *default_value,
+               uint64_t value_size,
+               uint64_t page_size,
+               uint64_t table_size,
+               uint64_t secondary_table_size);
 
-  static_assert(PAGE_SIZE >= VECTOR_PAGE_SIZE_MIN, "too small PAGE_SIZE");
-  static_assert(PAGE_SIZE <= VECTOR_PAGE_SIZE_MAX, "too large PAGE_SIZE");
+  uint64_t value_size() const {
+    return value_size_;
+  }
+  uint64_t page_size() const {
+    return page_size_;
+  }
+  uint64_t table_size() const {
+    return table_size_;
+  }
+  uint64_t secondary_table_size() const {
+    return secondary_table_size_;
+  }
+  bool has_default_value() const {
+    return has_default_value_ != 0;
+  }
+  uint32_t first_table_block_id() const {
+    return first_table_block_id_;
+  }
+  uint32_t secondary_table_block_id() const {
+    return secondary_table_block_id_;
+  }
 
-  static_assert(TABLE_SIZE >= VECTOR_TABLE_SIZE_MIN, "too small TABLE_SIZE");
-  static_assert(TABLE_SIZE <= VECTOR_TABLE_SIZE_MAX, "too large TABLE_SIZE");
+  void set_first_table_block_id(uint32_t value) {
+    first_table_block_id_ = value;
+  }
+  void set_secondary_table_block_id(uint32_t value) {
+    secondary_table_block_id_ = value;
+  }
 
-  static_assert(SECONDARY_TABLE_SIZE >= VECTOR_SECONDARY_TABLE_SIZE_MIN,
-                "too small SECONDARY_TABLE_SIZE");
-  static_assert(SECONDARY_TABLE_SIZE <= VECTOR_SECONDARY_TABLE_SIZE_MAX,
-                "too large SECONDARY_TABLE_SIZE");
+  Mutex *mutable_inter_process_mutex() {
+    return &inter_process_mutex_;
+  }
 
+  StringBuilder &write_to(StringBuilder &builder) const;
+
+ private:
+  uint64_t value_size_;
+  uint64_t page_size_;
+  uint64_t table_size_;
+  uint64_t secondary_table_size_;
+  uint32_t has_default_value_;
+  uint32_t first_table_block_id_;
+  uint32_t secondary_table_block_id_;
+  Mutex inter_process_mutex_;
+};
+
+inline StringBuilder &operator<<(StringBuilder &builder,
+                                 const VectorHeader &header) {
+  return header.write_to(builder);
+}
+
+class VectorImpl {
+  typedef void (*FillPage)(void *page_address, const void *value);
+
+ public:
+  static std::unique_ptr<VectorImpl> create(io::Pool pool,
+                                            const void *default_value,
+                                            uint64_t value_size,
+                                            uint64_t page_size,
+                                            uint64_t table_size,
+                                            uint64_t secondary_table_size,
+                                            FillPage fill_page);
+  static std::unique_ptr<VectorImpl> open(io::Pool pool,
+                                          uint32_t block_id,
+                                          uint64_t value_size,
+                                          uint64_t page_size,
+                                          uint64_t table_size,
+                                          uint64_t secondary_table_size,
+                                          FillPage fill_page);
+
+  template <uint64_t PAGE_SIZE,
+            uint64_t TABLE_SIZE,
+            uint64_t SECONDARY_TABLE_SIZE>
+  void *get_page_address(uint64_t page_id) {
+    if ((page_id < TABLE_SIZE) && first_table_cache_[page_id]) {
+      return first_table_cache_[page_id];
+    }
+    if ((page_id < (TABLE_SIZE * SECONDARY_TABLE_SIZE)) && tables_cache_) {
+      const uint64_t table_id = page_id / TABLE_SIZE;
+      const std::unique_ptr<void *[]> &table_cache = tables_cache_[table_id];
+      if (table_cache) {
+        const uint64_t local_page_id = page_id % TABLE_SIZE;
+        if (table_cache[local_page_id]) {
+          return table_cache[local_page_id];
+        }
+      }
+    }
+    return get_page_address_on_failure(page_id);
+  }
+
+  uint32_t block_id() const {
+    return block_info_->id();
+  }
+
+  StringBuilder &write_to(StringBuilder &builder) const;
+
+  static void unlink(io::Pool pool,
+                     uint32_t block_id,
+                     uint64_t value_size,
+                     uint64_t page_size,
+                     uint64_t table_size,
+                     uint64_t secondary_table_size);
+
+ private:
+  io::Pool pool_;
+  FillPage fill_page_;
+  const io::BlockInfo *block_info_;
+  VectorHeader *header_;
+  void *default_value_;
+  uint8_t table_size_bits_;
+  uint64_t table_size_mask_;
+  uint64_t max_page_id_;
+  uint32_t *first_table_;
+  uint32_t *secondary_table_;
+  std::unique_ptr<uint32_t *[]> secondary_table_cache_;
+  std::unique_ptr<void *[]> first_table_cache_;
+  std::unique_ptr<std::unique_ptr<void *[]>[]> tables_cache_;
+  Mutex inter_thread_mutex_;
+
+  VectorImpl();
+
+  void create_vector(io::Pool pool,
+                     const void *default_value,
+                     uint64_t value_size,
+                     uint64_t page_size,
+                     uint64_t table_size,
+                     uint64_t secondary_table_size,
+                     FillPage fill_page);
+  void open_vector(io::Pool pool,
+                   uint32_t block_id,
+                   uint64_t value_size,
+                   uint64_t page_size,
+                   uint64_t table_size,
+                   uint64_t secondary_table_size,
+                   FillPage fill_page);
+  void restore_from_header();
+
+  void *get_page_address_on_failure(uint64_t page_id);
+
+  void initialize_secondary_table();
+  void initialize_table(uint32_t *table_block_id);
+  void initialize_page(uint32_t *page_block_id);
+  void initialize_secondary_table_cache();
+  void initialize_table_cache(std::unique_ptr<void *[]> *table_cache);
+  void initialize_tables_cache();
+
+  Mutex *mutable_inter_process_mutex() {
+    return header_->mutable_inter_process_mutex();
+  }
+  Mutex *mutable_inter_thread_mutex() {
+    return &inter_thread_mutex_;
+  }
+};
+
+inline StringBuilder &operator<<(StringBuilder &builder,
+                                 const VectorImpl &vector) {
+  return vector.write_to(builder);
+}
+
+template <typename T,
+          uint64_t PAGE_SIZE = VECTOR_DEFAULT_PAGE_SIZE,
+          uint64_t TABLE_SIZE = VECTOR_DEFAULT_TABLE_SIZE,
+          uint64_t SECONDARY_TABLE_SIZE = VECTOR_DEFAULT_SECONDARY_TABLE_SIZE>
+class Vector {
+  static_assert(PAGE_SIZE >= VECTOR_MIN_PAGE_SIZE, "too small PAGE_SIZE");
+  static_assert(PAGE_SIZE <= VECTOR_MAX_PAGE_SIZE, "too large PAGE_SIZE");
   static_assert((PAGE_SIZE & (PAGE_SIZE - 1)) == 0,
                 "PAGE_SIZE must be a power of two");
+
+  static_assert(TABLE_SIZE >= VECTOR_MIN_TABLE_SIZE, "too small TABLE_SIZE");
+  static_assert(TABLE_SIZE <= VECTOR_MAX_TABLE_SIZE, "too large TABLE_SIZE");
   static_assert((TABLE_SIZE & (TABLE_SIZE - 1)) == 0,
                 "TABLE_SIZE must be a power of two");
+
+  static_assert(SECONDARY_TABLE_SIZE >= VECTOR_MIN_SECONDARY_TABLE_SIZE,
+                "too small SECONDARY_TABLE_SIZE");
+  static_assert(SECONDARY_TABLE_SIZE <= VECTOR_MAX_SECONDARY_TABLE_SIZE,
+                "too large SECONDARY_TABLE_SIZE");
   static_assert((SECONDARY_TABLE_SIZE & (SECONDARY_TABLE_SIZE - 1)) == 0,
                 "SECONDARY_TABLE_SIZE must be a power of two");
 
-  Vector() : base_() {}
-  ~Vector() {}
-
-  Vector(Vector &&vector) : base_(std::move(vector.base_)) {}
-  Vector &operator=(Vector &&vector) {
-    base_ = std::move(vector.base_);
-    return *this;
-  }
+ public:
+  typedef T Value;
 
-  bool is_open() const {
-    return base_.is_open();
-  }
+  Vector() = default;
+  Vector(const VectorCreate &, io::Pool pool)
+    : impl_(VectorImpl::create(pool, nullptr, sizeof(Value), PAGE_SIZE,
+                               TABLE_SIZE, SECONDARY_TABLE_SIZE, fill_page)) {}
+  Vector(const VectorCreate &, io::Pool pool, const Value &default_value)
+    : impl_(VectorImpl::create(pool, &default_value, sizeof(Value), PAGE_SIZE,
+                               TABLE_SIZE, SECONDARY_TABLE_SIZE, fill_page)) {}
+  Vector(const VectorOpen &, io::Pool pool, uint32_t block_id)
+    : impl_(VectorImpl::open(pool, block_id, sizeof(Value), PAGE_SIZE,
+                             TABLE_SIZE, SECONDARY_TABLE_SIZE, fill_page)) {}
 
-  void create(io::Pool *pool) {
-    base_.create(pool, sizeof(Value),
-                 PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE,
-                 nullptr, fill_page);
+  void create(io::Pool pool) {
+    *this = Vector(VECTOR_CREATE, pool);
   }
-  void create(io::Pool *pool, const Value &default_value) {
-    base_.create(pool, sizeof(Value),
-                 PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE,
-                 &default_value, fill_page);
+  void create(io::Pool pool, const Value &default_value) {
+    *this = Vector(VECTOR_CREATE, pool, default_value);
   }
-  void open(io::Pool *pool, uint32_t block_id) {
-    base_.open(pool, block_id, sizeof(Value),
-               PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE, fill_page);
+  void open(io::Pool pool, uint32_t block_id) {
+    *this = Vector(VECTOR_OPEN, pool, block_id);
   }
   void close() {
-    if (!is_open()) {
-      GRNXX_ERROR() << "failed to close vector";
-      GRNXX_THROW();
-    }
-    base_ = VectorBase();
+    *this = Vector();
   }
 
-  Value *get_value_address(uint64_t id) {
-    return base_.get_value_address<Value, PAGE_SIZE, TABLE_SIZE,
-                                   SECONDARY_TABLE_SIZE>(id);
-  }
-  Value &get_value(uint64_t id) {
-    return *get_value_address(id);
+  explicit operator bool() const {
+    return static_cast<bool>(impl_);
   }
+
   Value &operator[](uint64_t id) {
-    return get_value(id);
+    void * const page_address =
+       impl_->get_page_address<PAGE_SIZE, TABLE_SIZE,
+                               SECONDARY_TABLE_SIZE>(id / PAGE_SIZE);
+    return static_cast<T *>(page_address)[id % PAGE_SIZE];
   }
 
   uint32_t block_id() const {
-    return base_.block_id();
+    return impl_->block_id();
   }
 
-  void swap(Vector &vector) {
-    base_.swap(vector.base_);
+  void swap(Vector &rhs) {
+    impl_.swap(rhs.impl_);
   }
 
   StringBuilder &write_to(StringBuilder &builder) const {
-    return base_.write_to(builder);
+    return impl_ ? impl_->write_to(builder) : (builder << "n/a");
   }
 
-  static uint64_t value_size() {
+  static constexpr uint64_t value_size() {
     return sizeof(Value);
   }
-  static uint64_t page_size() {
+  static constexpr uint64_t page_size() {
     return PAGE_SIZE;
   }
-  static uint64_t table_size() {
+  static constexpr uint64_t table_size() {
     return TABLE_SIZE;
   }
-  static uint64_t secondary_table_size() {
+  static constexpr uint64_t secondary_table_size() {
     return SECONDARY_TABLE_SIZE;
   }
-  static uint64_t id_max() {
+  static constexpr uint64_t max_id() {
     return (PAGE_SIZE * TABLE_SIZE * SECONDARY_TABLE_SIZE) - 1;
   }
 
-  static void unlink(io::Pool *pool, uint32_t block_id) {
-    VectorBase::unlink(pool, block_id, sizeof(Value),
+  static void unlink(io::Pool pool, uint32_t block_id) {
+    VectorImpl::unlink(pool, block_id, sizeof(Value),
                        PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE);
   }
 
  private:
-  VectorBase base_;
+  std::shared_ptr<VectorImpl> impl_;
 
   static void fill_page(void *page_address, const void *value) {
     Value *values = static_cast<Value *>(page_address);
@@ -151,14 +309,17 @@ class Vector {
   }
 };
 
-template <typename T>
-inline void swap(Vector<T> &lhs, Vector<T> &rhs) {
+template <typename T, uint64_t PAGE_SIZE, uint64_t TABLE_SIZE,
+                      uint64_t SECONDARY_TABLE_SIZE>
+inline void swap(Vector<T, PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE> &lhs,
+                 Vector<T, PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE> &rhs) {
   lhs.swap(rhs);
 }
 
-template <typename T>
+template <typename T, uint64_t PAGE_SIZE, uint64_t TABLE_SIZE,
+                      uint64_t SECONDARY_TABLE_SIZE>
 inline StringBuilder &operator<<(StringBuilder &builder,
-                                 const Vector<T> &vector) {
+    const Vector<T, PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE> &vector) {
   return vector.write_to(builder);
 }
 

  Deleted: lib/db/vector_base.cpp (+0 -512) 100644
===================================================================
--- lib/db/vector_base.cpp    2012-12-06 20:37:22 +0900 (bf47347)
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
-  Copyright (C) 2012  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 "vector_base.hpp"
-
-#include <vector>
-
-#include "../lock.hpp"
-#include "../logger.hpp"
-
-namespace grnxx {
-namespace db {
-
-void VectorHeader::initialize(uint64_t value_size,
-                              uint64_t page_size,
-                              uint64_t table_size,
-                              uint64_t secondary_table_size,
-                              const void *default_value) {
-  std::memset(this, 0, sizeof(*this));
-
-  value_size_ = value_size;
-  page_size_ = page_size;
-  table_size_ = table_size;
-  secondary_table_size_ = secondary_table_size;
-  has_default_value_ = default_value ? 1 : 0;
-
-  first_table_block_id_ = io::BLOCK_INVALID_ID;
-  secondary_table_block_id_ = io::BLOCK_INVALID_ID;
-
-  mutex_.unlock();
-}
-
-VectorBase::VectorBase()
-  : pool_(),
-    block_info_(nullptr),
-    header_(nullptr),
-    default_value_(nullptr),
-    fill_page_(nullptr),
-    table_size_bits_(0),
-    table_size_mask_(0),
-    page_id_max_(0),
-    first_table_(nullptr),
-    secondary_table_(nullptr),
-    secondary_table_cache_(),
-    first_table_cache_(),
-    tables_cache_(),
-    mutex_(MUTEX_UNLOCKED) {}
-
-VectorBase::~VectorBase() {}
-
-VectorBase::VectorBase(VectorBase &&rhs)
-  : pool_(std::move(rhs.pool_)),
-    block_info_(std::move(rhs.block_info_)),
-    header_(std::move(rhs.header_)),
-    default_value_(std::move(rhs.default_value_)),
-    fill_page_(std::move(rhs.fill_page_)),
-    table_size_bits_(std::move(rhs.table_size_bits_)),
-    table_size_mask_(std::move(rhs.table_size_mask_)),
-    page_id_max_(std::move(rhs.page_id_max_)),
-    first_table_(std::move(rhs.first_table_)),
-    secondary_table_(std::move(rhs.secondary_table_)),
-    secondary_table_cache_(std::move(rhs.secondary_table_cache_)),
-    first_table_cache_(std::move(rhs.first_table_cache_)),
-    tables_cache_(std::move(rhs.tables_cache_)),
-    mutex_(std::move(rhs.mutex_)) {}
-
-VectorBase &VectorBase::operator=(VectorBase &&rhs) {
-  pool_ = std::move(rhs.pool_);
-  block_info_ = std::move(rhs.block_info_);
-  header_ = std::move(rhs.header_);
-  default_value_ = std::move(rhs.default_value_);
-  fill_page_ = std::move(rhs.fill_page_);
-  table_size_bits_ = std::move(rhs.table_size_bits_);
-  table_size_mask_ = std::move(rhs.table_size_mask_);
-  page_id_max_ = std::move(rhs.page_id_max_);
-  first_table_ = std::move(rhs.first_table_);
-  secondary_table_ = std::move(rhs.secondary_table_);
-  secondary_table_cache_ = std::move(rhs.secondary_table_cache_);
-  first_table_cache_ = std::move(rhs.first_table_cache_);
-  tables_cache_ = std::move(rhs.tables_cache_);
-  mutex_ = std::move(rhs.mutex_);
-  return *this;
-}
-
-void VectorBase::create(io::Pool *pool,
-                        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 (!pool) {
-    GRNXX_ERROR() << "invalid argument: pool = " << pool;
-    GRNXX_THROW();
-  } else if (!*pool) {
-    GRNXX_ERROR() << "invalid_argument: pool = " << *pool;
-    GRNXX_THROW();
-  }
-
-  VectorBase new_vector;
-  new_vector.create_vector(pool, value_size, page_size, table_size,
-                           secondary_table_size, default_value, fill_page);
-  *this = std::move(new_vector);
-}
-
-void VectorBase::open(io::Pool *pool,
-                      uint32_t block_id,
-                      uint64_t value_size,
-                      uint64_t page_size,
-                      uint64_t table_size,
-                      uint64_t secondary_table_size,
-                      FillPage fill_page) {
-  if (!pool) {
-    GRNXX_ERROR() << "invalid argument: pool = " << pool;
-    GRNXX_THROW();
-  } else if (!*pool) {
-    GRNXX_ERROR() << "invalid_argument: pool = " << *pool;
-    GRNXX_THROW();
-  }
-
-  VectorBase new_vector;
-  new_vector.open_vector(pool, block_id, value_size, page_size, table_size,
-                         secondary_table_size, fill_page);
-  *this = std::move(new_vector);
-}
-
-void VectorBase::swap(VectorBase &rhs) {
-  using std::swap;
-  swap(pool_, rhs.pool_);
-  swap(block_info_, rhs.block_info_);
-  swap(header_, rhs.header_);
-  swap(default_value_, rhs.default_value_);
-  swap(fill_page_, rhs.fill_page_);
-  swap(table_size_bits_, rhs.table_size_bits_);
-  swap(table_size_mask_, rhs.table_size_mask_);
-  swap(page_id_max_, rhs.page_id_max_);
-  swap(first_table_, rhs.first_table_);
-  swap(secondary_table_, rhs.secondary_table_);
-  swap(secondary_table_cache_, rhs.secondary_table_cache_);
-  swap(first_table_cache_, rhs.first_table_cache_);
-  swap(tables_cache_, rhs.tables_cache_);
-  swap(mutex_, rhs.mutex_);
-}
-
-void VectorBase::unlink(io::Pool *pool,
-                        uint32_t block_id,
-                        uint64_t value_size,
-                        uint64_t page_size,
-                        uint64_t table_size,
-                        uint64_t secondary_table_size) try {
-  std::vector<uint32_t> block_ids;
-
-  {
-    VectorBase vector;
-    vector.open(pool, block_id, value_size,
-                page_size, table_size, secondary_table_size, nullptr);
-    const VectorHeader * const header = vector.header_;
-
-    block_ids.push_back(block_id);
-
-    block_ids.push_back(header->first_table_block_id());
-    for (uint64_t i = 0; i < header->table_size(); ++i) {
-      if (vector.first_table_[i] != io::BLOCK_INVALID_ID) {
-        block_ids.push_back(vector.first_table_[i]);
-      }
-    }
-
-    if (header->secondary_table_block_id() != io::BLOCK_INVALID_ID) {
-      block_ids.push_back(header->secondary_table_block_id());
-      uint32_t * const secondary_table = static_cast<uint32_t *>(
-          pool->get_block_address(header->secondary_table_block_id()));
-      for (uint64_t i = 0; i < header->secondary_table_size(); ++i) {
-        if (secondary_table[i] != io::BLOCK_INVALID_ID) {
-          block_ids.push_back(secondary_table[i]);
-          uint32_t * const table = static_cast<uint32_t *>(
-              pool->get_block_address(secondary_table[i]));
-          for (uint64_t j = 0; j < header->table_size(); ++j) {
-            if (table[j] != io::BLOCK_INVALID_ID) {
-              block_ids.push_back(table[j]);
-            }
-          }
-        }
-      }
-    }
-  }
-
-  for (size_t i = 0; i < block_ids.size(); ++i) {
-    pool->free_block(block_ids[i]);
-  }
-} catch (const std::exception &exception) {
-  GRNXX_ERROR() << exception;
-  GRNXX_THROW();
-}
-
-void VectorBase::create_vector(io::Pool *pool,
-                               uint64_t value_size,
-                               uint64_t page_size,
-                               uint64_t table_size,
-                               uint64_t secondary_table_size,
-                               const void *default_value,
-                               FillPage fill_page) {
-  pool_ = *pool;
-
-  std::unique_ptr<void *[]> first_table_cache(
-        new (std::nothrow) void *[table_size]);
-  if (!first_table_cache) {
-    GRNXX_ERROR() << "new void *[" << table_size << "] failed";
-    GRNXX_THROW();
-  }
-
-  uint64_t header_block_size = sizeof(VectorHeader);
-  if (default_value) {
-    header_block_size += value_size;
-  }
-  block_info_ = pool_.create_block(header_block_size);
-
-  const io::BlockInfo *first_table_block_info;
-  try {
-    first_table_block_info = pool_.create_block(sizeof(uint32_t) * table_size);
-  } catch (...) {
-    pool_.free_block(*block_info_);
-    throw;
-  }
-
-  void * const block_address = pool_.get_block_address(*block_info_);
-  header_ = static_cast<VectorHeader *>(block_address);
-  header_->initialize(value_size, page_size, table_size,
-                      secondary_table_size, default_value);
-  restore_from_header();
-
-  if (default_value_) {
-    std::memcpy(default_value_, default_value,
-                static_cast<size_t>(value_size));
-    fill_page_ = fill_page;
-  }
-
-  header_->set_first_table_block_id(first_table_block_info->id());
-  first_table_ = static_cast<uint32_t *>(
-      pool_.get_block_address(*first_table_block_info));
-  first_table_cache_ = std::move(first_table_cache);
-  for (uint64_t i = 0; i < header_->table_size(); ++i) {
-    first_table_[i] = io::BLOCK_INVALID_ID;
-    first_table_cache_[i] = nullptr;
-  }
-}
-
-void VectorBase::open_vector(io::Pool *pool,
-                             uint32_t block_id,
-                             uint64_t value_size,
-                             uint64_t page_size,
-                             uint64_t table_size,
-                             uint64_t secondary_table_size,
-                             FillPage fill_page) {
-  pool_ = *pool;
-  block_info_ = pool_.get_block_info(block_id);
-  if (block_info_->size() < sizeof(VectorHeader)) {
-    GRNXX_ERROR() << "invalid argument: block_info = " << *block_info_
-                  << ", header_size = " << sizeof(VectorHeader);
-    GRNXX_THROW();
-  }
-
-  void * const block_address = pool_.get_block_address(*block_info_);
-  header_ = static_cast<VectorHeader *>(block_address);
-  restore_from_header();
-
-  if (default_value_) {
-    const uint64_t header_size = sizeof(VectorHeader) + value_size;
-    if (block_info_->size() < header_size) {
-      GRNXX_ERROR() << "invalid argument: block_info = " << *block_info_
-                    << ", header_size = " << header_size;
-      GRNXX_THROW();
-    }
-    fill_page_ = fill_page;
-  }
-
-  if (value_size != header_->value_size()) {
-    GRNXX_ERROR() << "invalid value size: actual = " << header_->value_size()
-                  << ", expected = " << value_size;
-    GRNXX_THROW();
-  }
-  if (page_size != header_->page_size()) {
-    GRNXX_ERROR() << "invalid page size: actual = " << header_->page_size()
-                  << ", expected = " << page_size;
-    GRNXX_THROW();
-  }
-  if (table_size != header_->table_size()) {
-    GRNXX_ERROR() << "invalid table size: actual = " << header_->table_size()
-                  << ", expected = " << table_size;
-    GRNXX_THROW();
-  }
-  if (secondary_table_size != header_->secondary_table_size()) {
-    GRNXX_ERROR() << "invalid secondary table size: actual = "
-                  << header_->secondary_table_size()
-                  << ", expected = " << secondary_table_size;
-    GRNXX_THROW();
-  }
-
-  first_table_ = static_cast<uint32_t *>(
-      pool_.get_block_address(header_->first_table_block_id()));
-
-  first_table_cache_.reset(new (std::nothrow) void *[header_->table_size()]);
-  if (!first_table_cache_) {
-    GRNXX_ERROR() << "new void *[" << header_->table_size() << "] failed";
-    GRNXX_THROW();
-  }
-  for (uint64_t i = 0; i < header_->table_size(); ++i) {
-    first_table_cache_[i] = nullptr;
-  }
-}
-
-void VectorBase::restore_from_header() {
-  if (header_->has_default_value()) {
-    default_value_ = header_ + 1;
-  }
-
-  table_size_bits_ = bit_scan_reverse(header_->table_size());
-  table_size_mask_ = header_->table_size() - 1;
-  page_id_max_ = header_->table_size() * header_->secondary_table_size() - 1;
-}
-
-void VectorBase::initialize_secondary_table() {
-  Lock lock(inter_process_mutex());
-  if (header_->secondary_table_block_id() == io::BLOCK_INVALID_ID) {
-    const auto block_info = pool_.create_block(
-        sizeof(uint32_t) * header_->secondary_table_size());
-    uint32_t * const body = static_cast<uint32_t *>(
-        pool_.get_block_address(*block_info));
-    for (uint64_t i = 0; i < header_->secondary_table_size(); ++i) {
-      body[i] = io::BLOCK_INVALID_ID;
-    }
-    header_->set_secondary_table_block_id(block_info->id());
-  }
-}
-
-void *VectorBase::get_page_address_on_failure(uint64_t page_id) {
-  if (page_id < header_->table_size()) {
-    if (!first_table_cache_[page_id]) {
-      if (first_table_[page_id] == io::BLOCK_INVALID_ID) {
-        initialize_page(&first_table_[page_id]);
-      }
-      first_table_cache_[page_id] =
-          pool_.get_block_address(first_table_[page_id]);
-    }
-    return first_table_cache_[page_id];
-  }
-
-  if (page_id <= page_id_max_) {
-    if (!tables_cache_) {
-      if (!secondary_table_cache_) {
-        if (!secondary_table_) {
-          if (header_->secondary_table_block_id() == io::BLOCK_INVALID_ID) {
-            initialize_secondary_table();
-          }
-          secondary_table_ = static_cast<uint32_t *>(
-              pool_.get_block_address(header_->secondary_table_block_id()));
-        }
-        initialize_secondary_table_cache();
-      }
-      initialize_tables_cache();
-    }
-
-    const uint64_t table_id = page_id >> table_size_bits_;
-    std::unique_ptr<void *[]> &table_cache = tables_cache_[table_id];
-    if (!table_cache) {
-      if (secondary_table_[table_id] == io::BLOCK_INVALID_ID) {
-        initialize_table(&secondary_table_[table_id]);
-      }
-      secondary_table_cache_[table_id] = static_cast<uint32_t *>(
-          pool_.get_block_address(secondary_table_[table_id]));
-      initialize_table_cache(&table_cache);
-    }
-
-    page_id &= table_size_mask_;
-    if (!table_cache[page_id]) {
-      uint32_t * const table = secondary_table_cache_[table_id];
-      if (table[page_id] == io::BLOCK_INVALID_ID) {
-        initialize_page(&table[page_id]);
-      }
-      table_cache[page_id] = pool_.get_block_address(table[page_id]);
-    }
-    return table_cache[page_id];
-  }
-
-  GRNXX_ERROR() << "invalid argument: page_id = " << page_id
-                << ": [0, " << page_id_max_ <<']';
-  GRNXX_THROW();
-}
-
-void VectorBase::initialize_table(uint32_t *table_block_id) {
-  Lock lock(inter_process_mutex());
-  if (*table_block_id == io::BLOCK_INVALID_ID) {
-    const auto block_info = pool_.create_block(
-        sizeof(uint32_t) * header_->table_size());
-    uint32_t * const body = static_cast<uint32_t *>(
-        pool_.get_block_address(*block_info));
-    for (uint64_t i = 0; i < header_->table_size(); ++i) {
-      body[i] = io::BLOCK_INVALID_ID;
-    }
-    *table_block_id = block_info->id();
-  }
-}
-
-void VectorBase::initialize_page(uint32_t *page_block_id) {
-  Lock lock(inter_process_mutex());
-  if (*page_block_id == io::BLOCK_INVALID_ID) {
-    const io::BlockInfo *block_info = pool_.create_block(
-        header_->value_size() * header_->page_size());
-    if (fill_page_) {
-      fill_page_(pool_.get_block_address(*block_info), default_value_);
-    }
-    *page_block_id = block_info->id();
-  }
-}
-
-void VectorBase::initialize_secondary_table_cache() {
-  Lock lock(inter_thread_mutex());
-  if (!secondary_table_cache_) {
-    std::unique_ptr<uint32_t *[]> tables(
-        new (std::nothrow) uint32_t *[header_->secondary_table_size()]);
-    if (!tables) {
-      GRNXX_ERROR() << "new grnxx::uint32_t *["
-                    << header_->secondary_table_size() << "] failed";
-      GRNXX_THROW();
-    }
-    for (uint64_t i = 0; i < header_->secondary_table_size(); ++i) {
-      tables[i] = nullptr;
-    }
-    secondary_table_cache_ = std::move(tables);
-  }
-}
-
-void VectorBase::initialize_table_cache(
-    std::unique_ptr<void *[]> *table_cache) {
-  Lock lock(inter_thread_mutex());
-  if (!*table_cache) {
-    std::unique_ptr<void *[]> cache(
-        new (std::nothrow) void *[header_->table_size()]);
-    if (!cache) {
-      GRNXX_ERROR() << "new void *[" << header_->table_size() << "] failed";
-      GRNXX_THROW();
-    }
-    for (uint64_t i = 0; i < header_->table_size(); ++i) {
-      cache[i] = nullptr;
-    }
-    *table_cache = std::move(cache);
-  }
-}
-
-void VectorBase::initialize_tables_cache() {
-  Lock lock(inter_thread_mutex());
-  if (!tables_cache_) {
-    std::unique_ptr<std::unique_ptr<void *[]>[]> cache(new (std::nothrow)
-        std::unique_ptr<void *[]>[header_->secondary_table_size()]);
-    for (uint64_t i = 0; i < header_->secondary_table_size(); ++i) {
-      cache[i] = nullptr;
-    }
-    tables_cache_ = std::move(cache);
-  }
-}
-
-StringBuilder &VectorHeader::write_to(StringBuilder &builder) const {
-  if (!builder) {
-    return builder;
-  }
-
-  return builder << "{ value_size = " << value_size_
-                 << ", page_size = " << page_size_
-                 << ", table_size = " << table_size_
-                 << ", secondary_table_size = " << secondary_table_size_
-                 << ", has_default_value = " << has_default_value_
-                 << ", first_table_block_id = " << first_table_block_id_
-                 << ", secondary_table_block_id = " << secondary_table_block_id_
-                 << ", mutex = " << mutex_ << " }";
-}
-
-StringBuilder &VectorBase::write_to(StringBuilder &builder) const {
-  if (!builder) {
-    return builder;
-  }
-
-  if (!is_open()) {
-    return builder << "n/a";
-  }
-
-  builder << "{ pool = " << pool_.path()
-          << ", block_info = " << *block_info_
-          << ", header = ";
-  if (header_) {
-    builder << *header_;
-  } else {
-    builder << "n/a";
-  }
-  return builder << ", page_id_max = " << page_id_max_
-                 << ", mutex = " << mutex_ << " }";
-}
-
-}  // namespace db
-}  // namespace grnxx

  Deleted: lib/db/vector_base.hpp (+0 -247) 100644
===================================================================
--- lib/db/vector_base.hpp    2012-12-06 20:37:22 +0900 (2cbac41)
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
-  Copyright (C) 2012  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_DB_VECTOR_BASE_HPP
-#define GRNXX_DB_VECTOR_BASE_HPP
-
-#include "../exception.hpp"
-#include "../logger.hpp"
-#include "../io/pool.hpp"
-
-namespace grnxx {
-namespace db {
-
-class VectorHeader {
- public:
-  void initialize(uint64_t value_size,
-                  uint64_t page_size,
-                  uint64_t table_size,
-                  uint64_t secondary_table_size,
-                  const void *default_value);
-
-  uint64_t value_size() const {
-    return value_size_;
-  }
-  uint64_t page_size() const {
-    return page_size_;
-  }
-  uint64_t table_size() const {
-    return table_size_;
-  }
-  uint64_t secondary_table_size() const {
-    return secondary_table_size_;
-  }
-  bool has_default_value() const {
-    return has_default_value_ != 0;
-  }
-  uint32_t first_table_block_id() const {
-    return first_table_block_id_;
-  }
-  uint32_t secondary_table_block_id() const {
-    return secondary_table_block_id_;
-  }
-
-  void set_first_table_block_id(uint32_t value) {
-    first_table_block_id_ = value;
-  }
-  void set_secondary_table_block_id(uint32_t value) {
-    secondary_table_block_id_ = value;
-  }
-
-  Mutex *mutex() {
-    return &mutex_;
-  }
-
-  StringBuilder &write_to(StringBuilder &builder) const;
-
- private:
-  uint64_t value_size_;
-  uint64_t page_size_;
-  uint64_t table_size_;
-  uint64_t secondary_table_size_;
-  uint8_t has_default_value_;
-  uint32_t first_table_block_id_;
-  uint32_t secondary_table_block_id_;
-  Mutex mutex_;
-
-  VectorHeader();
-  ~VectorHeader();
-
-  VectorHeader(const VectorHeader &);
-  VectorHeader &operator=(const VectorHeader &);
-};
-
-class VectorBase {
- public:
-  typedef void (*FillPage)(void *page_address, const void *value);
-
-  VectorBase();
-  ~VectorBase();
-
-  VectorBase(VectorBase &&rhs);
-  VectorBase &operator=(VectorBase &&rhs);
-
-  bool is_open() const {
-    return static_cast<bool>(pool_);
-  }
-
-  void create(io::Pool *pool,
-              uint64_t value_size,
-              uint64_t page_size,
-              uint64_t table_size,
-              uint64_t secondary_table_size,
-              const void *default_value,
-              FillPage fill_page);
-
-  void open(io::Pool *pool,
-            uint32_t block_id,
-            uint64_t value_size,
-            uint64_t page_size,
-            uint64_t table_size,
-            uint64_t secondary_table_size,
-            FillPage fill_page);
-
-  template <typename T,
-            uint64_t PAGE_SIZE,
-            uint64_t TABLE_SIZE,
-            uint64_t SECONDARY_TABLE_SIZE>
-  T *get_value_address(uint64_t id) {
-    void * const page_address =
-       get_page_address<PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE>(
-           id / PAGE_SIZE);
-    return static_cast<T *>(page_address) + (id % PAGE_SIZE);
-  }
-
-  template <uint64_t PAGE_SIZE,
-            uint64_t TABLE_SIZE,
-            uint64_t SECONDARY_TABLE_SIZE>
-  void *get_page_address(uint64_t page_id) {
-    if ((page_id < TABLE_SIZE) && first_table_cache_[page_id]) {
-      return first_table_cache_[page_id];
-    }
-    if ((page_id < (TABLE_SIZE * SECONDARY_TABLE_SIZE)) && tables_cache_) {
-      const uint64_t table_id = page_id / TABLE_SIZE;
-      const std::unique_ptr<void *[]> &table_cache = tables_cache_[table_id];
-      if (table_cache) {
-        const uint64_t local_page_id = page_id % TABLE_SIZE;
-        if (table_cache[local_page_id]) {
-          return table_cache[local_page_id];
-        }
-      }
-    }
-    return get_page_address_on_failure(page_id);
-  }
-
-  uint32_t block_id() const {
-    return is_open() ? block_info_->id() : io::BLOCK_INVALID_ID;
-  }
-  uint64_t value_size() const {
-    return is_open() ? header_->value_size() : 0;
-  }
-  uint64_t page_size() const {
-    return is_open() ? header_->page_size() : 0;
-  }
-  uint64_t table_size() const {
-    return is_open() ? header_->table_size() : 0;
-  }
-  uint64_t secondary_table_size() const {
-    return is_open() ? header_->secondary_table_size() : 0;
-  }
-  uint64_t id_max() const {
-    return (page_size() * table_size() * secondary_table_size()) - 1;
-  }
-
-  void swap(VectorBase &rhs);
-
-  StringBuilder &write_to(StringBuilder &builder) const;
-
-  static void unlink(io::Pool *pool,
-                     uint32_t block_id,
-                     uint64_t value_size,
-                     uint64_t page_size,
-                     uint64_t table_size,
-                     uint64_t secondary_table_size);
-
- private:
-  io::Pool pool_;
-  const io::BlockInfo *block_info_;
-  VectorHeader *header_;
-  void *default_value_;
-  FillPage fill_page_;
-  uint8_t table_size_bits_;
-  uint64_t table_size_mask_;
-  uint64_t page_id_max_;
-  uint32_t *first_table_;
-  uint32_t *secondary_table_;
-  std::unique_ptr<uint32_t *[]> secondary_table_cache_;
-  std::unique_ptr<void *[]> first_table_cache_;
-  std::unique_ptr<std::unique_ptr<void *[]>[]> tables_cache_;
-  Mutex mutex_;
-
-  void create_vector(io::Pool *pool,
-                     uint64_t value_size,
-                     uint64_t page_size,
-                     uint64_t table_size,
-                     uint64_t secondary_table_size,
-                     const void *default_value,
-                     FillPage fill_page);
-  void open_vector(io::Pool *pool,
-                   uint32_t block_id,
-                   uint64_t value_size,
-                   uint64_t page_size,
-                   uint64_t table_size,
-                   uint64_t secondary_table_size,
-                   FillPage fill_page);
-
-  void restore_from_header();
-  uint64_t header_size() const;
-
-  void *get_page_address_on_failure(uint64_t page_id);
-
-  void initialize_secondary_table();
-  void initialize_table(uint32_t *table_block_id);
-  void initialize_page(uint32_t *page_block_id);
-
-  void initialize_secondary_table_cache();
-  void initialize_table_cache(
-      std::unique_ptr<void *[]> *table_cache);
-  void initialize_tables_cache();
-
-  Mutex *inter_thread_mutex() {
-    return &mutex_;
-  }
-  Mutex *inter_process_mutex() {
-    return header_->mutex();
-  }
-
-  VectorBase(const VectorBase &);
-  VectorBase &operator=(const VectorBase &);
-};
-
-inline StringBuilder &operator<<(StringBuilder &builder,
-                                 const VectorHeader &header) {
-  return header.write_to(builder);
-}
-inline StringBuilder &operator<<(StringBuilder &builder,
-                                 const VectorBase &vector) {
-  return vector.write_to(builder);
-}
-
-}  // namespace db
-}  // namespace grnxx
-
-#endif  // GRNXX_DB_VECTOR_BASE_HPP

  Modified: test/test_db_vector.cpp (+26 -30)
===================================================================
--- test/test_db_vector.cpp    2012-12-06 20:37:22 +0900 (b9945d9)
+++ test/test_db_vector.cpp    2012-12-06 21:29:51 +0900 (9e845b2)
@@ -34,14 +34,14 @@ void test_basics() {
 
   grnxx::io::Pool pool(grnxx::io::POOL_CREATE, "temp.grn");
 
-  grnxx::db::Vector<std::uint32_t> vector;
-  vector.create(&pool);
+  grnxx::db::Vector<std::uint32_t> vector(grnxx::db::VECTOR_CREATE, pool);
 
+  assert(vector.block_id() == 0);
   assert(vector.value_size() == sizeof(std::uint32_t));
-  assert(vector.page_size() == grnxx::db::VECTOR_PAGE_SIZE_DEFAULT);
-  assert(vector.table_size() == grnxx::db::VECTOR_TABLE_SIZE_DEFAULT);
+  assert(vector.page_size() == grnxx::db::VECTOR_DEFAULT_PAGE_SIZE);
+  assert(vector.table_size() == grnxx::db::VECTOR_DEFAULT_TABLE_SIZE);
   assert(vector.secondary_table_size() ==
-         grnxx::db::VECTOR_SECONDARY_TABLE_SIZE_DEFAULT);
+         grnxx::db::VECTOR_DEFAULT_SECONDARY_TABLE_SIZE);
 
   GRNXX_NOTICE() << "vector = " << vector;
 
@@ -57,14 +57,14 @@ void test_basics() {
   vector[1000000] = 100;
   vector[1000000000] = 1000;
   vector[1000000000000ULL] = 10000;
-  vector[vector.id_max()] = 100000;
+  vector[vector.max_id()] = 100000;
 
   assert(vector[0] == 1);
   assert(vector[1000] == 10);
   assert(vector[1000000] == 100);
   assert(vector[1000000000] == 1000);
   assert(vector[1000000000000ULL] == 10000);
-  assert(vector[vector.id_max()] == 100000);
+  assert(vector[vector.max_id()] == 100000);
 
   const std::uint32_t block_id = vector.block_id();
 
@@ -73,14 +73,14 @@ void test_basics() {
 
   pool.open(grnxx::io::POOL_OPEN, "temp.grn");
 
-  vector.open(&pool, block_id);
+  vector.open(pool, block_id);
 
   assert(vector[0] == 1);
   assert(vector[1000] == 10);
   assert(vector[1000000] == 100);
   assert(vector[1000000000] == 1000);
   assert(vector[1000000000000ULL] == 10000);
-  assert(vector[vector.id_max()] == 100000);
+  assert(vector[vector.max_id()] == 100000);
 
   assert(grnxx::atomic_fetch_and_add(1, &vector[0]) == 1);
   assert(vector[0] == 2);
@@ -88,14 +88,14 @@ void test_basics() {
   assert(grnxx::atomic_fetch_and_add(10, &vector[0]) == 2);
   assert(vector[0] == 12);
 
-  vector.create(&pool, 56789);
+  vector.create(pool, 56789);
 
   assert(vector[0] == 56789);
   assert(vector[1000] == 56789);
   assert(vector[1000000] == 56789);
   assert(vector[1000000000] == 56789);
   assert(vector[1000000000000ULL] == 56789);
-  assert(vector[vector.id_max()] == 56789);
+  assert(vector[vector.max_id()] == 56789);
 
   assert(grnxx::atomic_compare_and_swap(
       std::uint32_t(56789), std::uint32_t(98765), &vector[0]));
@@ -107,8 +107,9 @@ void test_basics() {
 
   vector.close();
 
-  grnxx::db::Vector<float> float_vector;
-  float_vector.create(&pool);
+  grnxx::db::Vector<std::uint32_t>::unlink(pool, 0);
+
+  grnxx::db::Vector<float> float_vector(grnxx::db::VECTOR_CREATE, pool);
 
   float_vector[0] = 1.0F;
   assert(float_vector[0] == 1.0F);
@@ -117,8 +118,7 @@ void test_basics() {
 
   float_vector.close();
 
-  grnxx::db::Vector<double> double_vector;
-  double_vector.create(&pool);
+  grnxx::db::Vector<double> double_vector(grnxx::db::VECTOR_CREATE, pool);
 
   double_vector[0] = 1.0;
   assert(double_vector[0] == 1.0);
@@ -127,8 +127,7 @@ void test_basics() {
 
   double_vector.close();
 
-  grnxx::db::Vector<Point> point_vector;
-  point_vector.create(&pool);
+  grnxx::db::Vector<Point> point_vector(grnxx::db::VECTOR_CREATE, pool);
 
   point_vector[0].x = 123;
   point_vector[0].y = 456;
@@ -141,8 +140,8 @@ void test_basics() {
   assert(point_vector[1 << 30].y == 654);
 
   point_vector.close();
-  pool.close();
 
+  pool.close();
   grnxx::io::Pool::unlink_if_exists("temp.grn");
 }
 
@@ -152,8 +151,7 @@ void test_times() {
 
   grnxx::io::Pool pool(grnxx::io::POOL_TEMPORARY, "temp.grn");
 
-  grnxx::db::Vector<T> vector;
-  vector.create(&pool);
+  grnxx::db::Vector<T> vector(grnxx::db::VECTOR_CREATE, pool);
 
   grnxx::Time start, end;
 
@@ -182,24 +180,24 @@ void test_times() {
 
 
   start = grnxx::Time::now();
-  for (std::uint64_t id = vector.id_max() - VECTOR_SIZE + 1;
-       id <= vector.id_max(); ++id) {
+  for (std::uint64_t id = vector.max_id() - VECTOR_SIZE + 1;
+       id <= vector.max_id(); ++id) {
     vector[id] = T(0);
   }
   end = grnxx::Time::now();
   double ex_set_1st_elapsed = 1.0 * (end - start).nanoseconds() / VECTOR_SIZE;
 
   start = grnxx::Time::now();
-  for (std::uint64_t id = vector.id_max() - VECTOR_SIZE + 1;
-       id <= vector.id_max(); ++id) {
+  for (std::uint64_t id = vector.max_id() - VECTOR_SIZE + 1;
+       id <= vector.max_id(); ++id) {
     vector[id] = T(1);
   }
   end = grnxx::Time::now();
   double ex_set_2nd_elapsed = 1.0 * (end - start).nanoseconds() / VECTOR_SIZE;
 
   start = grnxx::Time::now();
-  for (std::uint64_t id = vector.id_max() - VECTOR_SIZE + 1;
-       id <= vector.id_max(); ++id) {
+  for (std::uint64_t id = vector.max_id() - VECTOR_SIZE + 1;
+       id <= vector.max_id(); ++id) {
     total += vector[id];
   }
   end = grnxx::Time::now();
@@ -248,14 +246,12 @@ void test_times() {
   const std::uint32_t block_id = vector.block_id();
   vector.close();
 
-
   start = grnxx::Time::now();
-  grnxx::db::Vector<T>::unlink(&pool, block_id);
+  grnxx::db::Vector<T>::unlink(pool, block_id);
   end = grnxx::Time::now();
   double unlink_elapsed = (end - start).nanoseconds();
 
-
-  vector.create(&pool, 0);
+  vector.create(pool, 0);
 
   start = grnxx::Time::now();
   for (std::uint64_t id = 0; id < VECTOR_SIZE; ++id) {
-------------- next part --------------
HTML����������������������������...
Download 



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