|
|
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.
|