[Pkg-javascript-commits] [node-leveldown] 329/492: don't allow empty batch() operations through

Andrew Kelley andrewrk-guest at moszumanska.debian.org
Sun Jul 6 17:14:13 UTC 2014


This is an automated email from the git hooks/post-receive script.

andrewrk-guest pushed a commit to annotated tag rocksdb-0.10.1
in repository node-leveldown.

commit 4b5e6372ddb47df709065d4be0fc0170b3dea6d9
Author: Rod Vagg <rod at vagg.org>
Date:   Tue May 14 22:59:04 2013 +1000

    don't allow empty batch() operations through
---
 src/batch.cc          | 23 +++++++++++++++++------
 src/batch.h           |  1 +
 src/database.cc       | 26 +++++++++++++++++++-------
 src/database.h        | 11 +++++++++++
 src/database_async.cc |  8 +-------
 5 files changed, 49 insertions(+), 20 deletions(-)

diff --git a/src/batch.cc b/src/batch.cc
index 0436599..4777446 100644
--- a/src/batch.cc
+++ b/src/batch.cc
@@ -14,6 +14,7 @@ Batch::Batch (leveldown::Database* database, bool sync) : database(database) {
   options->sync = sync;
   batch = new leveldb::WriteBatch();
   references = new std::vector< v8::Persistent<v8::Value> >;
+  hasData = false;
 }
 
 Batch::~Batch () {
@@ -118,6 +119,8 @@ v8::Handle<v8::Value> Batch::Put (const v8::Arguments& args) {
         valueBuffer));
 
   batch->batch->Put(key, value);
+  if (!batch->hasData)
+    batch->hasData = true;
 
   return scope.Close(args.Holder());
 }
@@ -139,6 +142,8 @@ v8::Handle<v8::Value> Batch::Del (const v8::Arguments& args) {
         keyBuffer));
 
   batch->batch->Delete(key);
+  if (!batch->hasData)
+    batch->hasData = true;
 
   return scope.Close(args.Holder());
 }
@@ -148,6 +153,7 @@ v8::Handle<v8::Value> Batch::Clear (const v8::Arguments& args) {
   Batch* batch = ObjectWrap::Unwrap<Batch>(args.Holder());
 
   batch->batch->Clear();
+  batch->hasData = false;
 
   return scope.Close(args.Holder());
 }
@@ -159,14 +165,19 @@ v8::Handle<v8::Value> Batch::Write (const v8::Arguments& args) {
   if (args.Length() == 0) {
     LD_THROW_RETURN(write() requires a callback argument)
   }
-  v8::Persistent<v8::Function> callback = v8::Persistent<v8::Function>::New(
-      LD_NODE_ISOLATE_PRE
-      v8::Local<v8::Function>::Cast(args[0]));
 
-  BatchWriteWorker* worker  = new BatchWriteWorker(batch, callback);
-  AsyncQueueWorker(worker);
+  if (batch->hasData) {
+    v8::Persistent<v8::Function> callback = v8::Persistent<v8::Function>::New(
+        LD_NODE_ISOLATE_PRE
+        v8::Local<v8::Function>::Cast(args[0]));
+
+    BatchWriteWorker* worker  = new BatchWriteWorker(batch, callback);
+    AsyncQueueWorker(worker);
+  } else {
+    LD_RUN_CALLBACK(v8::Local<v8::Function>::Cast(args[0]), NULL, 0);
+  }
 
   return v8::Undefined();
 }
 
-} // namespace leveldown
\ No newline at end of file
+} // namespace leveldown
diff --git a/src/batch.h b/src/batch.h
index 4655b05..54ab7dc 100644
--- a/src/batch.h
+++ b/src/batch.h
@@ -27,6 +27,7 @@ private:
   leveldb::WriteOptions* options;
   leveldb::WriteBatch* batch;
   std::vector< v8::Persistent<v8::Value> >* references;
+  bool hasData; // keep track of whether we're writing data or not
 
   static v8::Persistent<v8::Function> constructor;
 
