[Groonga-commit] groonga/grnxx [master] Add variables and logics for reuse. (grnxx::alpha::BlobVector)

アーカイブの一覧に戻る

susumu.yata null+****@clear*****
Tue Dec 4 21:39:43 JST 2012


susumu.yata	2012-12-04 21:39:43 +0900 (Tue, 04 Dec 2012)

  New Revision: 0e05ef26bcbdbdb5cda30f11d9d9d73ad9c0674b
  https://github.com/groonga/grnxx/commit/0e05ef26bcbdbdb5cda30f11d9d9d73ad9c0674b

  Log:
    Add variables and logics for reuse. (grnxx::alpha::BlobVector)

  Modified files:
    lib/alpha/blob_vector.cpp
    lib/alpha/blob_vector.hpp

  Modified: lib/alpha/blob_vector.cpp (+50 -6)
===================================================================
--- lib/alpha/blob_vector.cpp    2012-12-04 13:27:47 +0900 (8fd369f)
+++ lib/alpha/blob_vector.cpp    2012-12-04 21:39:43 +0900 (8a62443)
@@ -30,7 +30,9 @@ BlobVectorOpen BLOB_VECTOR_OPEN;
 BlobVectorHeader::BlobVectorHeader(uint32_t cells_block_id)
   : cells_block_id_(cells_block_id),
     value_store_block_id_(io::BLOCK_INVALID_ID),
-    next_medium_value_offset_(0),
+    page_infos_block_id_(io::BLOCK_INVALID_ID),
+    next_page_id_(0),
+    next_value_offset_(0),
     latest_large_value_block_id_(io::BLOCK_INVALID_ID),
     inter_process_mutex_() {}
 
