[Groonga-commit] groonga/grnxx at 43d50c5 [master] Add a specialization for grnxx::Array<bool>.

アーカイブの一覧に戻る

susumu.yata null+****@clear*****
Thu May 16 16:26:10 JST 2013


susumu.yata	2013-05-16 16:26:10 +0900 (Thu, 16 May 2013)

  New Revision: 43d50c5ff7fa75e3df76e8af13640f1051be3898
  https://github.com/groonga/grnxx/commit/43d50c5ff7fa75e3df76e8af13640f1051be3898

  Message:
    Add a specialization for grnxx::Array<bool>.

  Modified files:
    lib/grnxx/array.hpp

  Modified: lib/grnxx/array.hpp (+115 -0)
===================================================================
--- lib/grnxx/array.hpp    2013-05-16 14:59:23 +0900 (6fe4afe)
+++ lib/grnxx/array.hpp    2013-05-16 16:26:10 +0900 (d7f8e56)
@@ -441,6 +441,121 @@ class Array {
   }
 };
 
+// Bit array.
+template <uint64_t PAGE_SIZE_IN_BITS,
+          uint64_t TABLE_SIZE,
+          uint64_t SECONDARY_TABLE_SIZE>
+class Array<bool, PAGE_SIZE_IN_BITS, TABLE_SIZE, SECONDARY_TABLE_SIZE> {
+ public:
+  using Unit = uint8_t;
+  static constexpr uint64_t UNIT_SIZE = sizeof(Unit) * 8;
+  static constexpr uint64_t PAGE_SIZE = PAGE_SIZE_IN_BITS / UNIT_SIZE;
+
+ private:
+  static_assert((PAGE_SIZE % UNIT_SIZE) == 0, "(PAGE_SIZE % UNIT_SIZE) != 0");
+  using ArrayImpl = Array<Unit, PAGE_SIZE, TABLE_SIZE, SECONDARY_TABLE_SIZE>;
+
+ public:
+  using Value = typename Traits<bool>::Type;
+  using ValueArg = typename Traits<bool>::ArgumentType;
+
+  Array() : impl_() {}
+  ~Array() {}
+
+  // Return true iff the array is valid.
+  explicit operator bool() const {
+    return static_cast<bool>(impl_);
+  }
+
+  // Create an array.
+  bool create(Storage *storage, uint32_t storage_node_id) {
+    return impl_.create(storage, storage_node_id);
+  }
+
+  // Create an array with the default value.
+  bool create(Storage *storage, uint32_t storage_node_id,
+              ValueArg default_value) {
+    return impl_.create(storage, storage_node_id, default_value ? 0xFF : 0x00);
+  }
+
+  // Open an array.
+  bool open(Storage *storage, uint32_t storage_node_id) {
+    return impl_.open(storage, storage_node_id);
+  }
+
+  // Unlink an array.
+  static bool unlink(Storage *storage, uint32_t storage_node_id) {
+    return ArrayImpl::unlink(storage, storage_node_id);
+  }
+
+  // Return the number of values in each page.
+  static constexpr uint64_t page_size() {
+    return PAGE_SIZE_IN_BITS;
+  }
+  // Return the number of pages in each table.
+  static constexpr uint64_t table_size() {
+    return TABLE_SIZE;
+  }
+  // Return the number of tables in each secondary table.
+  static constexpr uint64_t secondary_table_size() {
+    return SECONDARY_TABLE_SIZE;
+  }
+  // Return the number of values in Array.
+  static constexpr uint64_t size() {
+    return page_size() * table_size() * secondary_table_size();
+  }
+
+  // Return the storage node ID.
+  uint32_t storage_node_id() const {
+    return impl_.storage_node_id();
+  }
+
+  // Get a value.
+  // This function throws an exception on failure.
+  Value operator[](uint64_t value_id) {
+    return (impl_[value_id / UNIT_SIZE] &
+            (Unit(1) << (value_id % UNIT_SIZE))) != 0;
+  }
+
+  // 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) {
+    const uint64_t unit_id = value_id / UNIT_SIZE;
+    const Unit * const page = get_page(unit_id / PAGE_SIZE);
+    if (!page) {
+      return false;
+    }
+    if (value) {
+      *value = (page[unit_id % PAGE_SIZE] &
+                (Unit(1) << (value_id % UNIT_SIZE))) != 0;
+    }
+    return true;
+  }
+
+  // Set a value and return true on success.
+  bool set(uint64_t value_id, ValueArg value) {
+    const uint64_t unit_id = value_id / UNIT_SIZE;
+    Unit * const page = get_page(unit_id / PAGE_SIZE);
+    if (!page) {
+      return false;
+    }
+    if (value) {
+      page[unit_id % PAGE_SIZE] |= Unit(1) << (value_id % UNIT_SIZE);
+    } else {
+      page[unit_id % PAGE_SIZE] &= ~(Unit(1) << (value_id % UNIT_SIZE));
+    }
+    return true;
+  }
+
+  // Get a page and return its starting address on success.
+  Unit *get_page(uint64_t page_id) {
+    return impl_.get_page(page_id);
+  }
+
+ private:
+  ArrayImpl impl_;
+};
+
 }  // namespace grnxx
 
 #endif  // GRNXX_ARRAY_HPP
-------------- next part --------------
HTML����������������������������...
ダウンロード 



More information about the Groonga-commit mailing list
アーカイブの一覧に戻る