Blame SOURCES/0002-Added-a-DB-SuspendCompations-and-DB-ResumeCompaction.patch

2d5d9c
From: Hiram Chirino <hiram@hiramchirino.com>
2d5d9c
Date: Tue, 30 Oct 2012 16:56:52 -0400
2d5d9c
Subject: [PATCH] Added a DB:SuspendCompations() and DB:ResumeCompactions()
2d5d9c
 methods. Fixes issue #184
2d5d9c
2d5d9c
https://code.google.com/p/leveldb/issues/detail?id=184
2d5d9c
2d5d9c
diff --git a/db/db_impl.cc b/db/db_impl.cc
2d5d9c
index 1a4e459..ae7b96d 100644
2d5d9c
--- a/db/db_impl.cc
2d5d9c
+++ b/db/db_impl.cc
2d5d9c
@@ -135,6 +135,9 @@ DBImpl::DBImpl(const Options& raw_options, const std::string& dbname)
2d5d9c
       table_cache_(new TableCache(dbname_, options_, TableCacheSize(options_))),
2d5d9c
       db_lock_(nullptr),
2d5d9c
       shutting_down_(false),
2d5d9c
+      suspend_cv(&suspend_mutex),
2d5d9c
+      suspend_count(0),
2d5d9c
+      suspended(false),
2d5d9c
       background_work_finished_signal_(&mutex_),
2d5d9c
       mem_(nullptr),
2d5d9c
       imm_(nullptr),
2d5d9c
@@ -1464,6 +1467,39 @@ void DBImpl::GetApproximateSizes(const Range* range, int n, uint64_t* sizes) {
2d5d9c
   v->Unref();
2d5d9c
 }
2d5d9c
 
2d5d9c
+void DBImpl::SuspendCompactions() {
2d5d9c
+  MutexLock l(& suspend_mutex);
2d5d9c
+  env_->Schedule(&SuspendWork, this);
2d5d9c
+  suspend_count++;
2d5d9c
+  while( !suspended ) {
2d5d9c
+    suspend_cv.Wait();
2d5d9c
+  }
2d5d9c
+}
2d5d9c
+void DBImpl::SuspendWork(void* db) {
2d5d9c
+  reinterpret_cast<DBImpl*>(db)->SuspendCallback();
2d5d9c
+}
2d5d9c
+void DBImpl::SuspendCallback() {
2d5d9c
+    MutexLock l(&suspend_mutex);
2d5d9c
+    Log(options_.info_log, "Compactions suspended");
2d5d9c
+    suspended = true;
2d5d9c
+    suspend_cv.SignalAll();
2d5d9c
+    while( suspend_count > 0 ) {
2d5d9c
+        suspend_cv.Wait();
2d5d9c
+    }
2d5d9c
+    suspended = false;
2d5d9c
+    suspend_cv.SignalAll();
2d5d9c
+    Log(options_.info_log, "Compactions resumed");
2d5d9c
+}
2d5d9c
+void DBImpl::ResumeCompactions() {
2d5d9c
+    MutexLock l(&suspend_mutex);
2d5d9c
+    suspend_count--;
2d5d9c
+    suspend_cv.SignalAll();
2d5d9c
+    while( suspended ) {
2d5d9c
+      suspend_cv.Wait();
2d5d9c
+    }
2d5d9c
+}
2d5d9c
+
2d5d9c
+
2d5d9c
 // Default implementations of convenience methods that subclasses of DB
2d5d9c
 // can call if they wish
2d5d9c
 Status DB::Put(const WriteOptions& opt, const Slice& key, const Slice& value) {
2d5d9c
diff --git a/db/db_impl.h b/db/db_impl.h
2d5d9c
index c7b0172..d955c2a 100644
2d5d9c
--- a/db/db_impl.h
2d5d9c
+++ b/db/db_impl.h
2d5d9c
@@ -48,6 +48,8 @@ class DBImpl : public DB {
2d5d9c
   bool GetProperty(const Slice& property, std::string* value) override;
2d5d9c
   void GetApproximateSizes(const Range* range, int n, uint64_t* sizes) override;
2d5d9c
   void CompactRange(const Slice* begin, const Slice* end) override;
2d5d9c
+  void SuspendCompactions() override;
2d5d9c
+  void ResumeCompactions() override;
2d5d9c
 
2d5d9c
   // Extra methods (for testing) that are not in the public DB interface
2d5d9c
 
2d5d9c
@@ -170,6 +172,13 @@ class DBImpl : public DB {
2d5d9c
   // Lock over the persistent DB state.  Non-null iff successfully acquired.
2d5d9c
   FileLock* db_lock_;
2d5d9c
 
2d5d9c
+  port::Mutex suspend_mutex;
2d5d9c
+  port::CondVar suspend_cv;
2d5d9c
+  int suspend_count;
2d5d9c
+  bool suspended;
2d5d9c
+  static void SuspendWork(void* db);
2d5d9c
+  void SuspendCallback();
2d5d9c
+
2d5d9c
   // State below is protected by mutex_
2d5d9c
   port::Mutex mutex_;
2d5d9c
   std::atomic<bool> shutting_down_;
2d5d9c
diff --git a/db/db_test.cc b/db/db_test.cc
2d5d9c
index 908b41d..2e65370 100644
2d5d9c
--- a/db/db_test.cc
2d5d9c
+++ b/db/db_test.cc
2d5d9c
@@ -2051,6 +2051,8 @@ class ModelDB : public DB {
2d5d9c
   };
2d5d9c
 
2d5d9c
   explicit ModelDB(const Options& options) : options_(options) {}
2d5d9c
+  virtual void SuspendCompactions() override {}
2d5d9c
+  virtual void ResumeCompactions() override {}
2d5d9c
   ~ModelDB() override = default;
2d5d9c
   Status Put(const WriteOptions& o, const Slice& k, const Slice& v) override {
2d5d9c
     return DB::Put(o, k, v);
2d5d9c
diff --git a/include/leveldb/db.h b/include/leveldb/db.h
2d5d9c
index a13d147..61c29c0 100644
2d5d9c
--- a/include/leveldb/db.h
2d5d9c
+++ b/include/leveldb/db.h
2d5d9c
@@ -145,6 +145,12 @@ class LEVELDB_EXPORT DB {
2d5d9c
   // Therefore the following call will compact the entire database:
2d5d9c
   //    db->CompactRange(nullptr, nullptr);
2d5d9c
   virtual void CompactRange(const Slice* begin, const Slice* end) = 0;
2d5d9c
+
2d5d9c
+  // Suspends the background compaction thread.  This methods
2d5d9c
+  // returns once suspended.
2d5d9c
+  virtual void SuspendCompactions() = 0;
2d5d9c
+  // Resumes a suspended background compation thread.
2d5d9c
+  virtual void ResumeCompactions() = 0;
2d5d9c
 };
2d5d9c
 
2d5d9c
 // Destroy the contents of the specified database.