[Groonga-commit] groonga/grnxx at 75e881c [master] Add exclusive access control.

Back to archive index

susumu.yata null+****@clear*****
Mon Apr 29 19:46:58 JST 2013


susumu.yata	2013-04-29 19:46:58 +0900 (Mon, 29 Apr 2013)

  New Revision: 75e881c5dbe3bd13d114a662817db38ca7f8019c
  https://github.com/groonga/grnxx/commit/75e881c5dbe3bd13d114a662817db38ca7f8019c

  Message:
    Add exclusive access control.

  Modified files:
    lib/grnxx/storage.hpp
    lib/grnxx/storage/header.cpp
    lib/grnxx/storage/header.hpp
    lib/grnxx/storage/storage_impl.cpp
    lib/grnxx/storage/storage_impl.hpp

  Modified: lib/grnxx/storage.hpp (+2 -3)
===================================================================
--- lib/grnxx/storage.hpp    2013-04-28 23:01:48 +0900 (54452a1)
+++ lib/grnxx/storage.hpp    2013-04-29 19:46:58 +0900 (3d30255)
@@ -160,7 +160,8 @@ class Storage {
   virtual bool unlink_node(uint32_t node_id) = 0;
 
   // Sweep marked nodes whose last modified time < (now - lifetime).
-  virtual bool sweep(Duration lifetime) = 0;
+  virtual bool sweep(Duration lifetime,
+                     uint32_t root_node_id = STORAGE_ROOT_NODE_ID) = 0;
 
   // Return the storage path.
   // Note that an anonymous or temporary storage may return nullptr.
@@ -173,8 +174,6 @@ class Storage {
   virtual uint16_t max_num_files() const = 0;
   // Return the total size.
   virtual uint64_t total_size() const = 0;
-
-  // TODO: Member functions to get details, such as total size, #nodes, etc.
 };
 
 }  // namespace grnxx

  Modified: lib/grnxx/storage/header.cpp (+2 -2)
===================================================================
--- lib/grnxx/storage/header.cpp    2013-04-28 23:01:48 +0900 (f3e9251)
+++ lib/grnxx/storage/header.cpp    2013-04-29 19:46:58 +0900 (add40f9)
@@ -44,8 +44,8 @@ Header::Header()
       latest_phantom_node_id(STORAGE_INVALID_NODE_ID),
       latest_unlinked_node_id(STORAGE_INVALID_NODE_ID),
       oldest_idle_node_ids(),
