[Groonga-commit] groonga/grnxx [master] Implement medium values of grnxx::alpha::BlobVector.

Back to archive index

susumu.yata null+****@clear*****
Tue Dec 4 12:42:54 JST 2012


susumu.yata	2012-12-04 12:42:54 +0900 (Tue, 04 Dec 2012)

  New Revision: fde2a9b30d001eca5fe2cd32a1bb2aed6c316677
  https://github.com/groonga/grnxx/commit/fde2a9b30d001eca5fe2cd32a1bb2aed6c316677

  Log:
    Implement medium values of grnxx::alpha::BlobVector.

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

  Modified: lib/alpha/blob_vector.cpp (+125 -84)
===================================================================
--- lib/alpha/blob_vector.cpp    2012-12-04 11:24:13 +0900 (ba74a54)
+++ lib/alpha/blob_vector.cpp    2012-12-04 12:42:54 +0900 (fa9ceb0)
@@ -26,6 +26,8 @@ namespace alpha {
 
 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),
     latest_large_value_block_id_(io::BLOCK_INVALID_ID),
     inter_process_mutex_() {}
 
@@ -109,8 +111,17 @@ const void *BlobVectorImpl::get_value(uint64_t id, uint64_t *length) {
       return cells_[id].small().value();
     }
     case BLOB_VECTOR_MEDIUM: {
-      // TODO: Not implemented yet.
-      return nullptr;
+      if (!value_store_) {
+        Lock lock(mutable_inter_thread_mutex());
+        if (!value_store_) {
+          value_store_ = BlobVectorValueStore(
+              VECTOR_OPEN, pool_, header_->value_store_block_id());
+        }
+      }
+      if (length) {
+        *length = cell.medium().length();
+      }
+      return &value_store_[cell.medium().offset()];
     }
     case BLOB_VECTOR_LARGE: {
       const BlobVectorLargeValueHeader *value_header =
@@ -147,9 +158,9 @@ void BlobVectorImpl::set_value(uint64_t id, const void *ptr, uint64_t 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(ptr, length, capacity, attribute);
+      new_cell = create_medium_value(id, ptr, length, capacity, attribute);
     } else {
-      new_cell = create_large_value(ptr, length, capacity, attribute);
+      new_cell = create_large_value(id, ptr, length, capacity, attribute);
     }
   }
 
@@ -166,17 +177,121 @@ void BlobVectorImpl::set_value(uint64_t id, const void *ptr, uint64_t length,
   free_value(old_cell);
 }
 
