[Groonga-commit] groonga/grnxx at 7a19366 [master] Improve the speed of Array3D.

Back to archive index

susumu.yata null+****@clear*****
Tue Jul 9 16:27:04 JST 2013


susumu.yata	2013-07-09 16:27:04 +0900 (Tue, 09 Jul 2013)

  New Revision: 7a19366999e9aa96c0e44ea3621d0f4b2e2a3315
  https://github.com/groonga/grnxx/commit/7a19366999e9aa96c0e44ea3621d0f4b2e2a3315

  Message:
    Improve the speed of Array3D.
    
    Use a dummy table to remove a branch in get_value().

  Modified files:
    lib/grnxx/array2_impl.cpp
    lib/grnxx/array2_impl.hpp

  Modified: lib/grnxx/array2_impl.cpp (+24 -5)
===================================================================
--- lib/grnxx/array2_impl.cpp    2013-07-09 15:59:47 +0900 (8246f94)
+++ lib/grnxx/array2_impl.cpp    2013-07-09 16:27:04 +0900 (83b4543)
@@ -265,6 +265,7 @@ bool Array2D::unlink(Storage *storage, uint32_t storage_node_id,
 }
 
 void Array2D::reserve_pages() {
+  // Create a table cache.
   pages_.reset(new (std::nothrow) void *[header_->table_size]);
   if (!pages_) {
     GRNXX_ERROR() << "new void *[] failed: size = " << header_->table_size;
@@ -308,15 +309,18 @@ Array3D::Array3D()
       header_(nullptr),
       fill_page_(nullptr),
       secondary_table_(nullptr),
+      dummy_table_(),
       page_mutex_(),
       table_mutex_() {}
 
 Array3D::~Array3D() {
   if (tables_) {
+    uint64_t offset = 0;
     for (uint64_t i = 0; i < header_->secondary_table_size; ++i) {
-      if (tables_[i] != invalid_table_address()) {
-        delete [] (tables_[i] + (header_->table_size * i));
+      if (tables_[i] != (dummy_table_.get() - offset)) {
+        delete [] (tables_[i] + offset);
       }
+      offset += header_->table_size;
     }
   }
 }
@@ -430,20 +434,34 @@ bool Array3D::unlink(Storage *storage, uint32_t storage_node_id,
 }
 
 void Array3D::reserve_tables() {
+  // Create a dummy table cache.
+  dummy_table_.reset(new (std::nothrow) void *[header_->table_size]);
+  if (!dummy_table_) {
+    GRNXX_ERROR() << "new void *[] failed: size = " << header_->table_size;
+    throw MemoryError();
+  }
+  for (uint64_t i = 0; i < header_->table_size; ++i) {
+    dummy_table_[i] = invalid_page_address();
+  }
+  // Create a secondary table cache.
   tables_.reset(new (std::nothrow) void **[header_->secondary_table_size]);
   if (!tables_) {
     GRNXX_ERROR() << "new void **[] failed: size = "
                   << header_->secondary_table_size;
     throw MemoryError();
   }
+  // Fill the secondary table cache with the dummy table cache.
+  uint64_t offset = 0;
   for (uint64_t i = 0; i < header_->secondary_table_size; ++i) {
-    tables_[i] = invalid_table_address();
+    tables_[i] = dummy_table_.get() - offset;
+    offset += header_->table_size;
   }
 }
 
 void Array3D::reserve_page(uint64_t page_id) {
   const uint64_t table_id = page_id / header_->table_size;
-  if (tables_[table_id] == invalid_table_address()) {
+  if (tables_[table_id] ==
+      (dummy_table_.get() - (header_->table_size * table_id))) {
     reserve_table(table_id);
   }
   Lock inter_thread_lock(&page_mutex_);
@@ -475,7 +493,8 @@ void Array3D::reserve_page(uint64_t page_id) {
 
 void Array3D::reserve_table(uint64_t table_id) {
   Lock inter_thread_lock(&table_mutex_);
-  if (tables_[table_id] == invalid_table_address()) {
+  if (tables_[table_id] ==
+      (dummy_table_.get() - (header_->table_size * table_id))) {
     if (secondary_table_[table_id] == STORAGE_INVALID_NODE_ID) {
       Lock inter_process_lock(&header_->table_mutex);
       if (secondary_table_[table_id] == STORAGE_INVALID_NODE_ID) {

  Modified: lib/grnxx/array2_impl.hpp (+2 -5)
===================================================================
--- lib/grnxx/array2_impl.hpp    2013-07-09 15:59:47 +0900 (9d11ff2)
+++ lib/grnxx/array2_impl.hpp    2013-07-09 16:27:04 +0900 (ad1efa1)
@@ -172,8 +172,7 @@ class Array3D {
   T *get_value(uint64_t value_id) {
     const uint64_t table_id = value_id / (PAGE_SIZE * TABLE_SIZE);
     const uint64_t page_id = value_id / PAGE_SIZE;
-    if ((tables_[table_id] == invalid_page_address()) ||
-        (tables_[table_id][page_id] == invalid_page_address())) {
+    if (tables_[table_id][page_id] == invalid_page_address()) {
       reserve_page(page_id);
     }
     return &static_cast<T *>(tables_[table_id][page_id])[value_id];
@@ -187,6 +186,7 @@ class Array3D {
   ArrayHeader *header_;
   ArrayFillPage fill_page_;
   uint32_t *secondary_table_;
+  std::unique_ptr<void *[]> dummy_table_;
   Mutex page_mutex_;
   Mutex table_mutex_;
 
@@ -194,9 +194,6 @@ class Array3D {
   void reserve_page(uint64_t page_id);
   void reserve_table(uint64_t table_id);
 
-  static void **invalid_table_address() {
-    return reinterpret_cast<void **>(static_cast<char *>(nullptr) + 1);
-  }
   static void *invalid_page_address() {
     return static_cast<char *>(nullptr) + 1;
   }
-------------- next part --------------
HTML����������������������������...
Download 



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