diff --git a/src/database.cc b/src/database.cc
index 0eacb15..7d2f98d 100644
--- a/src/database.cc
+++ b/src/database.cc
@@ -414,6 +414,7 @@ v8::Handle<v8::Value> Database::Batch (const v8::Arguments& args) {
   std::vector< v8::Persistent<v8::Value> >* references =
       new std::vector< v8::Persistent<v8::Value> >;
   leveldb::WriteBatch* batch = new leveldb::WriteBatch();
+  bool hasData = false;
 
   for (unsigned int i = 0; i < array->Length(); i++) {
     if (!array->Get(i)->IsObject())
@@ -430,6 +431,8 @@ v8::Handle<v8::Value> Database::Batch (const v8::Arguments& args) {
       LD_STRING_OR_BUFFER_TO_SLICE(key, keyBuffer, key)
 
       batch->Delete(key);
+      if (!hasData)
+        hasData = true;
       if (node::Buffer::HasInstance(keyBuffer->ToObject()))
         references->push_back(v8::Persistent<v8::Value>::New(
             LD_NODE_ISOLATE_PRE
@@ -442,6 +445,8 @@ v8::Handle<v8::Value> Database::Batch (const v8::Arguments& args) {
       LD_STRING_OR_BUFFER_TO_SLICE(value, valueBuffer, value)
 
       batch->Put(key, value);
+      if (!hasData)
+        hasData = true;
       if (node::Buffer::HasInstance(keyBuffer->ToObject()))
         references->push_back(v8::Persistent<v8::Value>::New(
             LD_NODE_ISOLATE_PRE
@@ -453,13 +458,20 @@ v8::Handle<v8::Value> Database::Batch (const v8::Arguments& args) {
     }
   }
 
-  AsyncQueueWorker(new BatchWorker(
-      database
-    , callback
-    , batch
-    , references
-    , sync
-  ));
+  // don't allow an empty batch through
+  if (hasData) {
+    AsyncQueueWorker(new BatchWorker(
+        database
+      , callback
+      , batch
+      , references
+      , sync
+    ));
+  } else {
+    ClearReferences(references);
+    LD_RUN_CALLBACK(callback, NULL, 0);
+    callback.Dispose(LD_NODE_ISOLATE);
+  }
 
   return v8::Undefined();
 }
diff --git a/src/database.h b/src/database.h
index b2f2377..25e8019 100644
--- a/src/database.h
+++ b/src/database.h
@@ -7,6 +7,7 @@
 #define LD_DATABASE_H
 
 #include <map>
+#include <vector>
 #include <node.h>
 
 #include "leveldb/db.h"
@@ -31,6 +32,16 @@ struct AsyncDescriptor;
 
 v8::Handle<v8::Value> LevelDOWN (const v8::Arguments& args);
 
+static inline void ClearReferences (std::vector< v8::Persistent<v8::Value> >* references) {
+  for (std::vector< v8::Persistent<v8::Value> >::iterator it = references->begin()
+      ; it != references->end()
+      ; ) {
+    it->Dispose(LD_NODE_ISOLATE);
+    it = references->erase(it);
+  }
+  delete references;
+}
+
 class Database : public node::ObjectWrap {
 public:
   static void Init ();
diff --git a/src/database_async.cc b/src/database_async.cc
index 2644f7c..44a3f98 100644
--- a/src/database_async.cc
+++ b/src/database_async.cc
@@ -192,13 +192,7 @@ BatchWorker::BatchWorker (
 };
 
 BatchWorker::~BatchWorker () {
-  for (std::vector< v8::Persistent<v8::Value> >::iterator it = references->begin()
-      ; it != references->end()
-      ; ) {
-    it->Dispose(LD_NODE_ISOLATE);
-    it = references->erase(it);
-  }
-  delete references;
+  ClearReferences(references);
   delete options;
 }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-leveldown.git



More information about the Pkg-javascript-commits mailing list