@@ -41,7 +43,9 @@ StringBuilder &BlobVectorHeader::write_to(StringBuilder &builder) const {
 
   builder << "{ cells_block_id = " << cells_block_id_
           << ", value_store_block_id = " << value_store_block_id_
-          << ", next_medium_value_offset = " << next_medium_value_offset_
+          << ", page_infos_block_id = " << page_infos_block_id_
+          << ", next_page_id = " << next_page_id_
+          << ", next_value_offset = " << next_value_offset_
           << ", latest_large_value_block_id = " << latest_large_value_block_id_
           << ", inter_process_mutex = " << inter_process_mutex_;
   return builder << " }";
@@ -231,6 +235,7 @@ BlobVectorImpl::BlobVectorImpl()
     recycler_(nullptr),
     cells_(),
     value_store_(),
+    page_infos_(),
     inter_thread_mutex_() {}
 
 void BlobVectorImpl::create_vector(io::Pool pool) {
@@ -292,23 +297,49 @@ BlobVectorMediumValue BlobVectorImpl::create_medium_value(
     }
   }
 
+  if (!page_infos_) {
+    Lock lock(mutable_inter_thread_mutex());
+    if (!page_infos_) {
+      if (header_->page_infos_block_id() == io::BLOCK_INVALID_ID) {
+        Lock lock(mutable_inter_process_mutex());
+        if (header_->page_infos_block_id() == io::BLOCK_INVALID_ID) {
+          page_infos_ = Vector<BlobVectorPageInfo>(
+              VECTOR_CREATE, pool_, BlobVectorPageInfo());
+          header_->set_page_infos_block_id(page_infos_.block_id());
+        }
+      }
+      if (!page_infos_) {
+        page_infos_ = Vector<BlobVectorPageInfo>(
+            VECTOR_OPEN, pool_, header_->page_infos_block_id());
+      }
+    }
+  }
+
   // TODO: Lock.
 
   capacity = (capacity + (BLOB_VECTOR_UNIT_SIZE - 1)) &
       ~(BLOB_VECTOR_UNIT_SIZE - 1);
 
-  uint64_t offset = header_->next_medium_value_offset();
+  uint64_t offset = header_->next_value_offset();
   const uint64_t offset_in_page =
-      offset & (BLOB_VECTOR_VALUE_STORE_PAGE_SIZE - 1);
+      ((offset - 1) & (BLOB_VECTOR_VALUE_STORE_PAGE_SIZE - 1)) + 1;
   const uint64_t size_left_in_page =
       BLOB_VECTOR_VALUE_STORE_PAGE_SIZE - offset_in_page;
 
   const uint64_t required_size =
       capacity + sizeof(BlobVectorMediumValueHeader);
   if (required_size > size_left_in_page) {
-    offset += size_left_in_page;
+    const uint32_t page_id = header_->next_page_id();
+    offset = static_cast<uint64_t>(
+        page_id << BLOB_VECTOR_VALUE_STORE_PAGE_SIZE_BITS);
+    if (page_infos_[page_id].next_page_id() != BLOB_VECTOR_INVALID_PAGE_ID) {
+      header_->set_next_page_id(page_infos_[page_id].next_page_id());
+    } else {
+      header_->set_next_page_id(page_id + 1);
+    }
+    page_infos_[page_id].set_num_values(0);
   }
-  header_->set_next_medium_value_offset(offset + required_size);
+  header_->set_next_value_offset(offset + required_size);
 
   auto value_header = reinterpret_cast<BlobVectorMediumValueHeader *>(
       &value_store_[offset]);
@@ -316,6 +347,10 @@ BlobVectorMediumValue BlobVectorImpl::create_medium_value(
   value_header->set_capacity(capacity);
   std::memcpy(value_header + 1, ptr, length);
 
+  const uint32_t page_id = static_cast<uint32_t>(
+      offset >> BLOB_VECTOR_VALUE_STORE_PAGE_SIZE_BITS);
+  page_infos_[page_id].set_num_values(page_infos_[page_id].num_values() + 1);
+
   return BlobVectorMediumValue(offset, length, attribute);
 }
 
@@ -340,6 +375,15 @@ void BlobVectorImpl::free_value(BlobVectorCell cell) {
       break;
     }
     case BLOB_VECTOR_MEDIUM: {
+      // TODO: Lock.
+
+      const uint32_t page_id = static_cast<uint32_t>(
+          cell.medium().offset() >> BLOB_VECTOR_VALUE_STORE_PAGE_SIZE_BITS);
+      page_infos_[page_id].set_num_values(
+          page_infos_[page_id].num_values() - 1);
+      if (page_infos_[page_id].num_values() == 0) {
+        // TODO: Freeze.
+      }
       break;
     }
     case BLOB_VECTOR_LARGE: {

  Modified: lib/alpha/blob_vector.hpp (+57 -5)
===================================================================
--- lib/alpha/blob_vector.hpp    2012-12-04 13:27:47 +0900 (febf2e8)
+++ lib/alpha/blob_vector.hpp    2012-12-04 21:39:43 +0900 (93e1c24)
@@ -25,6 +25,9 @@ namespace alpha {
 
 const uint64_t BLOB_VECTOR_MAX_ID = uint64_t(1) << 40;
 
+const uint32_t BLOB_VECTOR_INVALID_PAGE_ID =
+    std::numeric_limits<uint32_t>::max();
+
 const uint64_t BLOB_VECTOR_SMALL_VALUE_MAX_LENGTH  = 7;
 
 const uint64_t BLOB_VECTOR_MEDIUM_VALUE_MIN_LENGTH =
@@ -67,8 +70,14 @@ class BlobVectorHeader {
   uint32_t value_store_block_id() const {
     return value_store_block_id_;
   }
-  uint64_t next_medium_value_offset() const {
-    return next_medium_value_offset_;
+  uint32_t page_infos_block_id() const {
+    return page_infos_block_id_;
+  }
+  uint32_t next_page_id() const {
+    return next_page_id_;
+  }
+  uint64_t next_value_offset() const {
+    return next_value_offset_;
   }
   uint32_t latest_large_value_block_id() const {
     return latest_large_value_block_id_;
@@ -77,8 +86,14 @@ class BlobVectorHeader {
   void set_value_store_block_id(uint32_t value) {
     value_store_block_id_ = value;
   }
-  void set_next_medium_value_offset(uint64_t value) {
-    next_medium_value_offset_ = value;
+  void set_page_infos_block_id(uint32_t value) {
+    page_infos_block_id_ = value;
+  }
+  void set_next_page_id(uint32_t value) {
+    next_page_id_ = value;
+  }
+  void set_next_value_offset(uint64_t value) {
+    next_value_offset_ = value;
   }
   void set_latest_large_value_block_id(uint32_t value) {
     latest_large_value_block_id_ = value;
@@ -93,7 +108,9 @@ class BlobVectorHeader {
  private:
   uint32_t cells_block_id_;
   uint32_t value_store_block_id_;
-  uint64_t next_medium_value_offset_;
+  uint32_t page_infos_block_id_;
+  uint32_t next_page_id_;
+  uint64_t next_value_offset_;
   uint32_t latest_large_value_block_id_;
   Mutex inter_process_mutex_;
 };
@@ -114,6 +131,40 @@ const uint8_t BLOB_VECTOR_TYPE_MASK = 0x30;
 
 StringBuilder &operator<<(StringBuilder &builder, BlobVectorType type);
 
+class BlobVectorPageInfo {
+ public:
+  BlobVectorPageInfo()
+    : next_page_id_(BLOB_VECTOR_INVALID_PAGE_ID), stamp_(0), reserved_(0) {}
+
+  uint32_t next_page_id() const {
+    return next_page_id_;
+  }
+  uint32_t num_values() const {
+    return num_values_;
+  }
+  uint16_t stamp() const {
+    return reserved_;
+  }
+
+  void set_next_page_id(uint32_t value) {
+    next_page_id_ = value;
+  }
+  void set_num_values(uint32_t value) {
+    num_values_ = value;
+  }
+  void set_stamp(uint16_t value) {
+    stamp_ = value;
+  }
+
+ private:
+  union {
+    uint32_t next_page_id_;
+    uint32_t num_values_;
+  };
+  uint16_t stamp_;
+  uint16_t reserved_;
+};
+
 class BlobVectorMediumValueHeader {
  public:
   uint64_t value_id() const {
@@ -362,6 +413,7 @@ class BlobVectorImpl {
   Recycler *recycler_;
   Vector<BlobVectorCell> cells_;
   BlobVectorValueStore value_store_;
+  Vector<BlobVectorPageInfo> page_infos_;
   Mutex inter_thread_mutex_;
 
   BlobVectorImpl();
-------------- next part --------------
HTML����������������������������...
ダウンロード 



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