+StringBuilder &BlobVectorImpl::write_to(StringBuilder &builder) const {
+  if (!builder) {
+    return builder;
+  }
+
+  // TODO
+  return builder;
+}
+
+void BlobVectorImpl::unlink(io::Pool pool, uint32_t block_id) {
+  std::unique_ptr<BlobVectorImpl> vector =
+      BlobVectorImpl::open(pool, 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 *>(
+          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());
+  pool.free_block(vector->block_info_->id());
+}
+
+BlobVectorImpl::BlobVectorImpl()
+  : pool_(),
+    block_info_(nullptr),
+    header_(nullptr),
+    recycler_(nullptr),
+    cells_(),
+    value_store_(),
+    inter_thread_mutex_() {}
+
+void BlobVectorImpl::create_vector(io::Pool pool) {
+  pool_ = pool;
+  block_info_ = pool.create_block(sizeof(BlobVectorHeader));
+
+  try {
+    cells_ = Vector<BlobVectorCell>(VECTOR_CREATE, pool_, BlobVectorCell());
+  } catch (...) {
+    pool_.free_block(*block_info_);
+    throw;
+  }
+
+  void * const block_address = pool_.get_block_address(*block_info_);
+  header_ = static_cast<BlobVectorHeader *>(block_address);
+  *header_ = BlobVectorHeader(cells_.block_id());
+
+  recycler_ = pool.mutable_recycler();
+}
+
+void BlobVectorImpl::open_vector(io::Pool pool, uint32_t block_id) {
+  pool_ = pool;
+  block_info_ = pool.get_block_info(block_id);
+  if (block_info_->size() < sizeof(BlobVectorHeader)) {
+    GRNXX_ERROR() << "invalid argument: block_info = " << *block_info_
+                  << ", header_size = " << sizeof(BlobVectorHeader);
+    GRNXX_THROW();
+  }
+
+  void * const block_address = pool_.get_block_address(*block_info_);
+  header_ = static_cast<BlobVectorHeader *>(block_address);
+
+  // TODO: Check the format!
+
+  recycler_ = pool.mutable_recycler();
+
+  // Open the core table.
+  cells_ = Vector<BlobVectorCell>(VECTOR_OPEN, pool,
+                                  header_->cells_block_id());
+}
+
 BlobVectorMediumValue BlobVectorImpl::create_medium_value(
-    const void *ptr, uint64_t length, uint64_t capacity,
+    uint32_t id, const void *ptr, uint64_t length, uint64_t capacity,
     BlobVectorAttribute attribute) {
-  // TODO: Not implemented yet.
-  capacity = (capacity + (BLOB_VECTOR_MEDIUM_VALUE_UNIT_SIZE - 1)) &
-      ~(BLOB_VECTOR_MEDIUM_VALUE_UNIT_SIZE - 1);
-  return BlobVectorMediumValue(0, length, attribute);
+  if (!value_store_) {
+    Lock lock(mutable_inter_thread_mutex());
+    if (!value_store_) {
+      value_store_ = BlobVectorValueStore(
+          VECTOR_OPEN, pool_, header_->value_store_block_id());
+    }
+  }
+
+  // TODO: Lock.
+
+  capacity = (capacity + (BLOB_VECTOR_UNIT_SIZE - 1)) &
+      ~(BLOB_VECTOR_UNIT_SIZE - 1);
+
+  uint64_t offset = header_->next_medium_value_offset();
+  const uint64_t offset_in_page =
+      offset & (BLOB_VECTOR_VALUE_STORE_PAGE_SIZE - 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;
+  }
+  header_->set_next_medium_value_offset(offset + required_size);
+
+  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);
+
+  return BlobVectorMediumValue(offset, length, attribute);
 }
 
 BlobVectorLargeValue BlobVectorImpl::create_large_value(
-    const void *ptr, uint64_t length, uint64_t capacity,
+    uint32_t, const void *ptr, uint64_t length, uint64_t capacity,
     BlobVectorAttribute attribute) {
   const io::BlockInfo *block_info =
       pool_.create_block(sizeof(BlobVectorLargeValueHeader) + capacity);
@@ -247,79 +362,5 @@ void BlobVectorImpl::unregister_large_value(uint32_t block_id,
   }
 }
 
-StringBuilder &BlobVectorImpl::write_to(StringBuilder &builder) const {
-  if (!builder) {
-    return builder;
-  }
-
-  // TODO
-  return builder;
-}
-
-void BlobVectorImpl::unlink(io::Pool pool, uint32_t block_id) {
-  std::unique_ptr<BlobVectorImpl> vector =
-      BlobVectorImpl::open(pool, 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 *>(
-          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());
-  pool.free_block(vector->block_info_->id());
-}
-
-BlobVectorImpl::BlobVectorImpl()
-  : pool_(),
-    block_info_(nullptr),
-    header_(nullptr),
-    recycler_(nullptr),
-    cells_(),
-    inter_thread_mutex_() {}
-
-void BlobVectorImpl::create_vector(io::Pool pool) {
-  pool_ = pool;
-  block_info_ = pool.create_block(sizeof(BlobVectorHeader));
-
-  try {
-    cells_ = Vector<BlobVectorCell>(VECTOR_CREATE, pool_, BlobVectorCell());
-  } catch (...) {
-    pool_.free_block(*block_info_);
-    throw;
-  }
-
-  void * const block_address = pool_.get_block_address(*block_info_);
-  header_ = static_cast<BlobVectorHeader *>(block_address);
-  *header_ = BlobVectorHeader(cells_.block_id());
-
-  recycler_ = pool.mutable_recycler();
-}
-
-void BlobVectorImpl::open_vector(io::Pool pool, uint32_t block_id) {
-  pool_ = pool;
-  block_info_ = pool.get_block_info(block_id);
-  if (block_info_->size() < sizeof(BlobVectorHeader)) {
-    GRNXX_ERROR() << "invalid argument: block_info = " << *block_info_
-                  << ", header_size = " << sizeof(BlobVectorHeader);
-    GRNXX_THROW();
-  }
-
-  void * const block_address = pool_.get_block_address(*block_info_);
-  header_ = static_cast<BlobVectorHeader *>(block_address);
-
-  // TODO: Check the format!
-
-  recycler_ = pool.mutable_recycler();
-
-  // Open the core table.
-  cells_ = Vector<BlobVectorCell>(VECTOR_OPEN, pool,
-                                  header_->cells_block_id());
-}
-
 }  // namespace alpha
 }  // namespace grnxx

  Modified: lib/alpha/blob_vector.hpp (+39 -26)
