[Groonga-commit] groonga/grnxx [master] Implement grnxx::alpha::BlobVector::unlink().

アーカイブの一覧に戻る

susumu.yata null+****@clear*****
Mon Dec 3 17:40:38 JST 2012


susumu.yata	2012-12-03 17:40:38 +0900 (Mon, 03 Dec 2012)

  New Revision: 92102334642df1462de058f25209de271e7cc037
  https://github.com/groonga/grnxx/commit/92102334642df1462de058f25209de271e7cc037

  Log:
    Implement grnxx::alpha::BlobVector::unlink().

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

  Modified: lib/alpha/blob_vector.cpp (+71 -10)
===================================================================
--- lib/alpha/blob_vector.cpp    2012-12-01 18:21:16 +0900 (8448216)
+++ lib/alpha/blob_vector.cpp    2012-12-03 17:40:38 +0900 (ba74a54)
@@ -26,6 +26,7 @@ namespace alpha {
 
 BlobVectorHeader::BlobVectorHeader(uint32_t cells_block_id)
   : cells_block_id_(cells_block_id),
+    latest_large_value_block_id_(io::BLOCK_INVALID_ID),
     inter_process_mutex_() {}
 
 StringBuilder &operator<<(StringBuilder &builder, BlobVectorType type) {
@@ -112,12 +113,13 @@ const void *BlobVectorImpl::get_value(uint64_t id, uint64_t *length) {
       return nullptr;
     }
     case BLOB_VECTOR_LARGE: {
-      void * const block_address =
-          pool_.get_block_address(cell.large().block_id());
+      const BlobVectorLargeValueHeader *value_header =
+          static_cast<const BlobVectorLargeValueHeader *>(
+              pool_.get_block_address(cell.large().block_id()));
       if (length) {
-        *length = *static_cast<uint64_t *>(block_address);
+        *length = value_header->length();
       }
-      return static_cast<uint64_t *>(block_address) + 1;
+      return value_header + 1;
     }
     default: {
       GRNXX_ERROR() << "invalid value type";
@@ -177,10 +179,13 @@ BlobVectorLargeValue BlobVectorImpl::create_large_value(
     const void *ptr, uint64_t length, uint64_t capacity,
     BlobVectorAttribute attribute) {
   const io::BlockInfo *block_info =
-      pool_.create_block(sizeof(uint64_t) + capacity);
-  void * const block_address = pool_.get_block_address(*block_info);
-  *static_cast<uint64_t *>(block_address) = length;
-  std::memcpy(static_cast<uint64_t *>(block_address) + 1, ptr, length);
+      pool_.create_block(sizeof(BlobVectorLargeValueHeader) + capacity);
+  BlobVectorLargeValueHeader *value_header =
+      static_cast<BlobVectorLargeValueHeader *>(
+          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);
 }
 
@@ -194,12 +199,54 @@ void BlobVectorImpl::free_value(BlobVectorCell cell) {
       break;
     }
     case BLOB_VECTOR_LARGE: {
-      pool_.free_block(cell.large().block_id());
+      const io::BlockInfo * const block_info =
+          pool_.get_block_info(cell.large().block_id());
+      unregister_large_value(block_info->id(),
+          static_cast<BlobVectorLargeValueHeader *>(
+              pool_.get_block_address(*block_info)));
+      pool_.free_block(*block_info);
       break;
     }
   }
 }
 
+void BlobVectorImpl::register_large_value(uint32_t block_id,
+    BlobVectorLargeValueHeader *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 *>(
+        pool_.get_block_address(prev_id));
+    const uint32_t next_id = prev_header->next_value_block_id();
+    auto next_header = static_cast<BlobVectorLargeValueHeader *>(
+        pool_.get_block_address(next_id));
+    value_header->set_next_value_block_id(next_id);
+    value_header->set_prev_value_block_id(prev_id);
+    prev_header->set_next_value_block_id(block_id);
+    next_header->set_prev_value_block_id(block_id);
+  }
+  header_->set_latest_large_value_block_id(block_id);
+}
+
+void BlobVectorImpl::unregister_large_value(uint32_t block_id,
+    BlobVectorLargeValueHeader *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 *>(
+      pool_.get_block_address(next_id));
+  auto prev_header = static_cast<BlobVectorLargeValueHeader *>(
+      pool_.get_block_address(prev_id));
+  next_header->set_prev_value_block_id(prev_id);
+  prev_header->set_next_value_block_id(next_id);
+  if (block_id == header_->latest_large_value_block_id()) {
+    header_->set_latest_large_value_block_id(prev_id);
+  }
+}
+
 StringBuilder &BlobVectorImpl::write_to(StringBuilder &builder) const {
   if (!builder) {
     return builder;
@@ -210,7 +257,21 @@ StringBuilder &BlobVectorImpl::write_to(StringBuilder &builder) const {
 }
 
 void BlobVectorImpl::unlink(io::Pool pool, uint32_t block_id) {
-  // TODO
+  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()

  Modified: lib/alpha/blob_vector.hpp (+48 -0)
===================================================================
--- lib/alpha/blob_vector.hpp    2012-12-01 18:21:16 +0900 (37f6d9c)
+++ lib/alpha/blob_vector.hpp    2012-12-03 17:40:38 +0900 (e4c7109)
@@ -64,6 +64,13 @@ class BlobVectorHeader {
   uint32_t cells_block_id() const {
     return cells_block_id_;
   }
+  uint32_t latest_large_value_block_id() const {
+    return latest_large_value_block_id_;
+  }
+
+  void set_latest_large_value_block_id(uint32_t value) {
+    latest_large_value_block_id_ = value;
+  }
 
   Mutex *mutable_inter_process_mutex() {
     return &inter_process_mutex_;
@@ -71,6 +78,7 @@ class BlobVectorHeader {
 
  private:
   uint32_t cells_block_id_;
+  uint32_t latest_large_value_block_id_;
   Mutex inter_process_mutex_;
 };
 
@@ -85,6 +93,34 @@ const uint8_t BLOB_VECTOR_TYPE_MASK = 0x30;
 
 StringBuilder &operator<<(StringBuilder &builder, BlobVectorType type);
 
+class BlobVectorLargeValueHeader {
+ public:
+  uint64_t length() const {
+    return length_;
+  }
+  uint32_t next_value_block_id() const {
+    return next_value_block_id_;
+  }
+  uint32_t prev_value_block_id() const {
+    return prev_value_block_id_;
+  }
+
+  void set_length(uint64_t value) {
+    length_ = value;
+  }
+  void set_next_value_block_id(uint32_t value) {
+    next_value_block_id_ = value;
+  }
+  void set_prev_value_block_id(uint32_t value) {
+    prev_value_block_id_ = value;
+  }
+
+ private:
+  uint64_t length_;
+  uint32_t next_value_block_id_;
+  uint32_t prev_value_block_id_;
+};
+
 // TODO: Not implemented yet.
 enum BlobVectorAttribute : uint8_t {
   BLOB_VECTOR_APPENDABLE  = 0x00,
@@ -294,6 +330,18 @@ class BlobVectorImpl {
       BlobVectorAttribute attribute);
 
   void free_value(BlobVectorCell cell);
+
+  void register_large_value(uint32_t block_id,
+                            BlobVectorLargeValueHeader *value_header);
+  void unregister_large_value(uint32_t block_id,
+                              BlobVectorLargeValueHeader *value_header);
+
+  Mutex *mutable_inter_thread_mutex() {
+    return &inter_thread_mutex_;
+  }
+  Mutex *mutable_inter_process_mutex() {
+    return header_->mutable_inter_process_mutex();
+  }
 };
 
 inline StringBuilder &operator<<(StringBuilder &builder,
-------------- next part --------------
HTML����������������������������...
ダウンロード 



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