From e31f4332276edb9b71272d26c2c0296cf8117101 Mon Sep 17 00:00:00 2001 From: Gordon Hall Date: Mon, 30 Jan 2017 15:47:50 -0500 Subject: [PATCH] start working on exposing compactRange from leveldb --- leveldown.js | 5 +++++ src/database.cc | 29 +++++++++++++++++++++++++++++ src/database.h | 2 ++ src/database_async.cc | 40 ++++++++++++++++++++++++++++++++++++++++ src/database_async.h | 22 ++++++++++++++++++++++ 5 files changed, 98 insertions(+) diff --git a/leveldown.js b/leveldown.js index beb1e4c0..477654bb 100644 --- a/leveldown.js +++ b/leveldown.js @@ -58,6 +58,11 @@ LevelDOWN.prototype._approximateSize = function (start, end, callback) { } +LevelDOWN.prototype.compactRange = function (start, end, callback) { + this.binding.compactRange(start, end, callback) +} + + LevelDOWN.prototype.getProperty = function (property) { if (typeof property != 'string') throw new Error('getProperty() requires a valid `property` argument') diff --git a/src/database.cc b/src/database.cc index a799e054..647960a5 100644 --- a/src/database.cc +++ b/src/database.cc @@ -79,6 +79,11 @@ uint64_t Database::ApproximateSizeFromDatabase (const leveldb::Range* range) { return size; } +void Database::CompactRangeFromDatabase (const leveldb::Slice* start, + const leveldb::Slice* end) { + db->CompactRange(start, end); +} + void Database::GetPropertyFromDatabase ( const leveldb::Slice& property , std::string* value) { @@ -143,6 +148,7 @@ void Database::Init () { Nan::SetPrototypeMethod(tpl, "del", Database::Delete); Nan::SetPrototypeMethod(tpl, "batch", Database::Batch); Nan::SetPrototypeMethod(tpl, "approximateSize", Database::ApproximateSize); + Nan::SetPrototypeMethod(tpl, "compactRange", Database::CompactRange); Nan::SetPrototypeMethod(tpl, "getProperty", Database::GetProperty); Nan::SetPrototypeMethod(tpl, "iterator", Database::Iterator); } @@ -430,6 +436,29 @@ NAN_METHOD(Database::ApproximateSize) { Nan::AsyncQueueWorker(worker); } +NAN_METHOD(Database::CompactRange) { + v8::Local startHandle = info[0].As(); + v8::Local endHandle = info[1].As(); + + LD_METHOD_SETUP_COMMON(compactRange, -1, 2) + + LD_STRING_OR_BUFFER_TO_SLICE(start, startHandle, start) + LD_STRING_OR_BUFFER_TO_SLICE(end, endHandle, end) + + CompactRangeWorker* worker = new CompactRangeWorker( + database + , new Nan::Callback(callback) + , start + , end + , startHandle + , endHandle + ); + // persist to prevent accidental GC + v8::Local _this = info.This(); + worker->SaveToPersistent("database", _this); + Nan::AsyncQueueWorker(worker); +} + NAN_METHOD(Database::GetProperty) { v8::Local propertyHandle = info[0].As(); v8::Local callback; // for LD_STRING_OR_BUFFER_TO_SLICE diff --git a/src/database.h b/src/database.h index e16e6c70..25a68e22 100644 --- a/src/database.h +++ b/src/database.h @@ -68,6 +68,7 @@ class Database : public Nan::ObjectWrap { , leveldb::WriteBatch* batch ); uint64_t ApproximateSizeFromDatabase (const leveldb::Range* range); + void CompactRangeFromDatabase (const leveldb::Slice* start, const leveldb::Slice* end); void GetPropertyFromDatabase (const leveldb::Slice& property, std::string* value); leveldb::Iterator* NewIterator (leveldb::ReadOptions* options); const leveldb::Snapshot* NewSnapshot (); @@ -101,6 +102,7 @@ class Database : public Nan::ObjectWrap { static NAN_METHOD(Write); static NAN_METHOD(Iterator); static NAN_METHOD(ApproximateSize); + static NAN_METHOD(CompactRange); static NAN_METHOD(GetProperty); }; diff --git a/src/database_async.cc b/src/database_async.cc index a15efaa3..0408c072 100644 --- a/src/database_async.cc +++ b/src/database_async.cc @@ -267,4 +267,44 @@ void ApproximateSizeWorker::HandleOKCallback () { callback->Call(2, argv); } +/** COMPACT RANGE WORKER **/ + +CompactRangeWorker::CompactRangeWorker ( + Database *database + , Nan::Callback *callback + , leveldb::Slice start + , leveldb::Slice end + , v8::Local &startHandle + , v8::Local &endHandle +) : AsyncWorker(database, callback) +{ + Nan::HandleScope scope; + + SaveToPersistent("start", startHandle); + SaveToPersistent("end", endHandle); +}; + +CompactRangeWorker::~CompactRangeWorker () {} + +void CompactRangeWorker::Execute () { + database->CompactRangeFromDatabase(&start, &end); +} + +void CompactRangeWorker::WorkComplete() { + Nan::HandleScope scope; + + DisposeStringOrBufferFromSlice(GetFromPersistent("start"), start); + DisposeStringOrBufferFromSlice(GetFromPersistent("end"), end); + AsyncWorker::WorkComplete(); +} + +void CompactRangeWorker::HandleOKCallback () { + Nan::HandleScope scope; + + v8::Local argv[] = { + Nan::Null() + }; + callback->Call(1, argv); +} + } // namespace leveldown diff --git a/src/database_async.h b/src/database_async.h index a501f5a1..09b6205a 100644 --- a/src/database_async.h +++ b/src/database_async.h @@ -162,6 +162,28 @@ class ApproximateSizeWorker : public AsyncWorker { uint64_t size; }; +class CompactRangeWorker : public AsyncWorker { +public: + CompactRangeWorker ( + Database *database + , Nan::Callback *callback + , leveldb::Slice start + , leveldb::Slice end + , v8::Local &startHandle + , v8::Local &endHandle + ); + + virtual ~CompactRangeWorker (); + virtual void Execute (); + virtual void HandleOKCallback (); + virtual void WorkComplete (); + + private: + leveldb::Slice start; + leveldb::Slice end; +}; + + } // namespace leveldown #endif