-      inter_process_data_mutex(MUTEX_UNLOCKED),
-      inter_process_file_mutex(MUTEX_UNLOCKED),
+      data_mutex(MUTEX_UNLOCKED),
+      file_mutex(MUTEX_UNLOCKED),
       reserved{} {
   std::memcpy(version, GRNXX_STORAGE_HEADER_VERSION, HEADER_VERSION_SIZE);
   for (size_t i = 0; i < NUM_IDLE_NODE_LISTS; ++i) {

  Modified: lib/grnxx/storage/header.hpp (+2 -2)
===================================================================
--- lib/grnxx/storage/header.hpp    2013-04-28 23:01:48 +0900 (1988371)
+++ lib/grnxx/storage/header.hpp    2013-04-29 19:46:58 +0900 (257c86e)
@@ -60,9 +60,9 @@ struct Header {
   // The IDs of the oldest idle nodes.
   uint32_t oldest_idle_node_ids[NUM_IDLE_NODE_LISTS];
   // A mutex object for exclusively updating data.
-  Mutex inter_process_data_mutex;
+  Mutex data_mutex;
   // A mutex object for exclusively update files.
-  Mutex inter_process_file_mutex;
+  Mutex file_mutex;
   uint8_t reserved[148];
 
   // Initialize the members except "format".

  Modified: lib/grnxx/storage/storage_impl.cpp (+70 -21)
===================================================================
--- lib/grnxx/storage/storage_impl.cpp    2013-04-28 23:01:48 +0900 (d790c82)
+++ lib/grnxx/storage/storage_impl.cpp    2013-04-29 19:46:58 +0900 (ce6486a)
@@ -18,6 +18,7 @@
 #include "grnxx/storage/storage_impl.hpp"
 
 #include "grnxx/intrinsic.hpp"
+#include "grnxx/lock.hpp"
 #include "grnxx/logger.hpp"
 #include "grnxx/slice.hpp"
 #include "grnxx/storage/chunk.hpp"
@@ -67,6 +68,7 @@ StorageImpl::StorageImpl()
       header_chunk_(),
       node_header_chunks_(),
       node_body_chunks_(),
+      mutex_(MUTEX_UNLOCKED),
       clock_() {}
 
 StorageImpl::~StorageImpl() {}
@@ -176,6 +178,7 @@ StorageNode StorageImpl::create_node(uint32_t parent_node_id, uint64_t size) {
   if (!parent_node_header) {
     return StorageNode(nullptr);
   }
+  Lock lock(&header_->data_mutex);
   NodeHeader * const node_header = create_active_node(size);
   if (!node_header) {
     return StorageNode(nullptr);
@@ -220,9 +223,13 @@ bool StorageImpl::unlink_node(uint32_t node_id) {
   return true;
 }
 
-bool StorageImpl::sweep(Duration lifetime) {
-  // TODO
-  return false;
+bool StorageImpl::sweep(Duration lifetime, uint32_t root_node_id) {
+  Lock lock(&header_->data_mutex);
+  NodeHeader * const node_header = get_node_header(root_node_id);
+  if (!node_header) {
+    return false;
+  }
+  return sweep_subtree(clock_.now() - lifetime, node_header);
 }
 
 const char *StorageImpl::path() const {
@@ -619,6 +626,27 @@ bool StorageImpl::associate_node_with_chunk(NodeHeader *node_header,
   return true;
 }
 
+bool StorageImpl::sweep_subtree(Time threshold, NodeHeader *node_header) {
+  if (node_header->status == STORAGE_NODE_MARKED) {
+    if (node_header->modified_time <= threshold) {
+      // TODO: Unlink the node.
+      return true;
+    }
+  }
+  uint32_t node_id = node_header->child_node_id;
+  while (node_id != STORAGE_INVALID_NODE_ID) {
+    node_header = get_node_header(node_id);
+    if (!node_header) {
+      return false;
+    }
+    if (!sweep_subtree(threshold, node_header)) {
+      return false;
+    }
+    node_id = node_header->sibling_node_id;
+  }
+  return true;
+}
+
 ChunkIndex *StorageImpl::create_node_header_chunk(
     ChunkIndex **remainder_chunk_index) {
   if (header_->num_nodes > MAX_NODE_ID) {
@@ -808,8 +836,11 @@ Chunk *StorageImpl::get_node_header_chunk(uint16_t chunk_id) {
   if (!node_header_chunks_[chunk_id]) {
     const ChunkIndex &chunk_index = node_header_chunk_indexes_[chunk_id];
     if (flags_ & STORAGE_ANONYMOUS) {
-      node_header_chunks_[chunk_id].reset(
-          create_chunk(nullptr, chunk_index.offset, chunk_index.size));
+      Lock lock(&mutex_);
+      if (!node_header_chunks_[chunk_id]) {
+        node_header_chunks_[chunk_id].reset(
+            create_chunk(nullptr, chunk_index.offset, chunk_index.size));
+      }
     } else {
       File * const file = get_file(chunk_index.file_id);
       if (!file) {
@@ -817,12 +848,18 @@ Chunk *StorageImpl::get_node_header_chunk(uint16_t chunk_id) {
       }
       const int64_t required_size = chunk_index.offset + chunk_index.size;
       if (file->size() < required_size) {
-        if (!file->resize(required_size)) {
-          return nullptr;
+        Lock file_lock(&header_->file_mutex);
+        if (file->size() < required_size) {
+          if (!file->resize(required_size)) {
+            return nullptr;
+          }
         }
       }
-      node_header_chunks_[chunk_id].reset(
-          create_chunk(file, chunk_index.offset, chunk_index.size));
+      Lock lock(&mutex_);
+      if (!node_header_chunks_[chunk_id]) {
+        node_header_chunks_[chunk_id].reset(
+            create_chunk(file, chunk_index.offset, chunk_index.size));
+      }
     }
   }
   return node_header_chunks_[chunk_id].get();
@@ -832,8 +869,11 @@ Chunk *StorageImpl::get_node_body_chunk(uint16_t chunk_id) {
   if (!node_body_chunks_[chunk_id]) {
     const ChunkIndex &chunk_index = node_body_chunk_indexes_[chunk_id];
     if (flags_ & STORAGE_ANONYMOUS) {
-      node_body_chunks_[chunk_id].reset(
-          create_chunk(nullptr, chunk_index.offset, chunk_index.size));
+      Lock lock(&mutex_);
+      if (!node_body_chunks_[chunk_id]) {
+        node_body_chunks_[chunk_id].reset(
+            create_chunk(nullptr, chunk_index.offset, chunk_index.size));
+      }
     } else {
       File * const file = get_file(chunk_index.file_id);
       if (!file) {
@@ -841,12 +881,18 @@ Chunk *StorageImpl::get_node_body_chunk(uint16_t chunk_id) {
       }
       const int64_t required_size = chunk_index.offset + chunk_index.size;
       if (file->size() < required_size) {
-        if (!file->resize(required_size)) {
-          return nullptr;
+        Lock file_lock(&header_->file_mutex);
+        if (file->size() < required_size) {
+          if (!file->resize(required_size)) {
+            return nullptr;
+          }
         }
       }
-      node_body_chunks_[chunk_id].reset(
-          create_chunk(file, chunk_index.offset, chunk_index.size));
+      Lock lock(&mutex_);
+      if (!node_body_chunks_[chunk_id]) {
+        node_body_chunks_[chunk_id].reset(
+            create_chunk(file, chunk_index.offset, chunk_index.size));
+      }
     }
   }
   return node_body_chunks_[chunk_id].get();
@@ -860,12 +906,15 @@ File *StorageImpl::get_file(uint16_t file_id) {
       std::unique_ptr<char[]> path(generate_path(file_id));
       files_[file_id].reset(File::open(path.get(), file_flags));
     } else {
-      if (flags_ & STORAGE_TEMPORARY) {
-        file_flags |= FILE_TEMPORARY;
-        files_[file_id].reset(File::create(path_.get(), file_flags));
-      } else {
-        std::unique_ptr<char[]> path(generate_path(file_id));
-        files_[file_id].reset(File::open_or_create(path.get(), file_flags));
+      Lock file_lock(&header_->file_mutex);
+      if (!files_[file_id]) {
+        if (flags_ & STORAGE_TEMPORARY) {
+          file_flags |= FILE_TEMPORARY;
+          files_[file_id].reset(File::create(path_.get(), file_flags));
+        } else {
+          std::unique_ptr<char[]> path(generate_path(file_id));
+          files_[file_id].reset(File::open_or_create(path.get(), file_flags));
+        }
       }
     }
   }

  Modified: lib/grnxx/storage/storage_impl.hpp (+5 -3)
===================================================================
--- lib/grnxx/storage/storage_impl.hpp    2013-04-28 23:01:48 +0900 (8186144)
+++ lib/grnxx/storage/storage_impl.hpp    2013-04-29 19:46:58 +0900 (d89819c)
@@ -18,6 +18,7 @@
 #ifndef GRNXX_STORAGE_STORAGE_IMPL_HPP
 #define GRNXX_STORAGE_STORAGE_IMPL_HPP
 
+#include "grnxx/mutex.hpp"
 #include "grnxx/storage.hpp"
 #include "grnxx/time/periodic_clock.hpp"
 
@@ -51,7 +52,7 @@ class StorageImpl : public Storage {
 
   bool unlink_node(uint32_t node_id);
 
-  bool sweep(Duration lifetime);
+  bool sweep(Duration lifetime, uint32_t root_node_id);
 
   const char *path() const;
   StorageFlags flags() const;
@@ -59,8 +60,6 @@ class StorageImpl : public Storage {
   uint16_t max_num_files() const;
   uint64_t total_size() const;
 
-  // TODO: Member functions to get details, such as total size, #nodes, etc.
-
  private:
   std::unique_ptr<char[]> path_;
   StorageFlags flags_;
@@ -71,6 +70,7 @@ class StorageImpl : public Storage {
   std::unique_ptr<Chunk> header_chunk_;
   std::unique_ptr<std::unique_ptr<Chunk>[]> node_header_chunks_;
   std::unique_ptr<std::unique_ptr<Chunk>[]> node_body_chunks_;
+  Mutex mutex_;
   PeriodicClock clock_;
 
   bool create_file_backed_storage(const char *path, StorageFlags flags,
@@ -99,6 +99,8 @@ class StorageImpl : public Storage {
                                      ChunkIndex **remainder_chunk_index);
   ChunkIndex *create_node_body_chunk(uint64_t size);
 
+  bool sweep_subtree(Time threshold, NodeHeader *node_header);
+
   bool register_idle_node(NodeHeader *node_header);
   bool unregister_idle_node(NodeHeader *node_header);
 
-------------- next part --------------
HTML����������������������������...
Download 



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