[Pkg-javascript-commits] [node-leveldown] 202/492: allow one next() at a time, improve end() handling

Andrew Kelley andrewrk-guest at moszumanska.debian.org
Sun Jul 6 17:13:59 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 92e24a6f0d703cba975c7a8fe62b91f61175b0eb
Author: Rod Vagg <rod at vagg.org>
Date:   Thu Feb 14 19:35:28 2013 +1100

    allow one next() at a time, improve end() handling
---
 src/iterator.cc       | 33 ++++++++++++++++++++-------------
 src/iterator.h        |  4 ++--
 src/iterator_async.cc |  6 ++++--
 src/levelup.h         |  4 ++++
 4 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/src/iterator.cc b/src/iterator.cc
index 7775855..797c6b9 100644
--- a/src/iterator.cc
+++ b/src/iterator.cc
@@ -66,8 +66,8 @@ void levelup::Iterator::IteratorEnd () {
 }
 
 void checkEndCallback (levelup::Iterator* iterator) {
-  iterator->nextCalls--;
-  if (iterator->nextCalls == 0 && iterator->endWorker != NULL) {
+  iterator->nexting = false;
+  if (iterator->endWorker != NULL) {
     AsyncQueueWorker(iterator->endWorker);
     iterator->endWorker = NULL;
   }
@@ -77,24 +77,25 @@ void checkEndCallback (levelup::Iterator* iterator) {
 Handle<Value> levelup::Iterator::Next (const Arguments& args) {
   HandleScope scope;
   Iterator* iterator = ObjectWrap::Unwrap<Iterator>(args.This());
-  Persistent<Function> endCallback = Persistent<Function>::New(Local<Function>::Cast(args[0]));
-  Persistent<Function> dataCallback = Persistent<Function>::New(Local<Function>::Cast(args[1]));
 
   if (iterator->ended) {
-    Local<Value> argv[] = {
-        Local<Value>::New(Exception::Error(String::New("Cannot call next() after end()")))
-    };
-    RunCallback(dataCallback, argv, 1);
-    return Undefined();
+    THROW_RETURN("Cannot call next() after end()")
+  }
+
+  if (iterator->nexting) {
+    THROW_RETURN("Cannot call next() before previous next() has completed")
   }
 
+  Persistent<Function> endCallback = Persistent<Function>::New(Local<Function>::Cast(args[0]));
+  Persistent<Function> dataCallback = Persistent<Function>::New(Local<Function>::Cast(args[1]));
+
   NextWorker* worker = new NextWorker(
       iterator
     , dataCallback
     , endCallback
     , checkEndCallback
   );
-  iterator->nextCalls++;
+  iterator->nexting = true;
   AsyncQueueWorker(worker);
   return Undefined();
 }
@@ -102,16 +103,22 @@ Handle<Value> levelup::Iterator::Next (const Arguments& args) {
 Handle<Value> levelup::Iterator::End (const Arguments& args) {
   HandleScope scope;
   Iterator* iterator = ObjectWrap::Unwrap<Iterator>(args.This());
+
+  if (iterator->ended) {
+    THROW_RETURN("end() already called on iterator")
+  }
+
   Persistent<Function> endCallback = Persistent<Function>::New(Local<Function>::Cast(args[0]));
   EndWorker* worker = new EndWorker(
       iterator
     , endCallback
   );
   iterator->ended = true;
-  if (iterator->nextCalls == 0) {
-    AsyncQueueWorker(worker);
-  } else {
+  if (iterator->nexting) {
+    // waiting for a next() to return, queue the end
     iterator->endWorker = worker;
+  } else {
+    AsyncQueueWorker(worker);
   }
   return Undefined();
 }
diff --git a/src/iterator.h b/src/iterator.h
index c49f6d9..ada8c47 100644
--- a/src/iterator.h
+++ b/src/iterator.h
@@ -64,7 +64,7 @@ public:
     options->fill_cache = fillCache;
     dbIterator = NULL;
     count      = 0;
-    nextCalls  = 0;
+    nexting    = false;
     ended      = false;
     endWorker  = NULL;
   };
@@ -92,7 +92,7 @@ private:
 public:
   bool keyAsBuffer;
   bool valueAsBuffer;
-  int nextCalls;
+  bool nexting;
   bool ended;
   AsyncWorker* endWorker;
 
diff --git a/src/iterator_async.cc b/src/iterator_async.cc
index ab8dc6a..5148e33 100644
--- a/src/iterator_async.cc
+++ b/src/iterator_async.cc
@@ -48,6 +48,10 @@ void NextWorker::HandleOKCallback () {
     returnValue = Local<Value>::New(Buffer::New((char*)value.data(), value.size())->handle_);
   else
     returnValue = String::New((char*)value.data(), value.size());
+
+  // clean up & handle the next/end state see iterator.cc/checkEndCallback
+  localCallback(iterator);
+
   if (ok) {
     Local<Value> argv[] = {
         Local<Value>::New(Null())
@@ -59,8 +63,6 @@ void NextWorker::HandleOKCallback () {
     Local<Value> argv[0];
     RunCallback(endCallback, argv, 0);
   }
-
-  localCallback(iterator);
 }
 
 /** END WORKER **/
diff --git a/src/levelup.h b/src/levelup.h
index 344eeaf..7e2e17e 100644
--- a/src/levelup.h
+++ b/src/levelup.h
@@ -45,6 +45,10 @@
 #define UINT32_OPTION_VALUE(optionsObj, opt, default) \
   uint32_t opt = optionsObj->Has(option_ ## opt) && optionsObj->Get(option_ ## opt)->IsUint32() ? optionsObj->Get(option_ ## opt)->Uint32Value() : default;
 
+#define THROW_RETURN(msg) \
+  ThrowException(Exception::Error(String::New(#msg))); \
+  return Undefined();
+
 void RunCallback (v8::Persistent<v8::Function> callback, v8::Local<v8::Value> argv[], int length);
 
 #endif

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