bfc0460
From d2545cbf7f7dfae4b1d01c299ed0e17d71664439 Mon Sep 17 00:00:00 2001
bfc0460
From: Hiram Chirino <hiram@hiramchirino.com>
bfc0460
Date: Tue, 30 Oct 2012 16:56:52 -0400
bfc0460
Subject: [PATCH 5/6] Added a DB:SuspendCompations() and DB:ResumeCompactions()
bfc0460
 methods. Fixes issue #184
a04e332
bfc0460
https://code.google.com/p/leveldb/issues/detail?id=184
bfc0460
---
bfc0460
 db/db_impl.cc        | 36 ++++++++++++++++++++++++++++++++++++
bfc0460
 db/db_impl.h         |  9 +++++++++
bfc0460
 db/db_test.cc        |  4 ++++
bfc0460
 include/leveldb/db.h |  6 ++++++
bfc0460
 4 files changed, 55 insertions(+)
a04e332
a04e332
diff --git a/db/db_impl.cc b/db/db_impl.cc
a04e332
index 395d317..593a5b5 100644
a04e332
--- a/db/db_impl.cc
a04e332
+++ b/db/db_impl.cc
a04e332
@@ -124,6 +124,9 @@ DBImpl::DBImpl(const Options& options, const std::string& dbname)
a04e332
       dbname_(dbname),
a04e332
       db_lock_(NULL),
a04e332
       shutting_down_(NULL),
a04e332
+      suspend_cv(&suspend_mutex),
a04e332
+      suspend_count(0),
a04e332
+      suspended(false),
a04e332
       bg_cv_(&mutex_),
a04e332
       mem_(new MemTable(internal_comparator_)),
a04e332
       imm_(NULL),
a04e332
@@ -1398,6 +1401,39 @@ void DBImpl::GetApproximateSizes(
a04e332
   }
a04e332
 }
a04e332
 
a04e332
+void DBImpl::SuspendCompactions() {
a04e332
+  MutexLock l(& suspend_mutex);
a04e332
+  env_->Schedule(&SuspendWork, this);
a04e332
+  suspend_count++;
a04e332
+  while( !suspended ) {
a04e332
+    suspend_cv.Wait();
a04e332
+  }  
a04e332
+}
a04e332
+void DBImpl::SuspendWork(void* db) {
a04e332
+  reinterpret_cast<DBImpl*>(db)->SuspendCallback();
a04e332
+}
a04e332
+void DBImpl::SuspendCallback() {
a04e332
+    MutexLock l(&suspend_mutex);
a04e332
+    Log(options_.info_log, "Compactions suspended");
a04e332
+    suspended = true;
a04e332
+    suspend_cv.SignalAll();
a04e332
+    while( suspend_count > 0 ) {
a04e332
+        suspend_cv.Wait();
a04e332
+    }
a04e332
+    suspended = false;
a04e332
+    suspend_cv.SignalAll();
a04e332
+    Log(options_.info_log, "Compactions resumed");
a04e332
+}
a04e332
+void DBImpl::ResumeCompactions() {
a04e332
+    MutexLock l(&suspend_mutex);
a04e332
+    suspend_count--;
a04e332
+    suspend_cv.SignalAll();
a04e332
+    while( suspended ) {
a04e332
+      suspend_cv.Wait();
a04e332
+    }  
a04e332
+}
a04e332
+
a04e332
+
a04e332
 // Default implementations of convenience methods that subclasses of DB
a04e332
 // can call if they wish
a04e332
 Status DB::Put(const WriteOptions& opt, const Slice& key, const Slice& value) {
a04e332
diff --git a/db/db_impl.h b/db/db_impl.h
a04e332
index 3c8d711..9f3949c 100644
a04e332
--- a/db/db_impl.h
a04e332
+++ b/db/db_impl.h
a04e332
@@ -41,6 +41,8 @@ class DBImpl : public DB {
a04e332
   virtual bool GetProperty(const Slice& property, std::string* value);
a04e332
   virtual void GetApproximateSizes(const Range* range, int n, uint64_t* sizes);
a04e332
   virtual void CompactRange(const Slice* begin, const Slice* end);
a04e332
+  virtual void SuspendCompactions();
a04e332
+  virtual void ResumeCompactions();
a04e332
 
a04e332
   // Extra methods (for testing) that are not in the public DB interface
a04e332
 
a04e332
@@ -125,6 +127,13 @@ class DBImpl : public DB {
a04e332
   // Lock over the persistent DB state.  Non-NULL iff successfully acquired.
a04e332
   FileLock* db_lock_;
a04e332
 
a04e332
+  port::Mutex suspend_mutex;
a04e332
+  port::CondVar suspend_cv;
a04e332
+  int suspend_count;
a04e332
+  bool suspended;
a04e332
+  static void SuspendWork(void* db);
a04e332
+  void SuspendCallback();
a04e332
+
a04e332
   // State below is protected by mutex_
a04e332
   port::Mutex mutex_;
a04e332
   port::AtomicPointer shutting_down_;
a04e332
diff --git a/db/db_test.cc b/db/db_test.cc
a04e332
index 49aae04..782be38 100644
a04e332
--- a/db/db_test.cc
a04e332
+++ b/db/db_test.cc
a04e332
@@ -1801,6 +1801,10 @@ class ModelDB: public DB {
a04e332
 
a04e332
   explicit ModelDB(const Options& options): options_(options) { }
a04e332
   ~ModelDB() { }
a04e332
+  
a04e332
+  virtual void SuspendCompactions() {}
a04e332
+  virtual void ResumeCompactions() {}
a04e332
+  
a04e332
   virtual Status Put(const WriteOptions& o, const Slice& k, const Slice& v) {
a04e332
     return DB::Put(o, k, v);
a04e332
   }
a04e332
diff --git a/include/leveldb/db.h b/include/leveldb/db.h
a04e332
index da8b11a..089707c 100644
a04e332
--- a/include/leveldb/db.h
a04e332
+++ b/include/leveldb/db.h
a04e332
@@ -140,6 +140,12 @@ class DB {
a04e332
   //    db->CompactRange(NULL, NULL);
a04e332
   virtual void CompactRange(const Slice* begin, const Slice* end) = 0;
a04e332
 
a04e332
+  // Suspends the background compaction thread.  This methods
a04e332
+  // returns once suspended.
a04e332
+  virtual void SuspendCompactions() = 0;
a04e332
+  // Resumes a suspended background compation thread.
a04e332
+  virtual void ResumeCompactions() = 0;
a04e332
+
a04e332
  private:
a04e332
   // No copying allowed
a04e332
   DB(const DB&);
bfc0460
-- 
bfc0460
1.8.3.1
bfc0460