[Pkg-javascript-commits] [node-leveldown] 107/492: allow JS Strings through to native layer
Andrew Kelley
andrewrk-guest at moszumanska.debian.org
Sun Jul 6 17:13:49 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 bedf32e8093637335e983c0093aac22d962b13da
Author: Rod Vagg <rod at vagg.org>
Date: Sat Dec 15 17:02:15 2012 +1100
allow JS Strings through to native layer
major speed boost here for all utf8 databases
---
.jshintrc | 3 +-
lib/levelup.js | 13 +++---
lib/util.js | 4 +-
src/batch.h | 12 +++---
src/database.cc | 110 +++++++++++++--------------------------------------
src/database_async.h | 14 +++----
src/iterator.cc | 16 +++++---
src/levelup.h | 32 +++++++++++++++
8 files changed, 92 insertions(+), 112 deletions(-)
diff --git a/.jshintrc b/.jshintrc
index 6fac775..2685324 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -25,5 +25,6 @@
, "proto": true
, "expr": true
, "es5": true
+ , "esnext": true
, "strict": false
-}
+}
\ No newline at end of file
diff --git a/lib/levelup.js b/lib/levelup.js
index 7ddabfb..9f794dc 100644
--- a/lib/levelup.js
+++ b/lib/levelup.js
@@ -26,15 +26,13 @@ var bridge = require('bindings')('levelup.node')
}('hex utf8 utf-8 ascii binary base64 ucs2 ucs-2 utf16le utf-16le'.split(' ')))
, getOptions = function (options, globalOptions) {
- if (typeof options == 'string') // just an encoding
- options = extend({}, encodingOpts[options] || encodingOpts[defaultOptions.encoding])
- return extend(extend({}, globalOptions), options)
+ return typeof options == 'string' // just an encoding
+ ? options = extend({}, encodingOpts[options] || encodingOpts[defaultOptions.encoding])
+ : extend(extend({}, globalOptions), options)
}
, getCallback = function (options_, callback_) {
- if (typeof options_ == 'function')
- return options_
- return callback_
+ return typeof options_ == 'function' ? options_ : callback_
}
// Possible this._status values:
@@ -172,8 +170,7 @@ LevelUP.prototype = {
this.emit('error', err)
} else {
this.emit('put', key_, value_)
- // Node 0.9 bug, do this in current tick and a copy() operation will core dump
- callback && process.nextTick(callback.bind(null, null, key, value))
+ callback && callback(null, key, value)
}
}.bind(this))
} else {
diff --git a/lib/util.js b/lib/util.js
index 6c8550b..c34a084 100644
--- a/lib/util.js
+++ b/lib/util.js
@@ -5,7 +5,9 @@ var toBuffer = function (data, encoding) {
data = JSON.stringify(data)
encoding = 'utf8'
}
- return data === undefined || data === null || Buffer.isBuffer(data) ? data : new Buffer(String(data), encoding)
+ if (data === undefined || data === null || Buffer.isBuffer(data)) return data
+ data = String(data)
+ return encoding == 'utf8' ? data : new Buffer(data, encoding)
}
, toEncoding = function (buffer, encoding) {
diff --git a/src/batch.h b/src/batch.h
index ac95d38..a1a6380 100644
--- a/src/batch.h
+++ b/src/batch.h
@@ -19,7 +19,7 @@ class BatchDelete : public BatchOp {
public:
BatchDelete (
Slice key
- , Persistent<Object> keyPtr
+ , Persistent<Value> keyPtr
) : key(key)
, keyPtr(keyPtr)
{};
@@ -28,7 +28,7 @@ public:
private:
Slice key;
- Persistent<Object> keyPtr;
+ Persistent<Value> keyPtr;
};
class BatchWrite : public BatchOp {
@@ -36,8 +36,8 @@ public:
BatchWrite (
Slice key
, Slice value
- , Persistent<Object> keyPtr
- , Persistent<Object> valuePtr
+ , Persistent<Value> keyPtr
+ , Persistent<Value> valuePtr
) : key(key)
, keyPtr(keyPtr)
, value(value)
@@ -48,9 +48,9 @@ public:
private:
Slice key;
- Persistent<Object> keyPtr;
+ Persistent<Value> keyPtr;
Slice value;
- Persistent<Object> valuePtr;
+ Persistent<Value> valuePtr;
};
#endif
diff --git a/src/database.cc b/src/database.cc
index 5df7d1c..ae69ce6 100644
--- a/src/database.cc
+++ b/src/database.cc
@@ -153,42 +153,15 @@ Handle<Value> Database::Put (const Arguments& args) {
Database* database = ObjectWrap::Unwrap<Database>(args.This());
Persistent<Function> callback = Persistent<Function>::New(Local<Function>::Cast(args[3]));
- if (args[0]->IsNull() || args[0]->IsUndefined()) {
- Local<Value> argv[] = {
- Local<Value>::New(Exception::Error(String::New("Key cannot be `null` or `undefined`")))
- };
- RunCallback(callback, argv, 1);
- return Undefined();
- }
-
- if (!Buffer::HasInstance(args[0])) {
- Local<Value> argv[] = {
- Local<Value>::New(Exception::Error(String::New("Key must be an instance of Buffer")))
- };
- RunCallback(callback, argv, 1);
- return Undefined();
- }
-
- if (args[1]->IsNull() || args[1]->IsUndefined()) {
- Local<Value> argv[] = {
- Local<Value>::New(Exception::Error(String::New("Value cannot be `null` or `undefined`")))
- };
- RunCallback(callback, argv, 1);
- return Undefined();
- }
-
- if (!Buffer::HasInstance(args[1])) {
- Local<Value> argv[] = {
- Local<Value>::New(Exception::Error(String::New("Value must be an instance of Buffer")))
- };
- RunCallback(callback, argv, 1);
- return Undefined();
- }
-
- Persistent<Object> keyBuffer = Persistent<Object>::New(args[0]->ToObject());
- Slice key(Buffer::Data(keyBuffer), Buffer::Length(keyBuffer));
- Persistent<Object> valueBuffer = Persistent<Object>::New(args[1]->ToObject());
- Slice value(Buffer::Data(valueBuffer), Buffer::Length(valueBuffer));
+ CB_ERR_IF_NULL_OR_UNDEFINED(0, "Key")
+ CB_ERR_IF_NOT_BUFFER_OR_STRING(0, "Key")
+ CB_ERR_IF_NULL_OR_UNDEFINED(1, "Value")
+ CB_ERR_IF_NOT_BUFFER_OR_STRING(1, "Value")
+
+ Persistent<Value> keyBuffer = Persistent<Value>::New(args[0]);
+ STRING_OR_BUFFER_TO_SLICE(key, keyBuffer)
+ Persistent<Value> valueBuffer = Persistent<Value>::New(args[1]);
+ STRING_OR_BUFFER_TO_SLICE(value, valueBuffer)
Local<Object> optionsObj = Local<Object>::Cast(args[2]);
bool sync = optionsObj->Has(option_sync) && optionsObj->Get(option_sync)->BooleanValue();
@@ -212,25 +185,11 @@ Handle<Value> Database::Get (const Arguments& args) {
Database* database = ObjectWrap::Unwrap<Database>(args.This());
Persistent<Function> callback = Persistent<Function>::New(Local<Function>::Cast(args[2]));
- if (args[0]->IsNull() || args[0]->IsUndefined()) {
- Local<Value> argv[] = {
- Local<Value>::New(Exception::Error(String::New("Key cannot be `null` or `undefined`")))
- };
- RunCallback(callback, argv, 1);
- return Undefined();
- }
-
- if (!Buffer::HasInstance(args[0])) {
- Local<Value> argv[] = {
- Local<Value>::New(Exception::Error(String::New("Key must be an instance of Buffer")))
- };
- RunCallback(callback, argv, 1);
- return Undefined();
- }
+ CB_ERR_IF_NULL_OR_UNDEFINED(0, "Key")
+ CB_ERR_IF_NOT_BUFFER_OR_STRING(0, "Key")
- Persistent<Object> keyBuffer = Persistent<Object>::New(args[0]->ToObject());
- Slice key(Buffer::Data(keyBuffer), Buffer::Length(keyBuffer));
- //Local<Object> optionsObj = Local<Object>::Cast(args[1]);
+ Persistent<Value> keyBuffer = Persistent<Value>::New(args[0]);
+ STRING_OR_BUFFER_TO_SLICE(key, keyBuffer)
ReadWorker* worker = new ReadWorker(
database
@@ -249,24 +208,11 @@ Handle<Value> Database::Delete (const Arguments& args) {
Database* database = ObjectWrap::Unwrap<Database>(args.This());
Persistent<Function> callback = Persistent<Function>::New(Local<Function>::Cast(args[2]));
- if (args[0]->IsNull() || args[0]->IsUndefined()) {
- Local<Value> argv[] = {
- Local<Value>::New(Exception::Error(String::New("Key cannot be `null` or `undefined`")))
- };
- RunCallback(callback, argv, 1);
- return Undefined();
- }
+ CB_ERR_IF_NULL_OR_UNDEFINED(0, "Key")
+ CB_ERR_IF_NOT_BUFFER_OR_STRING(0, "Key")
- if (!Buffer::HasInstance(args[0])) {
- Local<Value> argv[] = {
- Local<Value>::New(Exception::Error(String::New("Key must be an instance of Buffer")))
- };
- RunCallback(callback, argv, 1);
- return Undefined();
- }
-
- Persistent<Object> keyBuffer = Persistent<Object>::New(args[0]->ToObject());
- Slice key(Buffer::Data(keyBuffer), Buffer::Length(keyBuffer));
+ Persistent<Value> keyBuffer = Persistent<Value>::New(args[0]);
+ STRING_OR_BUFFER_TO_SLICE(key, keyBuffer)
Local<Object> optionsObj = Local<Object>::Cast(args[1]);
bool sync = optionsObj->Has(option_sync) && optionsObj->Get(option_sync)->BooleanValue();
@@ -297,26 +243,24 @@ Handle<Value> Database::Batch (const Arguments& args) {
continue;
Local<Object> obj = Local<Object>::Cast(array->Get(i));
- if (!obj->Has(str_type) || !obj->Has(str_key))
+ if (!obj->Has(str_type) && !obj->Has(str_key))
continue;
- if (!obj->Get(str_key)->IsObject())
- continue;
- Local<Object> keyBuffer = obj->Get(str_key)->ToObject();
- if (!Buffer::HasInstance(keyBuffer))
+ Local<Value> keyBuffer = obj->Get(str_key);
+ if (!keyBuffer->IsString() && !Buffer::HasInstance(keyBuffer))
continue;
- Slice key(Buffer::Data(keyBuffer), Buffer::Length(keyBuffer));
+ STRING_OR_BUFFER_TO_SLICE(key, keyBuffer)
if (obj->Get(str_type)->StrictEquals(str_del)) {
- operations->push_back(new BatchDelete(key, Persistent<Object>::New(keyBuffer)));
+ operations->push_back(new BatchDelete(key, Persistent<Value>::New(keyBuffer)));
} else if (obj->Get(str_type)->StrictEquals(str_put) && obj->Has(str_value)) {
- if (!obj->Get(str_value)->IsObject())
+ if (!obj->Has(str_value))
continue;
- Local<Object> valueBuffer = obj->Get(str_value)->ToObject();
- if (!Buffer::HasInstance(valueBuffer))
+ Local<Value> valueBuffer = obj->Get(str_value);
+ if (!valueBuffer->IsString() && !Buffer::HasInstance(valueBuffer))
continue;
- Slice value(Buffer::Data(valueBuffer), Buffer::Length(valueBuffer));
- operations->push_back(new BatchWrite(key, value, Persistent<Object>::New(keyBuffer), Persistent<Object>::New(valueBuffer)));
+ STRING_OR_BUFFER_TO_SLICE(value, valueBuffer)
+ operations->push_back(new BatchWrite(key, value, Persistent<Value>::New(keyBuffer), Persistent<Value>::New(valueBuffer)));
}
}
diff --git a/src/database_async.h b/src/database_async.h
index 62508df..5f22116 100644
--- a/src/database_async.h
+++ b/src/database_async.h
@@ -58,7 +58,7 @@ public:
Database* database
, Persistent<Function> callback
, Slice key
- , Persistent<Object> keyPtr
+ , Persistent<Value> keyPtr
) : AsyncWorker(database, callback)
, key(key)
, keyPtr(keyPtr)
@@ -69,7 +69,7 @@ public:
protected:
Slice key;
- Persistent<Object> keyPtr;
+ Persistent<Value> keyPtr;
};
class ReadWorker : public IOWorker {
@@ -78,7 +78,7 @@ public:
Database* database
, Persistent<Function> callback
, Slice key
- , Persistent<Object> keyPtr
+ , Persistent<Value> keyPtr
) : IOWorker(database, callback, key, keyPtr)
{
options = new ReadOptions();
@@ -100,7 +100,7 @@ public:
, Persistent<Function> callback
, Slice key
, bool sync
- , Persistent<Object> keyPtr
+ , Persistent<Value> keyPtr
) : IOWorker(database, callback, key, keyPtr)
{
options = new WriteOptions();
@@ -122,8 +122,8 @@ public:
, Slice key
, Slice value
, bool sync
- , Persistent<Object> keyPtr
- , Persistent<Object> valuePtr
+ , Persistent<Value> keyPtr
+ , Persistent<Value> valuePtr
) : DeleteWorker(database, callback, key, sync, keyPtr)
, value(value)
, valuePtr(valuePtr)
@@ -134,7 +134,7 @@ public:
private:
Slice value;
- Persistent<Object> valuePtr;
+ Persistent<Value> valuePtr;
};
class BatchWorker : public AsyncWorker {
diff --git a/src/iterator.cc b/src/iterator.cc
index f1cf20b..5dcd002 100644
--- a/src/iterator.cc
+++ b/src/iterator.cc
@@ -120,14 +120,18 @@ Handle<Value> levelup::Iterator::New (const Arguments& args) {
Database* database = ObjectWrap::Unwrap<Database>(args[0]->ToObject());
Slice* start = NULL;
- if (args[1]->ToObject()->Has(option_start) && Buffer::HasInstance(args[1]->ToObject()->Get(option_start))) {
- Local<Object> startBuffer = Local<Object>::New(args[1]->ToObject()->Get(option_start)->ToObject());
- start = new Slice(Buffer::Data(startBuffer), Buffer::Length(startBuffer));
+ if (args[1]->ToObject()->Has(option_start)
+ && (Buffer::HasInstance(args[1]->ToObject()->Get(option_start)) || args[1]->ToObject()->Get(option_start)->IsString())) {
+ Local<Value> startBuffer = Local<Value>::New(args[1]->ToObject()->Get(option_start));
+ STRING_OR_BUFFER_TO_SLICE(_start, startBuffer)
+ start = new Slice(_start.data(), _start.size());
}
string* end = NULL;
- if (args[1]->ToObject()->Has(option_end) && Buffer::HasInstance(args[1]->ToObject()->Get(option_end))) {
- Local<Object> endBuffer = Local<Object>::New(args[1]->ToObject()->Get(option_end)->ToObject());
- end = new string(Buffer::Data(endBuffer), Buffer::Length(endBuffer));
+ if (args[1]->ToObject()->Has(option_end)
+ && (Buffer::HasInstance(args[1]->ToObject()->Get(option_end)) || args[1]->ToObject()->Get(option_end)->IsString())) {
+ Local<Value> endBuffer = Local<Value>::New(args[1]->ToObject()->Get(option_end));
+ STRING_OR_BUFFER_TO_SLICE(_end, endBuffer)
+ end = new string(_end.data(), _end.size());
}
bool reverse = false;
if (args[1]->ToObject()->Has(option_reverse)) {
diff --git a/src/levelup.h b/src/levelup.h
index cdb64de..feabc4b 100644
--- a/src/levelup.h
+++ b/src/levelup.h
@@ -12,6 +12,38 @@
#define LU_V8_METHOD(name) \
static v8::Handle<v8::Value> name (const v8::Arguments& args);
+#define CB_ERR_IF_NULL_OR_UNDEFINED(index, name) \
+ if (args[index]->IsNull() || args[index]->IsUndefined()) { \
+ Local<Value> argv[] = { \
+ Local<Value>::New(Exception::Error(String::New("#name cannot be `null` or `undefined`"))) \
+ }; \
+ RunCallback(callback, argv, 1); \
+ return Undefined(); \
+ }
+
+#define CB_ERR_IF_NOT_BUFFER_OR_STRING(index, name) \
+ if (!args[index]->IsString() && !Buffer::HasInstance(args[index])) { \
+ Local<Value> argv[] = { \
+ Local<Value>::New(Exception::Error(String::New("name must be a Buffer or a String"))) \
+ }; \
+ RunCallback(callback, argv, 1); \
+ return Undefined(); \
+ }
+
+#define STRING_OR_BUFFER_TO_SLICE(to, from) \
+ size_t to ## Sz_; \
+ char* to ## Ch_; \
+ if (from->IsString()) { \
+ to ## Sz_ = from->ToString()->Utf8Length(); \
+ to ## Ch_ = new char[to ## Sz_]; \
+ from->ToString()->WriteUtf8(to ## Ch_, -1, NULL, String::NO_NULL_TERMINATION); \
+ } else { \
+ assert(Buffer::HasInstance(from->ToObject())); \
+ to ## Sz_ = Buffer::Length(from->ToObject()); \
+ to ## Ch_ = Buffer::Data(from->ToObject()); \
+ } \
+ Slice to(to ## Ch_, to ## Sz_);
+
const char* ToCString(const v8::String::Utf8Value& value);
const char* ToCString(const v8::String::AsciiValue& value);
--
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