===================================================================
--- lib/alpha/blob_vector.hpp    2012-12-04 11:24:13 +0900 (a7f8dd0)
+++ lib/alpha/blob_vector.hpp    2012-12-04 12:42:54 +0900 (67de484)
@@ -34,25 +34,25 @@ const uint64_t BLOB_VECTOR_MEDIUM_VALUE_MAX_LENGTH = 65535;
 const uint64_t BLOB_VECTOR_LARGE_VALUE_MIN_LENGTH  =
     BLOB_VECTOR_MEDIUM_VALUE_MAX_LENGTH + 1;
 
-const uint8_t  BLOB_VECTOR_MEDIUM_VALUE_UNIT_SIZE_BITS  = 3;
-const uint64_t BLOB_VECTOR_MEDIUM_VALUE_UNIT_SIZE       =
-    uint64_t(1) << BLOB_VECTOR_MEDIUM_VALUE_UNIT_SIZE_BITS;
-
-//const uint8_t  BLOB_VECTOR_MEDIUM_VALUE_STORE_PAGE_SIZE_BITS            = 19;
-//const uint8_t  BLOB_VECTOR_MEDIUM_VALUE_STORE_TABLE_SIZE_BITS           = 12;
-//const uint8_t  BLOB_VECTOR_MEDIUM_VALUE_STORE_SECONDARY_TABLE_SIZE_BITS = 16;
-
-//const uint64_t BLOB_VECTOR_MEDIUM_VALUE_STORE_PAGE_SIZE            =
-//    uint64_t(1) << BLOB_VECTOR_MEDIUM_VALUE_STORE_PAGE_SIZE_BITS;
-//const uint64_t BLOB_VECTOR_MEDIUM_VALUE_STORE_TABLE_SIZE           =
-//    uint64_t(1) << BLOB_VECTOR_MEDIUM_VALUE_STORE_TABLE_SIZE_BITS;
-//const uint64_t BLOB_VECTOR_MEDIUM_VALUE_STORE_SECONDARY_TABLE_SIZE =
-//    uint64_t(1) << BLOB_VECTOR_MEDIUM_VALUE_STORE_SECONDARY_TABLE_SIZE_BITS;
-
-//typedef Vector<char, BLOB_VECTOR_MEDIUM_VALUE_STORE_PAGE_SIZE,
-//                     BLOB_VECTOR_MEDIUM_VALUE_STORE_TABLE_SIZE,
-//                     BLOB_VECTOR_MEDIUM_VALUE_STORE_SECONDARY_TABLE_SIZE>
-//BlobVectorMediumValueStore;
+const uint8_t  BLOB_VECTOR_UNIT_SIZE_BITS  = 3;
+const uint64_t BLOB_VECTOR_UNIT_SIZE       =
+    uint64_t(1) << BLOB_VECTOR_UNIT_SIZE_BITS;
+
+const uint8_t  BLOB_VECTOR_VALUE_STORE_PAGE_SIZE_BITS            = 19;
+const uint8_t  BLOB_VECTOR_VALUE_STORE_TABLE_SIZE_BITS           = 12;
+const uint8_t  BLOB_VECTOR_VALUE_STORE_SECONDARY_TABLE_SIZE_BITS = 16;
+
+const uint64_t BLOB_VECTOR_VALUE_STORE_PAGE_SIZE            =
+    uint64_t(1) << BLOB_VECTOR_VALUE_STORE_PAGE_SIZE_BITS;
+const uint64_t BLOB_VECTOR_VALUE_STORE_TABLE_SIZE           =
+    uint64_t(1) << BLOB_VECTOR_VALUE_STORE_TABLE_SIZE_BITS;
+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;
@@ -64,10 +64,22 @@ class BlobVectorHeader {
   uint32_t cells_block_id() const {
     return cells_block_id_;
   }
+  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 latest_large_value_block_id() const {
     return latest_large_value_block_id_;
   }
 
+  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_latest_large_value_block_id(uint32_t value) {
     latest_large_value_block_id_ = value;
   }
@@ -78,6 +90,8 @@ class BlobVectorHeader {
 
  private:
   uint32_t cells_block_id_;
+  uint32_t value_store_block_id_;
+  uint64_t next_medium_value_offset_;
   uint32_t latest_large_value_block_id_;
   Mutex inter_process_mutex_;
 };
@@ -85,7 +99,7 @@ class BlobVectorHeader {
 enum BlobVectorType : uint8_t {
   BLOB_VECTOR_NULL   = 0x00,
   BLOB_VECTOR_SMALL  = 0x10,
-  BLOB_VECTOR_MEDIUM = 0x20,  // TODO: Not implemented yet.
+  BLOB_VECTOR_MEDIUM = 0x20,
   BLOB_VECTOR_LARGE  = 0x30
 };
 
@@ -99,8 +113,7 @@ class BlobVectorMediumValueHeader {
     return dwords_[0] | (static_cast<uint64_t>(bytes_[4]) << 32);
   }
   uint64_t capacity() const {
-    return static_cast<uint64_t>(words_[3])
-        << BLOB_VECTOR_MEDIUM_VALUE_UNIT_SIZE_BITS;
+    return static_cast<uint64_t>(words_[3]) << BLOB_VECTOR_UNIT_SIZE_BITS;
   }
 
   void set_value_id(uint64_t value) {
@@ -108,8 +121,7 @@ class BlobVectorMediumValueHeader {
     bytes_[4] = static_cast<uint8_t>(value >> 32);
   }
   void set_capacity(uint64_t value) {
-    words_[3] = static_cast<uint16_t>(
-        value >> BLOB_VECTOR_MEDIUM_VALUE_UNIT_SIZE_BITS);
+    words_[3] = static_cast<uint16_t>(value >> BLOB_VECTOR_UNIT_SIZE_BITS);
   }
 
  private:
@@ -342,6 +354,7 @@ class BlobVectorImpl {
   BlobVectorHeader *header_;
   Recycler *recycler_;
   Vector<BlobVectorCell> cells_;
+  BlobVectorValueStore value_store_;
   Mutex inter_thread_mutex_;
 
   BlobVectorImpl();
@@ -350,10 +363,10 @@ class BlobVectorImpl {
   void open_vector(io::Pool pool, uint32_t block_id);
 
   BlobVectorMediumValue create_medium_value(
-      const void *ptr, uint64_t length, uint64_t capacity,
+      uint32_t id, const void *ptr, uint64_t length, uint64_t capacity,
       BlobVectorAttribute attribute);
   BlobVectorLargeValue create_large_value(
-      const void *ptr, uint64_t length, uint64_t capacity,
+      uint32_t id, const void *ptr, uint64_t length, uint64_t capacity,
       BlobVectorAttribute attribute);
 
   void free_value(BlobVectorCell cell);
-------------- next part --------------
HTML����������������������������...
Download 



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