[Pkg-javascript-commits] [node-leveldown] 07/492: batch binary, improved batch interface
Andrew Kelley
andrewrk-guest at moszumanska.debian.org
Sun Jul 6 17:13:38 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 254b6a2e97e4ffe903e9cbc8c5be3d7dbef4f994
Author: Rod Vagg <rod at vagg.org>
Date: Sun Jul 15 14:35:28 2012 +1000
batch binary, improved batch interface
---
lib/levelup.js | 50 ++++++++++++++++++++++++++++++++------------------
src/batch.cc | 13 +++++--------
src/batch.h | 19 ++++++-------------
src/database.cc | 50 +++++++++++++++++++-------------------------------
test/binary-test.js | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 112 insertions(+), 70 deletions(-)
diff --git a/lib/levelup.js b/lib/levelup.js
index fd6ac0f..5cb32e1 100644
--- a/lib/levelup.js
+++ b/lib/levelup.js
@@ -39,7 +39,7 @@ var bridge = require('../build/Release/levelup')
}
, toBuffer = function (data, encoding) {
- return Buffer.isBuffer(data) ? data : new Buffer('' + data, encoding)
+ return data === undefined || data === null || Buffer.isBuffer(data) ? data : new Buffer('' + data, encoding)
}
, toEncoding = function (buffer, encoding) {
@@ -98,6 +98,7 @@ var bridge = require('../build/Release/levelup')
return callback(err)
throw err
}
+ // reference to key to prevent premature GC
callback && callback(null, toEncoding(value, options.valueEncoding || options.encoding), key)
})
} else
@@ -118,7 +119,7 @@ var bridge = require('../build/Release/levelup')
return callback(err)
throw err
}
- callback && callback(null, key, value)
+ callback && callback(null, key, value) // reference to key&value to prevent premature GC
})
} else
callback(new errors.ReadError('Database has not been opened'))
@@ -137,7 +138,7 @@ var bridge = require('../build/Release/levelup')
return callback(err)
throw err
}
- callback && callback(null, key)
+ callback && callback(null, key) // reference to key to prevent premature GC
})
} else
callback(new errors.ReadError('Database has not been opened'))
@@ -145,22 +146,35 @@ var bridge = require('../build/Release/levelup')
, batch: function (arr, options_, callback_) {
var callback = getCallback(options_, callback_)
- , options
- if (this.isOpen()) {
- options = getOptions(options_, this.encoding)
- this.db.batch(arr, options, function (err) {
- if (err) {
- err = new errors.WriteError(err)
- if (callback)
- return callback(err)
- throw err
+ , options, keyEncoding, valueEncoding
+
+ if (!this.isOpen())
+ return callback(new errors.ReadError('Database has not been opened'))
+
+ options = getOptions(options_, this.encoding)
+ keyEncoding = options.keyEncoding || options.encoding
+ valueEncoding = options.valueEncoding || options.encoding
+ arr = arr.map(function (e) {
+ var o = {}
+ if (e.type) {
+ o.type = e.type
+ if (e.key) {
+ o.key = toBuffer(e.key, keyEncoding)
+ if (e.value)
+ o.value = toBuffer(e.value, valueEncoding)
}
- // reference to 'arr' important to keep from being garbage collected
- // we don't keep a Persistent<T> reference in the bridge
- callback && callback(null, arr)
- })
- } else
- callback(new errors.ReadError('Database has not been opened'))
+ }
+ return o
+ })
+ this.db.batch(arr, options, function (err) {
+ if (err) {
+ err = new errors.WriteError(err)
+ if (callback)
+ return callback(err)
+ throw err
+ }
+ callback && callback(null)
+ })
}
}
diff --git a/src/batch.cc b/src/batch.cc
index ef2309f..9a4ccd2 100644
--- a/src/batch.cc
+++ b/src/batch.cc
@@ -8,21 +8,18 @@
using namespace std;
BatchDelete::~BatchDelete () {
- if (keyPtr != NULL)
- delete keyPtr;
+ delete key;
}
void BatchDelete::Execute (WriteBatch* batch) {
- batch->Delete(key);
+ batch->Delete(Slice(*key));
}
BatchWrite::~BatchWrite () {
- if (keyPtr != NULL)
- delete keyPtr;
- if (valuePtr != NULL)
- delete valuePtr;
+ delete key;
+ delete value;
}
void BatchWrite::Execute (WriteBatch* batch) {
- batch->Put(key, value);
+ batch->Put(Slice(*key), Slice(*value));
}
\ No newline at end of file
diff --git a/src/batch.h b/src/batch.h
index eb1cd81..3860670 100644
--- a/src/batch.h
+++ b/src/batch.h
@@ -15,36 +15,29 @@ public:
class BatchDelete : public BatchOp {
public:
BatchDelete (
- Slice key
- , string* keyPtr
+ string* key
) : key(key)
- , keyPtr(keyPtr)
{};
~BatchDelete ();
virtual void Execute (WriteBatch* batch);
protected:
- Slice key;
- string* keyPtr;
+ string* key;
};
class BatchWrite : public BatchDelete {
public:
BatchWrite (
- Slice key
- , string* keyPtr
- , Slice value
- , string* valuePtr
- ) : BatchDelete(key, keyPtr)
+ string* key
+ , string* value
+ ) : BatchDelete(key)
, value(value)
- , valuePtr(valuePtr)
{};
~BatchWrite ();
virtual void Execute (WriteBatch* batch);
private:
- Slice value;
- string* valuePtr;
+ string* value;
};
#endif
\ No newline at end of file
diff --git a/src/database.cc b/src/database.cc
index 0f5452f..f9cc964 100644
--- a/src/database.cc
+++ b/src/database.cc
@@ -134,9 +134,9 @@ Handle<Value> Database::Put (const Arguments& args) {
Database* database = ObjectWrap::Unwrap<Database>(args.This());
- Local<Object> keyBuffer = args[0]->ToObject();
+ Persistent<Object> keyBuffer = Persistent<Object>::New(args[0]->ToObject());
Slice key(Buffer::Data(keyBuffer), Buffer::Length(keyBuffer));
- Local<Object> valueBuffer = args[1]->ToObject();
+ Persistent<Object> valueBuffer = Persistent<Object>::New(args[1]->ToObject());
Slice value(Buffer::Data(valueBuffer), Buffer::Length(valueBuffer));
Local<Object> optionsObj = Local<Object>::Cast(args[2]);
bool sync = optionsObj->Has(option_sync) && optionsObj->Get(option_sync)->BooleanValue();
@@ -148,8 +148,8 @@ Handle<Value> Database::Put (const Arguments& args) {
, key
, value
, sync
- , Persistent<Object>::New(keyBuffer)
- , Persistent<Object>::New(valueBuffer)
+ , keyBuffer
+ , valueBuffer
);
AsyncQueueWorker(worker);
@@ -160,7 +160,7 @@ Handle<Value> Database::Get (const Arguments& args) {
HandleScope scope;
Database* database = ObjectWrap::Unwrap<Database>(args.This());
- Local<Object> keyBuffer = args[0]->ToObject();
+ 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<Function> callback = Persistent<Function>::New(Local<Function>::Cast(args[2]));
@@ -169,7 +169,7 @@ Handle<Value> Database::Get (const Arguments& args) {
database
, callback
, key
- , Persistent<Object>::New(keyBuffer)
+ , keyBuffer
);
AsyncQueueWorker(worker);
@@ -180,7 +180,7 @@ Handle<Value> Database::Delete (const Arguments& args) {
HandleScope scope;
Database* database = ObjectWrap::Unwrap<Database>(args.This());
- Local<Object> keyBuffer = args[0]->ToObject();
+ 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]);
bool sync = optionsObj->Has(option_sync) && optionsObj->Get(option_sync)->BooleanValue();
@@ -191,7 +191,7 @@ Handle<Value> Database::Delete (const Arguments& args) {
, callback
, key
, sync
- , Persistent<Object>::New(keyBuffer)
+ , keyBuffer
);
AsyncQueueWorker(worker);
@@ -213,31 +213,19 @@ Handle<Value> Database::Batch (const Arguments& args) {
if (!obj->Has(str_type) || !obj->Has(str_key))
continue;
- Local<Object> keyObj = obj->Get(str_key)->ToObject();
- string* keyStr = NULL;
- Slice key;
- if (Buffer::HasInstance(keyObj))
- key = Slice(Buffer::Data(keyObj), Buffer::Length(keyObj));
- else {
- keyStr = new string(ToCString(String::Utf8Value(keyObj->ToString())));
- key = *keyStr;
- }
+ Local<Object> keyBuffer = obj->Get(str_key)->ToObject();
+ if (!keyBuffer->IsObject() || !Buffer::HasInstance(keyBuffer))
+ continue;
+ string* key = new string(Buffer::Data(keyBuffer), Buffer::Length(keyBuffer));
if (obj->Get(str_type)->StrictEquals(str_del)) {
- operations.push_back(new BatchDelete(key, keyStr));
- } else if (obj->Get(str_type)->StrictEquals(str_put)) {
- if (obj->Has(str_value)) {
- Local<Object> valueObj = obj->Get(str_value)->ToObject();
- string* valueStr = NULL;
- Slice value;
- if (Buffer::HasInstance(valueObj))
- value = Slice(Buffer::Data(valueObj), Buffer::Length(valueObj));
- else {
- valueStr = new string(ToCString(String::Utf8Value(valueObj->ToString())));
- value = *valueStr;
- }
- operations.push_back(new BatchWrite(key, keyStr, value, valueStr));
- }
+ operations.push_back(new BatchDelete(key));
+ } else if (obj->Get(str_type)->StrictEquals(str_put) && obj->Has(str_value)) {
+ Local<Object> valueBuffer = obj->Get(str_value)->ToObject();
+ if (!valueBuffer->IsObject() || !Buffer::HasInstance(valueBuffer))
+ continue;
+ string* value = new string(Buffer::Data(valueBuffer), Buffer::Length(valueBuffer));
+ operations.push_back(new BatchWrite(key, value));
}
}
diff --git a/test/binary-test.js b/test/binary-test.js
index d754879..1fd8464 100644
--- a/test/binary-test.js
+++ b/test/binary-test.js
@@ -8,6 +8,8 @@ var buster = require('buster')
, async = require('async')
, fs = require('fs')
+require('./common.js')
+
buster.testCase('Binary API', {
'setUp': function (done) {
this.cleanupDirs = []
@@ -92,4 +94,52 @@ buster.testCase('Binary API', {
}.bind(this))
}.bind(this))
}
+
+
+ , 'test put() and del() and get() with binary key {encoding:binary}': function (done) {
+ this.openTestDatabase(function (db) {
+ db.put(this.testData, 'binarydata', {encoding:'binary'}, function (err) {
+ refute(err)
+ db.del(this.testData, {encoding:'binary'}, function (err) {
+ db.get(this.testData, {encoding:'binary'}, function (err, value) {
+ assert(err)
+ done()
+ }.bind(this))
+ }.bind(this))
+ }.bind(this))
+ }.bind(this))
+ }
+
+ , 'batch() with multiple puts': function (done) {
+ this.openTestDatabase(function (db) {
+ db.batch(
+ [
+ { type: 'put', key: 'foo', value: this.testData }
+ , { type: 'put', key: 'bar', value: this.testData }
+ , { type: 'put', key: 'baz', value: 'abazvalue' }
+ ]
+ , {keyEncoding:'utf8',valueEncoding:'binary'}
+ , function (err) {
+ refute(err)
+ async.forEach(
+ ['foo', 'bar', 'baz']
+ , function (key, callback) {
+ db.get(key, {encoding:'binary'}, function (err, value) {
+ refute(err)
+ if (key == 'baz') {
+ assert.equals(value, 'a' + key + 'value')
+ callback()
+ } else {
+ checkBinaryTestData(value, callback)
+ }
+ })
+ }
+ , done
+ )
+ }.bind(this)
+ )
+ }.bind(this))
+ }
+
+
})
\ No newline at end of file
--
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