[Groonga-commit] groonga/grnxx [master] Simplify the implementation of grnxx::alpha::BlobVector.

Back to archive index

susumu.yata null+****@clear*****
Mon Dec 10 00:59:07 JST 2012


susumu.yata	2012-12-10 00:59:07 +0900 (Mon, 10 Dec 2012)

  New Revision: 67ebc4b58855959a26b79c8399f18003ec8ad59c
  https://github.com/groonga/grnxx/commit/67ebc4b58855959a26b79c8399f18003ec8ad59c

  Log:
    Simplify the implementation of grnxx::alpha::BlobVector.

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

  Modified: lib/alpha/blob_vector.cpp (+72 -141)
===================================================================
--- lib/alpha/blob_vector.cpp    2012-12-09 21:33:21 +0900 (0b3517a)
+++ lib/alpha/blob_vector.cpp    2012-12-10 00:59:07 +0900 (8fc2c81)
@@ -27,10 +27,10 @@ namespace alpha {
 BlobVectorCreate BLOB_VECTOR_CREATE;
 BlobVectorOpen BLOB_VECTOR_OPEN;
 
-BlobVectorHeader::BlobVectorHeader(uint32_t cells_block_id)
-  : cells_block_id_(cells_block_id),
+BlobVectorHeader::BlobVectorHeader(uint32_t table_block_id)
+  : table_block_id_(table_block_id),
     value_store_block_id_(io::BLOCK_INVALID_ID),
-    page_infos_block_id_(io::BLOCK_INVALID_ID),
+    index_store_block_id_(io::BLOCK_INVALID_ID),
     next_page_id_(0),
     next_value_offset_(0),
     latest_frozen_page_id_(BLOB_VECTOR_INVALID_PAGE_ID),
@@ -42,9 +42,9 @@ StringBuilder &BlobVectorHeader::write_to(StringBuilder &builder) const {
     return builder;
   }
 
-  builder << "{ cells_block_id = " << cells_block_id_
+  builder << "{ table_block_id = " << table_block_id_
           << ", value_store_block_id = " << value_store_block_id_
-          << ", page_infos_block_id = " << page_infos_block_id_
+          << ", index_store_block_id = " << index_store_block_id_
           << ", next_page_id = " << next_page_id_
           << ", next_value_offset = " << next_value_offset_
           << ", latest_large_value_block_id = " << latest_large_value_block_id_
@@ -52,41 +52,6 @@ StringBuilder &BlobVectorHeader::write_to(StringBuilder &builder) const {
   return builder << " }";
 }
 
-StringBuilder &operator<<(StringBuilder &builder, BlobVectorType type) {
-  switch (type) {
-    case BLOB_VECTOR_NULL: {
-      return builder << "BLOB_VECTOR_NULL";
-    }
-    case BLOB_VECTOR_SMALL: {
-      return builder << "BLOB_VECTOR_SMALL";
-    }
-    case BLOB_VECTOR_MEDIUM: {
-      return builder << "BLOB_VECTOR_MEDIUM";
-    }
-    case BLOB_VECTOR_LARGE: {
-      return builder << "BLOB_VECTOR_LARGE";
-    }
-    default: {
-      return builder << "n/a";
-    }
-  }
-}
-
-StringBuilder &operator<<(StringBuilder &builder,
-                          BlobVectorAttribute attribute) {
-  switch (attribute) {
-    case BLOB_VECTOR_APPENDABLE: {
-      return builder << "BLOB_VECTOR_APPENDABLE";
-    }
-    case BLOB_VECTOR_PREPENDABLE: {
-      return builder << "BLOB_VECTOR_PREPENDABLE";
-    }
-    default: {
-      return builder << "n/a";
-    }
-  }
-}
-
 std::unique_ptr<BlobVectorImpl> BlobVectorImpl::create(io::Pool pool) {
   std::unique_ptr<BlobVectorImpl> vector(new (std::nothrow) BlobVectorImpl);
   if (!vector) {
@@ -109,13 +74,7 @@ std::unique_ptr<BlobVectorImpl> BlobVectorImpl::open(io::Pool pool,
 }
 
 const void *BlobVectorImpl::get_value(uint64_t id, uint64_t *length) {
-  if (id > BLOB_VECTOR_MAX_ID) {
-    GRNXX_ERROR() << "invalid argument: id = " << id
-                  << ", max_id = " << BLOB_VECTOR_MAX_ID;
-    GRNXX_THROW();
-  }
-
-  const BlobVectorCell cell = cells_[id];
+  const BlobVectorCell cell = table_[id];
   switch (cell.type()) {
     case BLOB_VECTOR_NULL: {
       if (length) {
@@ -125,30 +84,28 @@ const void *BlobVectorImpl::get_value(uint64_t id, uint64_t *length) {
     }
     case BLOB_VECTOR_SMALL: {
       if (length) {
-        *length = cell.small().length();
+        *length = cell.small_length();
       }
       // FIXME: The cell might be updated by other threads and processes.
       //        This interface cannot solve this problem.
-      return cells_[id].small().value();
+      return table_[id].value();
     }
     case BLOB_VECTOR_MEDIUM: {
       if (!value_store_) {
         Lock lock(mutable_inter_thread_mutex());
         if (!value_store_) {
-          value_store_ = BlobVectorValueStore(
-              VECTOR_OPEN, pool_, header_->value_store_block_id());
+          value_store_.open(pool_, header_->value_store_block_id());
         }
       }
       if (length) {
-        *length = cell.medium().length();
+        *length = cell.medium_length();
       }
-      return &value_store_[cell.medium().offset()]
-          + sizeof(BlobVectorMediumValueHeader);
+      return &value_store_[cell.offset()];
     }
     case BLOB_VECTOR_LARGE: {
-      const BlobVectorLargeValueHeader *value_header =
-          static_cast<const BlobVectorLargeValueHeader *>(
-              pool_.get_block_address(cell.large().block_id()));
+      const BlobVectorValueHeader *value_header =
+          static_cast<const BlobVectorValueHeader *>(
+              pool_.get_block_address(cell.block_id()));
       if (length) {
         *length = value_header->length();
       }
@@ -161,28 +118,17 @@ const void *BlobVectorImpl::get_value(uint64_t id, uint64_t *length) {
   }
 }
 
-void BlobVectorImpl::set_value(uint64_t id, const void *ptr, uint64_t length,
-                               uint64_t capacity,
-                               BlobVectorAttribute attribute) {
-  if (id > BLOB_VECTOR_MAX_ID) {
-    GRNXX_ERROR() << "invalid argument: id = " << id
-                  << ", max_id = " << BLOB_VECTOR_MAX_ID;
-    GRNXX_THROW();
-  }
-
+void BlobVectorImpl::set_value(uint64_t id, const void *ptr, uint64_t length) {
   BlobVectorCell new_cell;
   if (!ptr) {
-    new_cell = BlobVectorNullValue(attribute);
+    new_cell = BlobVectorCell::null_value_cell();
   } else {
-    if (capacity < length) {
-      capacity = length;
-    }
-    if (capacity < BLOB_VECTOR_MEDIUM_VALUE_MIN_LENGTH) {
-      new_cell = BlobVectorSmallValue(ptr, length, attribute);
-    } else if (capacity < BLOB_VECTOR_LARGE_VALUE_MIN_LENGTH) {
-      new_cell = create_medium_value(id, ptr, length, capacity, attribute);
+    if (length < BLOB_VECTOR_MEDIUM_VALUE_MIN_LENGTH) {
+      new_cell = BlobVectorCell::small_value_cell(ptr, length);
+    } else if (length < BLOB_VECTOR_LARGE_VALUE_MIN_LENGTH) {
+      new_cell = create_medium_value(ptr, length);
     } else {
-      new_cell = create_large_value(id, ptr, length, capacity, attribute);
+      new_cell = create_large_value(ptr, length);
     }
   }
 
@@ -190,8 +136,8 @@ void BlobVectorImpl::set_value(uint64_t id, const void *ptr, uint64_t length,
   BlobVectorCell old_cell;
   try {
     do {
-      old_cell = cells_[id];
-    } while (!atomic_compare_and_swap(old_cell, new_cell, &cells_[id]));
+      old_cell = table_[id];
+    } while (!atomic_compare_and_swap(old_cell, new_cell, &table_[id]));
   } catch (...) {
     free_value(new_cell);
     throw;
@@ -218,14 +164,14 @@ void BlobVectorImpl::unlink(io::Pool pool, uint32_t block_id) {
   if (vector->header_->latest_large_value_block_id() != io::BLOCK_INVALID_ID) {
     uint32_t block_id = vector->header_->latest_large_value_block_id();
     do {
-      auto value_header = static_cast<const BlobVectorLargeValueHeader *>(
+      auto value_header = static_cast<const BlobVectorValueHeader *>(
           pool.get_block_address(block_id));
       const uint32_t prev_block_id = value_header->prev_value_block_id();
       pool.free_block(block_id);
       block_id = prev_block_id;
     } while (block_id != vector->header_->latest_large_value_block_id());
   }
-  Vector<BlobVectorCell>::unlink(pool, vector->header_->cells_block_id());
+  BlobVectorTable::unlink(pool, vector->header_->table_block_id());
   pool.free_block(vector->block_info_->id());
 }
 
@@ -234,9 +180,9 @@ BlobVectorImpl::BlobVectorImpl()
     block_info_(nullptr),
     header_(nullptr),
     recycler_(nullptr),
-    cells_(),
+    table_(),
     value_store_(),
-    page_infos_(),
+    index_store_(),
     inter_thread_mutex_(MUTEX_UNLOCKED) {}
 
 void BlobVectorImpl::create_vector(io::Pool pool) {
@@ -244,7 +190,7 @@ void BlobVectorImpl::create_vector(io::Pool pool) {
   block_info_ = pool.create_block(sizeof(BlobVectorHeader));
 
   try {
-    cells_ = Vector<BlobVectorCell>(VECTOR_CREATE, pool_, BlobVectorCell());
+    table_.create(pool_, BlobVectorCell());
   } catch (...) {
     pool_.free_block(*block_info_);
     throw;
@@ -252,7 +198,7 @@ void BlobVectorImpl::create_vector(io::Pool pool) {
 
   void * const block_address = pool_.get_block_address(*block_info_);
   header_ = static_cast<BlobVectorHeader *>(block_address);
-  *header_ = BlobVectorHeader(cells_.block_id());
+  *header_ = BlobVectorHeader(table_.block_id());
 
   recycler_ = pool.mutable_recycler();
 }
@@ -274,50 +220,42 @@ void BlobVectorImpl::open_vector(io::Pool pool, uint32_t block_id) {
   recycler_ = pool.mutable_recycler();
 
   // Open the core table.
-  cells_ = Vector<BlobVectorCell>(VECTOR_OPEN, pool,
-                                  header_->cells_block_id());
+  table_.open(pool, header_->table_block_id());
 }
 
-BlobVectorMediumValue BlobVectorImpl::create_medium_value(
-    uint32_t id, const void *ptr, uint64_t length, uint64_t capacity,
-    BlobVectorAttribute attribute) {
+BlobVectorCell BlobVectorImpl::create_medium_value(const void *ptr,
+                                                   uint64_t length) {
   Lock lock(mutable_inter_thread_mutex());
 
   if (!value_store_) {
     if (header_->value_store_block_id() == io::BLOCK_INVALID_ID) {
       Lock lock(mutable_inter_process_mutex());
       if (header_->value_store_block_id() == io::BLOCK_INVALID_ID) {
-        value_store_ = BlobVectorValueStore(VECTOR_CREATE, pool_);
+        value_store_.create(pool_);
         header_->set_value_store_block_id(value_store_.block_id());
       }
     }
     if (!value_store_) {
-      value_store_ = BlobVectorValueStore(
-          VECTOR_OPEN, pool_, header_->value_store_block_id());
+      value_store_.open(pool_, header_->value_store_block_id());
     }
   }
 
-  if (!page_infos_) {
-    if (header_->page_infos_block_id() == io::BLOCK_INVALID_ID) {
+  if (!index_store_) {
+    if (header_->index_store_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 (header_->index_store_block_id() == io::BLOCK_INVALID_ID) {
+        index_store_.create(pool_, BlobVectorPageInfo());
+        header_->set_index_store_block_id(index_store_.block_id());
       }
     }
-    if (!page_infos_) {
-      page_infos_ = Vector<BlobVectorPageInfo>(
-          VECTOR_OPEN, pool_, header_->page_infos_block_id());
+    if (!index_store_) {
+      index_store_.open(pool_, header_->index_store_block_id());
     }
   }
 
   // Unfreeze the oldest frozen page for reuse.
   unfreeze_oldest_frozen_page();
 
-  capacity = (capacity + (BLOB_VECTOR_UNIT_SIZE - 1)) &
-      ~(BLOB_VECTOR_UNIT_SIZE - 1);
-
   uint64_t offset = header_->next_value_offset();
   const uint64_t offset_in_page =
       ((offset - 1) & (BLOB_VECTOR_VALUE_STORE_PAGE_SIZE - 1)) + 1;
@@ -325,14 +263,12 @@ BlobVectorMediumValue BlobVectorImpl::create_medium_value(
       BLOB_VECTOR_VALUE_STORE_PAGE_SIZE - offset_in_page;
 
   // Reserve a new page if there is not enough space in the current page.
-  const uint64_t required_size =
-      capacity + sizeof(BlobVectorMediumValueHeader);
-  if (required_size > size_left_in_page) {
+  if (length > size_left_in_page) {
     if (offset != 0) {
       // Freeze the current page if it is empty.
       const uint32_t page_id = static_cast<uint32_t>(
           (offset - 1) >> BLOB_VECTOR_VALUE_STORE_PAGE_SIZE_BITS);
-      if (page_infos_[page_id].num_values() == 0) {
+      if (index_store_[page_id].num_values() == 0) {
         freeze_page(page_id);
       }
     }
@@ -340,40 +276,35 @@ BlobVectorMediumValue BlobVectorImpl::create_medium_value(
     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());
+    if (index_store_[page_id].next_page_id() != BLOB_VECTOR_INVALID_PAGE_ID) {
+      header_->set_next_page_id(index_store_[page_id].next_page_id());
     } else {
       header_->set_next_page_id(page_id + 1);
     }
-    page_infos_[page_id].set_num_values(0);
+    index_store_[page_id].set_num_values(0);
   }
-  header_->set_next_value_offset(offset + required_size);
+  header_->set_next_value_offset(offset + length);
 
-  auto value_header = reinterpret_cast<BlobVectorMediumValueHeader *>(
-      &value_store_[offset]);
-  value_header->set_value_id(id);
-  value_header->set_capacity(capacity);
-  std::memcpy(value_header + 1, ptr, length);
+  std::memcpy(&value_store_[offset], 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);
+  index_store_[page_id].set_num_values(index_store_[page_id].num_values() + 1);
 
-  return BlobVectorMediumValue(offset, length, attribute);
+  return BlobVectorCell::medium_value_cell(offset, length);
 }
 
-BlobVectorLargeValue BlobVectorImpl::create_large_value(
-    uint32_t, const void *ptr, uint64_t length, uint64_t capacity,
-    BlobVectorAttribute attribute) {
+BlobVectorCell BlobVectorImpl::create_large_value(const void *ptr,
+                                                  uint64_t length) {
   const io::BlockInfo *block_info =
-      pool_.create_block(sizeof(BlobVectorLargeValueHeader) + capacity);
-  BlobVectorLargeValueHeader *value_header =
-      static_cast<BlobVectorLargeValueHeader *>(
+      pool_.create_block(sizeof(BlobVectorValueHeader) + length);
+  BlobVectorValueHeader *value_header =
+      static_cast<BlobVectorValueHeader *>(
           pool_.get_block_address(*block_info));
   value_header->set_length(length);
   std::memcpy(value_header + 1, ptr, length);
   register_large_value(block_info->id(), value_header);
-  return BlobVectorLargeValue(block_info->id(), attribute);
+  return BlobVectorCell::large_value_cell(block_info->id());
 }
 
 void BlobVectorImpl::free_value(BlobVectorCell cell) {
@@ -386,10 +317,10 @@ void BlobVectorImpl::free_value(BlobVectorCell cell) {
       Lock lock(mutable_inter_thread_mutex());
 
       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) {
+          cell.offset() >> BLOB_VECTOR_VALUE_STORE_PAGE_SIZE_BITS);
+      index_store_[page_id].set_num_values(
+          index_store_[page_id].num_values() - 1);
+      if (index_store_[page_id].num_values() == 0) {
         const uint32_t current_page_id =
             static_cast<uint32_t>(header_->next_value_offset()
                                   >> BLOB_VECTOR_VALUE_STORE_PAGE_SIZE_BITS);
@@ -401,9 +332,9 @@ void BlobVectorImpl::free_value(BlobVectorCell cell) {
     }
     case BLOB_VECTOR_LARGE: {
       const io::BlockInfo * const block_info =
-          pool_.get_block_info(cell.large().block_id());
+          pool_.get_block_info(cell.block_id());
       unregister_large_value(block_info->id(),
-          static_cast<BlobVectorLargeValueHeader *>(
+          static_cast<BlobVectorValueHeader *>(
               pool_.get_block_address(*block_info)));
       pool_.free_block(*block_info);
       break;
@@ -412,17 +343,17 @@ void BlobVectorImpl::free_value(BlobVectorCell cell) {
 }
 
 void BlobVectorImpl::register_large_value(uint32_t block_id,
-    BlobVectorLargeValueHeader *value_header) {
+    BlobVectorValueHeader *value_header) {
   Lock lock(mutable_inter_process_mutex());
   if (header_->latest_large_value_block_id() == io::BLOCK_INVALID_ID) {
     value_header->set_next_value_block_id(block_id);
     value_header->set_prev_value_block_id(block_id);
   } else {
     const uint32_t prev_id = header_->latest_large_value_block_id();
-    auto prev_header = static_cast<BlobVectorLargeValueHeader *>(
+    auto prev_header = static_cast<BlobVectorValueHeader *>(
         pool_.get_block_address(prev_id));
     const uint32_t next_id = prev_header->next_value_block_id();
-    auto next_header = static_cast<BlobVectorLargeValueHeader *>(
+    auto next_header = static_cast<BlobVectorValueHeader *>(
         pool_.get_block_address(next_id));
     value_header->set_next_value_block_id(next_id);
     value_header->set_prev_value_block_id(prev_id);
@@ -433,13 +364,13 @@ void BlobVectorImpl::register_large_value(uint32_t block_id,
 }
 
 void BlobVectorImpl::unregister_large_value(uint32_t block_id,
-    BlobVectorLargeValueHeader *value_header) {
+    BlobVectorValueHeader *value_header) {
   Lock lock(mutable_inter_process_mutex());
   const uint32_t next_id = value_header->next_value_block_id();
   const uint32_t prev_id = value_header->prev_value_block_id();
-  auto next_header = static_cast<BlobVectorLargeValueHeader *>(
+  auto next_header = static_cast<BlobVectorValueHeader *>(
       pool_.get_block_address(next_id));
-  auto prev_header = static_cast<BlobVectorLargeValueHeader *>(
+  auto prev_header = static_cast<BlobVectorValueHeader *>(
       pool_.get_block_address(prev_id));
   next_header->set_prev_value_block_id(prev_id);
   prev_header->set_next_value_block_id(next_id);
@@ -449,10 +380,10 @@ void BlobVectorImpl::unregister_large_value(uint32_t block_id,
 }
 
 void BlobVectorImpl::freeze_page(uint32_t page_id) {
-  BlobVectorPageInfo &page_info = page_infos_[page_id];
+  BlobVectorPageInfo &page_info = index_store_[page_id];
   if (header_->latest_frozen_page_id() != BLOB_VECTOR_INVALID_PAGE_ID) {
     BlobVectorPageInfo &latest_frozen_page_info =
-        page_infos_[header_->latest_frozen_page_id()];
+        index_store_[header_->latest_frozen_page_id()];
     page_info.set_next_page_id(latest_frozen_page_info.next_page_id());
     latest_frozen_page_info.set_next_page_id(page_id);
   } else {
@@ -465,11 +396,11 @@ void BlobVectorImpl::freeze_page(uint32_t page_id) {
 void BlobVectorImpl::unfreeze_oldest_frozen_page() {
   if (header_->latest_frozen_page_id() != BLOB_VECTOR_INVALID_PAGE_ID) {
     BlobVectorPageInfo &latest_frozen_page_info =
-        page_infos_[header_->latest_frozen_page_id()];
+        index_store_[header_->latest_frozen_page_id()];
     const uint32_t oldest_frozen_page_id =
         latest_frozen_page_info.next_page_id();
     BlobVectorPageInfo &oldest_frozen_page_info =
-        page_infos_[oldest_frozen_page_id];
+        index_store_[oldest_frozen_page_id];
     if (recycler_->check(oldest_frozen_page_info.stamp())) {
       latest_frozen_page_info.set_next_page_id(
           oldest_frozen_page_info.next_page_id());

  Modified: lib/alpha/blob_vector.hpp (+68 -184)
===================================================================
--- lib/alpha/blob_vector.hpp    2012-12-09 21:33:21 +0900 (5afed2d)
+++ lib/alpha/blob_vector.hpp    2012-12-10 00:59:07 +0900 (e023e6c)
@@ -54,26 +54,21 @@ const uint64_t BLOB_VECTOR_VALUE_STORE_TABLE_SIZE           =
 const uint64_t BLOB_VECTOR_VALUE_STORE_SECONDARY_TABLE_SIZE =
     uint64_t(1) << BLOB_VECTOR_VALUE_STORE_SECONDARY_TABLE_SIZE_BITS;
 
-typedef Vector<char, BLOB_VECTOR_VALUE_STORE_PAGE_SIZE,
-                     BLOB_VECTOR_VALUE_STORE_TABLE_SIZE,
-                     BLOB_VECTOR_VALUE_STORE_SECONDARY_TABLE_SIZE>
-BlobVectorValueStore;
-
 extern class BlobVectorCreate {} BLOB_VECTOR_CREATE;
 extern class BlobVectorOpen {} BLOB_VECTOR_OPEN;
 
 class BlobVectorHeader {
  public:
-  explicit BlobVectorHeader(uint32_t cells_block_id);
+  explicit BlobVectorHeader(uint32_t table_block_id);
 
-  uint32_t cells_block_id() const {
-    return cells_block_id_;
+  uint32_t table_block_id() const {
+    return table_block_id_;
   }
   uint32_t value_store_block_id() const {
     return value_store_block_id_;
   }
-  uint32_t page_infos_block_id() const {
-    return page_infos_block_id_;
+  uint32_t index_store_block_id() const {
+    return index_store_block_id_;
   }
   uint32_t next_page_id() const {
     return next_page_id_;
@@ -91,8 +86,8 @@ class BlobVectorHeader {
   void set_value_store_block_id(uint32_t value) {
     value_store_block_id_ = value;
   }
-  void set_page_infos_block_id(uint32_t value) {
-    page_infos_block_id_ = value;
+  void set_index_store_block_id(uint32_t value) {
+    index_store_block_id_ = value;
   }
   void set_next_page_id(uint32_t value) {
     next_page_id_ = value;
@@ -114,9 +109,9 @@ class BlobVectorHeader {
   StringBuilder &write_to(StringBuilder &builder) const;
 
  private:
-  uint32_t cells_block_id_;
+  uint32_t table_block_id_;
   uint32_t value_store_block_id_;
-  uint32_t page_infos_block_id_;
+  uint32_t index_store_block_id_;
   uint32_t next_page_id_;
   uint64_t next_value_offset_;
   uint32_t latest_frozen_page_id_;
@@ -129,7 +124,7 @@ inline StringBuilder &operator<<(StringBuilder &builder,
   return header.write_to(builder);
 }
 
-enum BlobVectorType : uint8_t {
+enum BlobVectorValueType : uint8_t {
   BLOB_VECTOR_NULL   = 0x00,
   BLOB_VECTOR_SMALL  = 0x10,
   BLOB_VECTOR_MEDIUM = 0x20,
@@ -138,8 +133,6 @@ enum BlobVectorType : uint8_t {
 
 const uint8_t BLOB_VECTOR_TYPE_MASK = 0x30;
 
-StringBuilder &operator<<(StringBuilder &builder, BlobVectorType type);
-
 class BlobVectorPageInfo {
  public:
   BlobVectorPageInfo()
@@ -174,32 +167,7 @@ class BlobVectorPageInfo {
   uint16_t reserved_;
 };
 
-class BlobVectorMediumValueHeader {
- public:
-  uint64_t value_id() const {
-    return dwords_[0] | (static_cast<uint64_t>(bytes_[4]) << 32);
-  }
-  uint64_t capacity() const {
-    return static_cast<uint64_t>(words_[3]) << BLOB_VECTOR_UNIT_SIZE_BITS;
-  }
-
-  void set_value_id(uint64_t value) {
-    dwords_[0] = static_cast<uint32_t>(value);
-    bytes_[4] = static_cast<uint8_t>(value >> 32);
-  }
-  void set_capacity(uint64_t value) {
-    words_[3] = static_cast<uint16_t>(value >> BLOB_VECTOR_UNIT_SIZE_BITS);
-  }
-
- private:
-  union {
-    uint8_t bytes_[8];
-    uint16_t words_[4];
-    uint32_t dwords_[2];
-  };
-};
-
-class BlobVectorLargeValueHeader {
+class BlobVectorValueHeader {
  public:
   uint64_t length() const {
     return length_;
@@ -227,68 +195,52 @@ class BlobVectorLargeValueHeader {
   uint32_t prev_value_block_id_;
 };
 
-// TODO: Not implemented yet.
-enum BlobVectorAttribute : uint8_t {
-  BLOB_VECTOR_APPENDABLE  = 0x00,
-  BLOB_VECTOR_PREPENDABLE = 0x40
-};
-
-const uint8_t BLOB_VECTOR_ATTRIBUTE_MASK = 0x40;
-
-StringBuilder &operator<<(StringBuilder &builder,
-                          BlobVectorAttribute attribute);
-
 const uint8_t BLOB_VECTOR_CELL_FLAGS_MASK = 0xF0;
 
-class BlobVectorNullValue {
+class BlobVectorCell {
  public:
-  explicit BlobVectorNullValue(BlobVectorAttribute attribute)
-    : qword_(0) {
-    bytes_[0] = BLOB_VECTOR_NULL | attribute;
-  }
+  constexpr BlobVectorCell() : qword_(0) {}
 
- private:
-  union {
-    uint8_t bytes_[8];
-    uint64_t qword_;
-  };
-};
+  static constexpr BlobVectorCell null_value_cell() {
+    return BlobVectorCell();
+  }
+  static BlobVectorCell small_value_cell(const void *ptr, uint64_t length) {
+    BlobVectorCell cell;
+    cell.bytes_[0] = BLOB_VECTOR_SMALL | static_cast<uint8_t>(length);
+    std::memcpy(&cell.bytes_[1], ptr, length);
+    return cell;
+  }
+  static BlobVectorCell medium_value_cell(uint64_t offset, uint64_t length) {
+    BlobVectorCell cell;
+    cell.bytes_[0] = BLOB_VECTOR_MEDIUM | static_cast<uint8_t>(offset >> 40);
+    cell.bytes_[1] = static_cast<uint8_t>(offset >> 32);
+    cell.words_[1] = static_cast<uint16_t>(length);
+    cell.dwords_[1] = static_cast<uint32_t>(offset);
+    return cell;
+  }
+  static BlobVectorCell large_value_cell(uint32_t block_id) {
+    BlobVectorCell cell;
+    cell.bytes_[0] = BLOB_VECTOR_LARGE;
+    cell.dwords_[1] = block_id;
+    return cell;
+  }
 
-class BlobVectorSmallValue {
- public:
-  BlobVectorSmallValue(const void *ptr, uint64_t length,
-                       BlobVectorAttribute attribute) : qword_(0) {
-    bytes_[0] = BLOB_VECTOR_SMALL | attribute |
-                static_cast<uint8_t>(length);
-    std::memcpy(&bytes_[1], ptr, length);
+  BlobVectorValueType type() const {
+    Flags flags;
+    flags.byte = flags_.byte & BLOB_VECTOR_TYPE_MASK;
+    return flags.type;
   }
 
-  uint64_t length() const {
+  // Accessors to small values.
+  uint64_t small_length() const {
     return bytes_[0] & ~BLOB_VECTOR_CELL_FLAGS_MASK;
   }
   const void *value() const {
     return &bytes_[1];
   }
 
- private:
-  union {
-    uint8_t bytes_[8];
-    uint64_t qword_;
-  };
-};
-
-class BlobVectorMediumValue {
- public:
-  BlobVectorMediumValue(uint64_t offset, uint64_t length,
-                        BlobVectorAttribute attribute) : qword_(0) {
-    bytes_[0] = BLOB_VECTOR_MEDIUM | attribute |
-                static_cast<uint8_t>(offset >> 40);
-    bytes_[1] = static_cast<uint8_t>(offset >> 32);
-    words_[1] = static_cast<uint16_t>(length);
-    dwords_[1] = static_cast<uint32_t>(offset);
-  }
-
-  uint64_t length() const {
+  // Accessors to medium values.
+  uint64_t medium_length() const {
     return words_[1];
   }
   uint64_t offset() const {
@@ -297,102 +249,41 @@ class BlobVectorMediumValue {
            (static_cast<uint64_t>(bytes_[1]) << 32) | dwords_[1];
   }
 
- private:
-  union {
-    uint8_t bytes_[8];
-    uint16_t words_[4];
-    uint32_t dwords_[2];
-    uint64_t qword_;
-  };
-};
-
-class BlobVectorLargeValue {
- public:
-  BlobVectorLargeValue(uint32_t block_id,
-                       BlobVectorAttribute attribute) : qword_(0) {
-    bytes_[0] = BLOB_VECTOR_LARGE | attribute;
-    dwords_[1] = block_id;
-  }
-
+  // Accessors to large values.
   uint32_t block_id() const {
     return dwords_[1];
   }
 
  private:
-  union {
-    uint8_t bytes_[8];
-    uint32_t dwords_[2];
-    uint64_t qword_;
-  };
-};
-
-class BlobVectorCell {
- public:
-  BlobVectorCell() : qword_(0) {}
-
-  BlobVectorCell &operator=(const BlobVectorNullValue &rhs) {
-    null_value_ = rhs;
-    return *this;
-  }
-  BlobVectorCell &operator=(const BlobVectorSmallValue &rhs) {
-    small_value_ = rhs;
-    return *this;
-  }
-  BlobVectorCell &operator=(const BlobVectorMediumValue &rhs) {
-    medium_value_ = rhs;
-    return *this;
-  }
-  BlobVectorCell &operator=(const BlobVectorLargeValue &rhs) {
-    large_value_ = rhs;
-    return *this;
-  }
-
-  BlobVectorType type() const {
-    Flags flags;
-    flags.byte = flags_.byte & BLOB_VECTOR_TYPE_MASK;
-    return flags.type;
-  }
-  BlobVectorAttribute attribute() const {
-    Flags flags;
-    flags.byte = flags_.byte & BLOB_VECTOR_ATTRIBUTE_MASK;
-    return flags.attribute;
-  };
-
-  const BlobVectorNullValue &null() const {
-    return null_value_;
-  }
-  const BlobVectorSmallValue &small() const {
-    return small_value_;
-  }
-  const BlobVectorMediumValue &medium() const {
-    return medium_value_;
-  }
-  const BlobVectorLargeValue &large() const {
-    return large_value_;
-  }
-
-  StringBuilder &write_to(StringBuilder &builder) const;
-
- private:
   union Flags {
     uint8_t byte;
-    BlobVectorType type;
-    BlobVectorAttribute attribute;
+    BlobVectorValueType type;
   };
 
   union {
     Flags flags_;
+    uint8_t bytes_[8];
+    uint16_t words_[4];
+    uint32_t dwords_[2];
     uint64_t qword_;
-    BlobVectorNullValue null_value_;
-    BlobVectorSmallValue small_value_;
-    BlobVectorMediumValue medium_value_;
-    BlobVectorLargeValue large_value_;
   };
 };
 
 static_assert(sizeof(BlobVectorCell) == sizeof(uint64_t),
               "sizeof(BlobVectorCell) != sizeof(uint64_t)");
 
+typedef Vector<BlobVectorCell> BlobVectorTable;
+
+typedef Vector<char, BLOB_VECTOR_VALUE_STORE_PAGE_SIZE,
+                     BLOB_VECTOR_VALUE_STORE_TABLE_SIZE,
+                     BLOB_VECTOR_VALUE_STORE_SECONDARY_TABLE_SIZE>
+BlobVectorValueStore;
+
+typedef Vector<BlobVectorPageInfo,
+               BLOB_VECTOR_VALUE_STORE_TABLE_SIZE,
+               BLOB_VECTOR_VALUE_STORE_SECONDARY_TABLE_SIZE>
+BlobVectorIndexStore;
+
 class BlobVectorImpl {
  public:
   static std::unique_ptr<BlobVectorImpl> create(io::Pool pool);
@@ -400,10 +291,7 @@ class BlobVectorImpl {
                                               uint32_t block_id);
 
   const void *get_value(uint64_t id, uint64_t *length);
-
-  void set_value(uint64_t id, const void *ptr, uint64_t length,
-                 uint64_t capacity = 0,
-                 BlobVectorAttribute attribute = BLOB_VECTOR_APPENDABLE);
+  void set_value(uint64_t id, const void *ptr, uint64_t length);
 
   // TODO
 
@@ -420,9 +308,9 @@ class BlobVectorImpl {
   const io::BlockInfo *block_info_;
   BlobVectorHeader *header_;
   Recycler *recycler_;
-  Vector<BlobVectorCell> cells_;
+  BlobVectorTable table_;
   BlobVectorValueStore value_store_;
-  Vector<BlobVectorPageInfo> page_infos_;
+  BlobVectorIndexStore index_store_;
   Mutex inter_thread_mutex_;
 
   BlobVectorImpl();
@@ -430,19 +318,15 @@ class BlobVectorImpl {
   void create_vector(io::Pool pool);
   void open_vector(io::Pool pool, uint32_t block_id);
 
-  BlobVectorMediumValue create_medium_value(
-      uint32_t id, const void *ptr, uint64_t length, uint64_t capacity,
-      BlobVectorAttribute attribute);
-  BlobVectorLargeValue create_large_value(
-      uint32_t id, const void *ptr, uint64_t length, uint64_t capacity,
-      BlobVectorAttribute attribute);
+  BlobVectorCell create_medium_value(const void *ptr, uint64_t length);
+  BlobVectorCell create_large_value(const void *ptr, uint64_t length);
 
   void free_value(BlobVectorCell cell);
 
   void register_large_value(uint32_t block_id,
-                            BlobVectorLargeValueHeader *value_header);
+                            BlobVectorValueHeader *value_header);
   void unregister_large_value(uint32_t block_id,
-                              BlobVectorLargeValueHeader *value_header);
+                              BlobVectorValueHeader *value_header);
 
   void freeze_page(uint32_t page_id);
   void unfreeze_oldest_frozen_page();
-------------- next part --------------
HTML����������������������������...
Download 



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