[Pkg-javascript-commits] [node-leveldown] 08/11: New upstream version 1.5.0+dfsg

Jérémy Lal kapouer at moszumanska.debian.org
Tue Dec 20 15:11:20 UTC 2016


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

kapouer pushed a commit to branch master
in repository node-leveldown.

commit 5ed79e1c41f5c456f974a648bb48506a44f852ad
Author: Jérémy Lal <kapouer at melix.org>
Date:   Tue Dec 20 16:05:47 2016 +0100

    New upstream version 1.5.0+dfsg
---
 .gitignore                      |   2 +-
 .prebuildrc                     |  17 ------
 .travis.yml                     |  26 +++++----
 LICENSE.md                      |   2 +-
 README.md                       |  41 +++++++++-----
 bench/memory.js                 | 100 ++++++++++++++++++++++++++++++++
 iterator.js                     |   3 +-
 package.json                    |  21 +++----
 src/async.h                     |   2 +-
 src/batch.cc                    |   9 ++-
 src/batch_async.cc              |   2 +-
 src/batch_async.h               |   2 +-
 src/common.h                    |   4 +-
 src/database.cc                 |  11 +++-
 src/database.h                  |   2 +-
 src/database_async.cc           |   2 +-
 src/database_async.h            |   2 +-
 src/iterator.cc                 | 123 +++++++++++++++++++++++++++-------------
 src/iterator.h                  |   5 +-
 src/iterator_async.cc           |   3 +-
 src/iterator_async.h            |   2 +-
 src/leveldown.cc                |   2 +-
 src/leveldown.h                 |  21 ++++++-
 src/leveldown_async.cc          |   2 +-
 src/leveldown_async.h           |   2 +-
 test/compression-test.js        |   2 +-
 test/iterator-recursion-test.js |  15 ++---
 test/repair-test.js             |   7 ++-
 28 files changed, 307 insertions(+), 125 deletions(-)

diff --git a/.gitignore b/.gitignore
index 406eada..eb86a1d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,10 @@
 node_modules/
 build/
 build-pre-gyp/
+Release/
 libleveldb.so
 libleveldb.a
 leakydb
-bench/
 *.sln
 *.vcxproj
 *.vcxproj.filters
diff --git a/.prebuildrc b/.prebuildrc
deleted file mode 100644
index 55d59d2..0000000
--- a/.prebuildrc
+++ /dev/null
@@ -1,17 +0,0 @@
-# abi 11
-target[] = 0.10.40
-
-# abi 14
-target[] = 0.12.7
-
-# abi 42
-target[] = 1.0.4
-
-# abi 43
-target[] = 1.8.4
-
-# abi 44
-target[] = 2.4.0
-
-# abi 45
-target[] = 3.0.0
diff --git a/.travis.yml b/.travis.yml
index f28850b..99a769e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,19 +1,23 @@
+sudo: false
+
 language: node_js
 
+env:
+  - CXX=g++-4.8
+
+addons:
+  apt:
+    sources:
+      - ubuntu-toolchain-r-test
+    packages:
+      - g++-4.8
+
 before_install:
   - export JOBS=max
-  - export prebuild_compile=true
 
 node_js:
-  - "2.4"
-  - "1.8"
-  - "1.0"
+  - "6"
+  - "5"
+  - "4"
   - "0.12"
   - "0.10"
-
-install:
-  - npm install
-
-script:
-  - npm test
-
diff --git a/LICENSE.md b/LICENSE.md
index 29b95e3..7b9c5a5 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,7 +1,7 @@
 The MIT License (MIT)
 =====================
 
-Copyright (c) 2014 Rod Vagg
+Copyright (c) 2016 Rod Vagg
 ---------------------------
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
diff --git a/README.md b/README.md
index 6af6a89..3f98b41 100644
--- a/README.md
+++ b/README.md
@@ -3,10 +3,10 @@ LevelDOWN
 
 <img alt="LevelDB Logo" height="100" src="http://leveldb.org/img/logo.svg">
 
-A Low-level Node.js LevelDB binding
--------------------------
+**A Low-level Node.js LevelDB binding**
 
 [![Build Status](https://secure.travis-ci.org/Level/leveldown.png)](http://travis-ci.org/Level/leveldown)
+[![dependencies](https://david-dm.org/Level/leveldown.svg)](https://david-dm.org/level/leveldown)
 
 [![NPM](https://nodei.co/npm/leveldown.png?stars&downloads&downloadRank)](https://nodei.co/npm/leveldown/) [![NPM](https://nodei.co/npm-dl/leveldown.png?months=6&height=3)](https://nodei.co/npm/leveldown/)
 
@@ -85,7 +85,7 @@ The following options are for advanced performance tuning. Modify them only if y
 
 * `'maxOpenFiles'` *(number, default: `1000`)*: The maximum number of files that LevelDB is allowed to have open at a time. If your data store is likely to have a large working set, you may increase this value to prevent file descriptor churn. To calculate the number of files required for your working set, divide your total data by 2MB, as each table file is a maximum of 2MB. 
 
-* `'blockRestartInterval'` *(number, default: `16`)*: The number of entries before restarting the "delta encoding" of keys within blocks. Each "restart" point stores the full key for the entry, between restarts, the common prefix of the keys for those entries is omitted. Restarts are similar to the concept of keyframs in video encoding and are used to minimise the amount of space required to store keys. This is particularly helpful when using deep namespacing / prefixing in your keys.
+* `'blockRestartInterval'` *(number, default: `16`)*: The number of entries before restarting the "delta encoding" of keys within blocks. Each "restart" point stores the full key for the entry, between restarts, the common prefix of the keys for those entries is omitted. Restarts are similar to the concept of keyframes in video encoding and are used to minimise the amount of space required to store keys. This is particularly helpful when using deep namespacing / prefixing in your keys.
 
 
 --------------------------------------------------------
@@ -125,7 +125,7 @@ The optional `options` object may contain:
 
 * `'fillCache'` *(boolean, default: `true`)*: LevelDB will by default fill the in-memory LRU Cache with data from a call to get. Disabling this is done by setting `fillCache` to `false`.
 
-* `'asBuffer'` *(boolean, default: `true`)*: Used to determine whether to return the `value` of the entry as a `String` or a Node.js `Buffer` object. Note that converting from a `Buffer` to a `String` incurs a cost so if you need a `String` (and the `value` can legitimately become a UFT8 string) then you should fetch it as one with `asBuffer: true` and you'll avoid this conversion cost.
+* `'asBuffer'` *(boolean, default: `true`)*: Used to determine whether to return the `value` of the entry as a `String` or a Node.js `Buffer` object. Note that converting from a `Buffer` to a `String` incurs a cost so if you need a `String` (and the `value` can legitimately become a UTF8 string) then you should fetch it as one with `asBuffer: true` and you'll avoid this conversion cost.
 
 The `callback` function will be called with a single `error` if the operation failed for any reason. If successful the first argument will be `null` and the second argument will be the `value` as a `String` or `Buffer` depending on the `asBuffer` option.
 
@@ -147,7 +147,9 @@ The `callback` function will be called with no arguments if the operation is suc
 --------------------------------------------------------
 <a name="leveldown_batch"></a>
 ### leveldown#batch(operations[, options], callback)
-<code>batch()</code> is an instance method on an existing database object. Used for very fast bulk-write operations (both *put* and *delete*). The `operations` argument should be an `Array` containing a list of operations to be executed sequentially, although as a whole they are performed as an atomic operation inside LevelDB. Each operation is contained in an object having the following properties: `type`, `key`, `value`, where the *type* is either `'put'` or `'del'`. In the case of `'d [...]
+<code>batch()</code> is an instance method on an existing database object. Used for very fast bulk-write operations (both *put* and *delete*). The `operations` argument should be an `Array` containing a list of operations to be executed sequentially, although as a whole they are performed as an atomic operation inside LevelDB.
+
+Each operation is contained in an object having the following properties: `type`, `key`, `value`, where the *type* is either `'put'` or `'del'`. In the case of `'del'` the `'value'` property is ignored. Any entries with a `'key'` of `null` or `undefined` will cause an error to be returned on the `callback`. Any entries where the *type* is `'put'` that have a `'value'` of `undefined`, `null`, `[]`, `''` or `new Buffer(0)` will be stored as a zero-length character array and therefore be fe [...]
 
 See [LevelUP](https://github.com/level/levelup#batch) for full documentation on how this works in practice.
 
@@ -191,13 +193,13 @@ Currently, the only valid properties are:
 
 The optional `options` object may contain:
 
-* `'gt'` (greater than), `'gte'` (greater than or equal) define the lower bound of the values to be fetched and will determine the starting point where `'reverse'` is not `true`. Only records where the key is greater than (or equal to) this option will be included in the range. When `'reverse'` is 'true` the order will be reversed, but the records returned will be the same.
+* `'gt'` (greater than), `'gte'` (greater than or equal) define the lower bound of the values to be fetched and will determine the starting point where `'reverse'` is *not* `true`. Only records where the key is greater than (or equal to) this option will be included in the range. When `'reverse'` is `true` the order will be reversed, but the records returned will be the same.
 
-* `'lt'` (less than), `'lte'` (less than or equal) define the higher bound of the range to be fetched and will determine the starting poitn where `'reverse'` is *not* `true`. Only key / value pairs where the key is less than (or equal to) this option will be included in the range. When `'reverse'` is `true` the order will be reversed, but the records returned will be the same.
+* `'lt'` (less than), `'lte'` (less than or equal) define the higher bound of the range to be fetched and will determine the starting point where `'reverse'` is *not* `true`. Only records where the key is less than (or equal to) this option will be included in the range. When `'reverse'` is `true` the order will be reversed, but the records returned will be the same.
 
 * `'start', 'end'` legacy ranges - instead use `'gte', 'lte'`
 
-* `'reverse'` *(boolean, default: `false`)*: a boolean, set to true if you want the stream to go in reverse order. Beware that due to the way LevelDB works, a reverse seek will be slower than a forward seek.
+* `'reverse'` *(boolean, default: `false`)*: a boolean, set to `true` if you want the stream to go in reverse order. Beware that due to the way LevelDB works, a reverse seek will be slower than a forward seek.
 
 * `'keys'` *(boolean, default: `true`)*: whether the callback to the `next()` method should receive a non-null `key`. There is a small efficiency gain if you ultimately don't care what the keys are as they don't need to be converted and copied into JavaScript.
 
@@ -205,9 +207,9 @@ The optional `options` object may contain:
 
 * `'limit'` *(number, default: `-1`)*: limit the number of results collected by this iterator. This number represents a *maximum* number of results and may not be reached if you get to the end of the store or your `'end'` value first. A value of `-1` means there is no limit.
 
-* `'fillCache'` *(boolean, default: `false`)*: wheather LevelDB's LRU-cache should be filled with data read.
+* `'fillCache'` *(boolean, default: `false`)*: whether LevelDB's LRU-cache should be filled with data read.
 
-* `'keyAsBuffer'` *(boolean, default: `true`)*: Used to determine whether to return the `key` of each entry as a `String` or a Node.js `Buffer` object. Note that converting from a `Buffer` to a `String` incurs a cost so if you need a `String` (and the `value` can legitimately become a UFT8 string) then you should fetch it as one.
+* `'keyAsBuffer'` *(boolean, default: `true`)*: Used to determine whether to return the `key` of each entry as a `String` or a Node.js `Buffer` object. Note that converting from a `Buffer` to a `String` incurs a cost so if you need a `String` (and the `value` can legitimately become a UTF8 string) then you should fetch it as one.
 
 * `'valueAsBuffer'` *(boolean, default: `true`)*: Used to determine whether to return the `value` of each entry as a `String` or a Node.js `Buffer` object.
 
@@ -235,7 +237,7 @@ Otherwise, the `callback` function will be called with the following 3 arguments
 ### iterator#seek(key)
 <code>seek()</code> is an instance method on an existing iterator object, used to seek the underlying LevelDB iterator to a given key.
 
-By calling <code>seek(key)</code>, subsequent calls to <code>next(cb)</code> will return key/values larger or smaller than key, based on your <code>reverse</code> setting in the iterator constructor.
+By calling <code>seek(key)</code>, subsequent calls to <code>next(cb)</code> will return key/values larger or smaller than `key`, based on your <code>reverse</code> setting in the iterator constructor.
 
 --------------------------------------------------------
 <a name="iterator_end"></a>
@@ -250,6 +252,7 @@ By calling <code>seek(key)</code>, subsequent calls to <code>next(cb)</code> wil
 
 The callback will be called when the destroy operation is complete, with a possible `error` argument.
 
+--------------------------------------------------------
 <a name="leveldown_repair"></a>
 ### leveldown.repair(location, callback)
 <code>repair()</code> can be used to attempt a restoration of a damaged LevelDB store. From the LevelDB documentation:
@@ -307,13 +310,25 @@ A large portion of the Windows support comes from code by [Krzysztof Kowalczyk](
 Prebuilt binaries
 -----------------
 
-LevelDOWN uses `node-pre-gyp` to support prebuilt binaries. For a list of supported prebuilt platform binaries see https://github.com/Level/leveldown/releases
+LevelDOWN uses `prebuild` to support prebuilt binaries. See [this list](https://github.com/Level/leveldown/releases) of supported prebuilt platform binaries. When installing LevelDOWN `prebuild --download` will download prebuilt binaries from GitHub if they exist and fallback to a compile step if they don't.
+
+If you are working on LevelDOWN and want to compile the C++ code you can do:
+
+```
+$ npm run rebuild [--debug] [--verbose]
+```
+
+or
+
+```
+$ npm i --build-from-source [--debug] [--verbose]
+```
 
 <a name="license"></a>
 License & copyright
 -------------------
 
-Copyright © 2012-2015 **LevelDOWN** [contributors](https://github.com/level/community#contributors).
+Copyright © 2012-2016 **LevelDOWN** [contributors](https://github.com/level/community#contributors).
 
 **LevelDOWN** is licensed under the MIT license. All rights not explicitly granted in the MIT license are reserved. See the included `LICENSE.md` file for more details.
 
diff --git a/bench/memory.js b/bench/memory.js
new file mode 100644
index 0000000..6fe4588
--- /dev/null
+++ b/bench/memory.js
@@ -0,0 +1,100 @@
+var leveldown = require('../')
+
+var addr = '1111111111111111111114oLvT2'
+
+var db = leveldown(process.env.HOME + '/iterleak.db')
+var records = {
+  'w/a/14r6JPSJNzBXXJEM2jnmoybQCw3arseKuY/primary': '00',
+  'w/a/17nJuKqjTyAeujSJnPCebpSTEz1v9kjNKg/primary': '00',
+  'w/a/18cxWLCiJMESL34Ev1LJ2meGTgL14bAxfj/primary': '00',
+  'w/a/18pghEAnqCRTrjd7iyUj6XNKmSNx4fAywB/primary': '00',
+  'w/a/19EWPPzY6XkQeM7DxqJ4THbY3DGekRQKbt/primary': '00',
+  'w/a/1DKDeLQyBCkV5aMG15XbAdpwwHnxqw9rvY/primary': '00',
+  'w/a/1HSJAoU5TaGKhAJxwpTC1imiMM1ab8SFGW/primary': '00',
+  'w/a/1HkeafxVvStf2Np6wxUjkTpCt1gTDJSLpi/primary': '00',
+  'w/a/1Hr5JduPFdZ4n4dHBUqRoxLQEG4P93C658/primary': '00',
+  'w/a/1KATodK9Ko8MchJZzDxLhjWz4d8oAuCqEh/primary': '00',
+  'w/a/1NhRKhiAAJrmwXoLhL9dGG1z6oMiFGrxZ7/primary': '00',
+  'w/a/1yTq3DpyUNqUCxDttczGjufbEBKAXMTSq/primary': '00',
+  'w/w/primary': '00'
+}
+
+db.open({
+  createIfMissing: true,
+  errorIfExists: false,
+  compression: true,
+  cacheSize: 8 << 20,
+  writeBufferSize: 4 << 20,
+  maxOpenFiles: 8192
+}, function(err) {
+  if (err)
+    throw err
+
+  memory()
+
+  var batch = db.batch();
+  Object.keys(records).forEach(function(key) {
+    var value = new Buffer(records[key], 'hex')
+    batch.put(key, value)
+  })
+
+  batch.write(function(err) {
+    if (err)
+      throw err
+
+    // This will leak roughly 1mb per call.
+    setTimeout(function self() {
+      var i = 0
+      ;(function next(err) {
+        if (err)
+          throw err
+        if (i++ >= 10000) {
+          memory()
+          return setTimeout(self, 1000)
+        }
+        iterate(addr, next)
+      })()
+    }, 1000)
+  })
+})
+
+function memory() {
+  var mem = process.memoryUsage()
+  console.log('Memory: rss=%dmb, js-heap=%d/%dmb native-heap=%dmb',
+              mb(mem.rss),
+              mb(mem.heapUsed),
+              mb(mem.heapTotal),
+              mb(mem.rss - mem.heapTotal))
+}
+
+function mb(size) {
+  return size / 1024 / 1024 | 0
+}
+
+function iterate(address, callback) {
+  var iter = db.iterator({
+    gte: 'w/a/' + address,
+    lte: 'w/a/' + address + '~',
+    keys: true,
+    values: false,
+    fillCache: false,
+    keyAsBuffer: false
+  })
+
+  ;(function next() {
+    iter.next(function(err, key, value) {
+      if (err) {
+        return iter.end(function(e) {
+          if (e)
+            throw e
+          callback(err)
+        })
+      }
+
+      if (key === undefined)
+        return iter.end(callback)
+
+      next()
+    })
+  })()
+}
diff --git a/iterator.js b/iterator.js
index 4c8c3a7..d5181a6 100644
--- a/iterator.js
+++ b/iterator.js
@@ -1,5 +1,6 @@
 const util             = require('util')
     , AbstractIterator = require('abstract-leveldown').AbstractIterator
+    , fastFuture       = require('fast-future')
 
 
 function Iterator (db, options) {
@@ -8,7 +9,7 @@ function Iterator (db, options) {
   this.binding    = db.binding.iterator(options)
   this.cache      = null
   this.finished   = false
-  this.fastFuture = require('fast-future')()
+  this.fastFuture = fastFuture()
 }
 
 util.inherits(Iterator, AbstractIterator)
diff --git a/package.json b/package.json
index 346864c..db303cd 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "name": "leveldown",
   "description": "A Node.js LevelDB binding, primary backend for LevelUP",
-  "version": "1.4.1",
+  "version": "1.5.0",
   "contributors": [
     "Rod Vagg <r at va.gg> (https://github.com/rvagg)",
     "John Chesley <john at chesl.es> (https://github.com/chesles/)",
@@ -28,30 +28,31 @@
   ],
   "main": "leveldown.js",
   "dependencies": {
-    "abstract-leveldown": "~2.4.0",
+    "abstract-leveldown": "~2.6.1",
     "bindings": "~1.2.1",
     "fast-future": "~1.0.0",
-    "nan": "~2.0.0",
-    "prebuild": "~2.3.3"
+    "nan": "~2.4.0",
+    "prebuild": "^4.1.1"
   },
   "devDependencies": {
-    "async": "~1.0.0",
+    "async": "^2.0.1",
     "delayed": "~1.0.1",
     "du": "~0.1.0",
     "faucet": "0.0.1",
-    "mkfiletree": "~0.0.1",
+    "mkfiletree": "~1.0.1",
     "monotonic-timestamp": "~0.0.8",
     "node-uuid": "~1.4.3",
     "optimist": "~0.6.1",
     "readfiletree": "~0.0.1",
-    "rimraf": "~2.2.8",
+    "rimraf": "~2.5.0",
     "slump": "~2.0.0",
-    "tape": "~4.0.0"
+    "tape": "^4.5.1"
   },
   "scripts": {
-    "install": "prebuild --download",
+    "install": "prebuild --install",
     "test": "tape test/*-test.js | faucet",
-    "prebuild": "prebuild --verbose"
+    "rebuild": "prebuild --compile",
+    "prebuild": "prebuild --all --strip --verbose"
   },
   "license": "MIT",
   "gypfile": true
diff --git a/src/async.h b/src/async.h
index bcce316..665f85b 100644
--- a/src/async.h
+++ b/src/async.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015 LevelDOWN contributors
+/* Copyright (c) 2012-2016 LevelDOWN contributors
  * See list at <https://github.com/level/leveldown#contributing>
  * MIT License <https://github.com/level/leveldown/blob/master/LICENSE.md>
  */
diff --git a/src/batch.cc b/src/batch.cc
index 23a8a3d..97f0676 100644
--- a/src/batch.cc
+++ b/src/batch.cc
@@ -61,6 +61,7 @@ v8::Local<v8::Value> Batch::NewInstance (
 
   Nan::EscapableHandleScope scope;
 
+  Nan::MaybeLocal<v8::Object> maybeInstance;
   v8::Local<v8::Object> instance;
 
   v8::Local<v8::FunctionTemplate> constructorHandle =
@@ -68,12 +69,16 @@ v8::Local<v8::Value> Batch::NewInstance (
 
   if (optionsObj.IsEmpty()) {
     v8::Local<v8::Value> argv[1] = { database };
-    instance = constructorHandle->GetFunction()->NewInstance(1, argv);
+    maybeInstance = Nan::NewInstance(constructorHandle->GetFunction(), 1, argv);
   } else {
     v8::Local<v8::Value> argv[2] = { database, optionsObj };
-    instance = constructorHandle->GetFunction()->NewInstance(2, argv);
+    maybeInstance = Nan::NewInstance(constructorHandle->GetFunction(), 2, argv);
   }
 
+  if (maybeInstance.IsEmpty())
+      Nan::ThrowError("Could not create new Batch instance");
+  else
+    instance = maybeInstance.ToLocalChecked();
   return scope.Escape(instance);
 }
 
diff --git a/src/batch_async.cc b/src/batch_async.cc
index f840f24..651fbe5 100644
--- a/src/batch_async.cc
+++ b/src/batch_async.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015 LevelDOWN contributors
+/* Copyright (c) 2012-2016 LevelDOWN contributors
  * See list at <https://github.com/level/leveldown#contributing>
  * MIT License <https://github.com/level/leveldown/blob/master/LICENSE.md>
  */
diff --git a/src/batch_async.h b/src/batch_async.h
index 72587b9..09b9510 100644
--- a/src/batch_async.h
+++ b/src/batch_async.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015 LevelDOWN contributors
+/* Copyright (c) 2012-2016 LevelDOWN contributors
  * See list at <https://github.com/level/leveldown#contributing>
  * MIT License <https://github.com/level/leveldown/blob/master/LICENSE.md>
  */
diff --git a/src/common.h b/src/common.h
index 1eca681..c7d2640 100644
--- a/src/common.h
+++ b/src/common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015 LevelDOWN contributors
+/* Copyright (c) 2012-2016 LevelDOWN contributors
  * See list at <https://github.com/level/leveldown#contributing>
  * MIT License <https://github.com/level/leveldown/blob/master/LICENSE.md>
  */
@@ -13,6 +13,7 @@ namespace leveldown {
 NAN_INLINE bool BooleanOptionValue(v8::Local<v8::Object> options,
                                    const char* _key,
                                    bool def = false) {
+  Nan::HandleScope scope;
   v8::Local<v8::String> key = Nan::New(_key).ToLocalChecked();
   return !options.IsEmpty()
     && options->Has(key)
@@ -23,6 +24,7 @@ NAN_INLINE bool BooleanOptionValue(v8::Local<v8::Object> options,
 NAN_INLINE uint32_t UInt32OptionValue(v8::Local<v8::Object> options,
                                       const char* _key,
                                       uint32_t def) {
+  Nan::HandleScope scope;
   v8::Local<v8::String> key = Nan::New(_key).ToLocalChecked();
   return !options.IsEmpty()
     && options->Has(key)
diff --git a/src/database.cc b/src/database.cc
index c3ea44b..a799e05 100644
--- a/src/database.cc
+++ b/src/database.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015 LevelDOWN contributors
+/* Copyright (c) 2012-2016 LevelDOWN contributors
  * See list at <https://github.com/level/leveldown#contributing>
  * MIT License <https://github.com/level/leveldown/blob/master/LICENSE.md>
  */
@@ -157,14 +157,19 @@ NAN_METHOD(Database::New) {
 v8::Local<v8::Value> Database::NewInstance (v8::Local<v8::String> &location) {
   Nan::EscapableHandleScope scope;
 
+  Nan::MaybeLocal<v8::Object> maybeInstance;
   v8::Local<v8::Object> instance;
 
   v8::Local<v8::FunctionTemplate> constructorHandle =
       Nan::New<v8::FunctionTemplate>(database_constructor);
 
   v8::Local<v8::Value> argv[] = { location };
-  instance = constructorHandle->GetFunction()->NewInstance(1, argv);
+  maybeInstance = Nan::NewInstance(constructorHandle->GetFunction(), 1, argv);
 
+  if (maybeInstance.IsEmpty())
+      Nan::ThrowError("Could not create new Database instance");
+  else
+    instance = maybeInstance.ToLocalChecked();
   return scope.Escape(instance);
 }
 
@@ -455,7 +460,7 @@ NAN_METHOD(Database::Iterator) {
   // each iterator gets a unique id for this Database, so we can
   // easily store & lookup on our `iterators` map
   uint32_t id = database->currentIteratorId++;
-  v8::TryCatch try_catch;
+  Nan::TryCatch try_catch;
   v8::Local<v8::Object> iteratorHandle = Iterator::NewInstance(
       info.This()
     , Nan::New<v8::Number>(id)
diff --git a/src/database.h b/src/database.h
index dd833ee..e16e6c7 100644
--- a/src/database.h
+++ b/src/database.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015 LevelDOWN contributors
+/* Copyright (c) 2012-2016 LevelDOWN contributors
  * See list at <https://github.com/level/leveldown#contributing>
  * MIT License <https://github.com/level/leveldown/blob/master/LICENSE.md>
  */
diff --git a/src/database_async.cc b/src/database_async.cc
index b5533bd..a15efaa 100644
--- a/src/database_async.cc
+++ b/src/database_async.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015 LevelDOWN contributors
+/* Copyright (c) 2012-2016 LevelDOWN contributors
  * See list at <https://github.com/level/leveldown#contributing>
  * MIT License <https://github.com/level/leveldown/blob/master/LICENSE.md>
  */
diff --git a/src/database_async.h b/src/database_async.h
index e0a8f80..a501f5a 100644
--- a/src/database_async.h
+++ b/src/database_async.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015 LevelDOWN contributors
+/* Copyright (c) 2012-2016 LevelDOWN contributors
  * See list at <https://github.com/level/leveldown#contributing>
  * MIT License <https://github.com/level/leveldown/blob/master/LICENSE.md>
  */
diff --git a/src/iterator.cc b/src/iterator.cc
index 37c5ede..5ac0bf6 100644
--- a/src/iterator.cc
+++ b/src/iterator.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015 LevelDOWN contributors
+/* Copyright (c) 2012-2016 LevelDOWN contributors
  * See list at <https://github.com/level/leveldown#contributing>
  * MIT License <https://github.com/level/leveldown/blob/master/LICENSE.md>
  */
@@ -31,7 +31,6 @@ Iterator::Iterator (
   , bool fillCache
   , bool keyAsBuffer
   , bool valueAsBuffer
-  , v8::Local<v8::Object> &startHandle
   , size_t highWaterMark
 ) : database(database)
   , id(id)
@@ -51,11 +50,6 @@ Iterator::Iterator (
 {
   Nan::HandleScope scope;
 
-  v8::Local<v8::Object> obj = Nan::New<v8::Object>();
-  if (!startHandle.IsEmpty())
-    obj->Set(Nan::New("start").ToLocalChecked(), startHandle);
-  persistentHandle.Reset(obj);
-
   options    = new leveldb::ReadOptions();
   options->fill_cache = fillCache;
   // get a snapshot of the current state
@@ -70,12 +64,27 @@ Iterator::Iterator (
 
 Iterator::~Iterator () {
   delete options;
-  if (!persistentHandle.IsEmpty())
-    persistentHandle.Reset();
-  if (start != NULL)
+  if (start != NULL) {
+    // Special case for `start` option: it won't be
+    // freed up by any of the delete calls below.
+    if (!((lt != NULL && reverse)
+        || (lte != NULL && reverse)
+        || (gt != NULL && !reverse)
+        || (gte != NULL && !reverse))) {
+      delete[] start->data();
+    }
     delete start;
+  }
   if (end != NULL)
     delete end;
+  if (lt != NULL)
+    delete lt;
+  if (gt != NULL)
+    delete gt;
+  if (lte != NULL)
+    delete lte;
+  if (gte != NULL)
+    delete gte;
 };
 
 bool Iterator::GetIterator () {
@@ -189,6 +198,7 @@ void Iterator::IteratorEnd () {
   //TODO: could return it->status()
   delete dbIterator;
   dbIterator = NULL;
+  database->ReleaseSnapshot(options->snapshot);
 }
 
 void Iterator::Release () {
@@ -312,28 +322,29 @@ v8::Local<v8::Object> Iterator::NewInstance (
 
   Nan::EscapableHandleScope scope;
 
+  Nan::MaybeLocal<v8::Object> maybeInstance;
   v8::Local<v8::Object> instance;
   v8::Local<v8::FunctionTemplate> constructorHandle =
       Nan::New<v8::FunctionTemplate>(iterator_constructor);
 
   if (optionsObj.IsEmpty()) {
     v8::Local<v8::Value> argv[2] = { database, id };
-    instance = constructorHandle->GetFunction()->NewInstance(2, argv);
+    maybeInstance = Nan::NewInstance(constructorHandle->GetFunction(), 2, argv);
   } else {
     v8::Local<v8::Value> argv[3] = { database, id, optionsObj };
-    instance = constructorHandle->GetFunction()->NewInstance(3, argv);
+    maybeInstance = Nan::NewInstance(constructorHandle->GetFunction(), 3, argv);
   }
 
+  if (maybeInstance.IsEmpty())
+      Nan::ThrowError("Could not create new Iterator instance");
+  else
+    instance = maybeInstance.ToLocalChecked();
   return scope.Escape(instance);
 }
 
 NAN_METHOD(Iterator::New) {
   Database* database = Nan::ObjectWrap::Unwrap<Database>(info[0]->ToObject());
 
-  //TODO: remove this, it's only here to make LD_STRING_OR_BUFFER_TO_SLICE happy
-  v8::Local<v8::Function> callback;
-
-  v8::Local<v8::Object> startHandle;
   leveldb::Slice* start = NULL;
   std::string* end = NULL;
   int limit = -1;
@@ -349,6 +360,7 @@ NAN_METHOD(Iterator::New) {
   v8::Local<v8::Object> gtHandle;
   v8::Local<v8::Object> gteHandle;
 
+  char *startStr = NULL;
   std::string* lt = NULL;
   std::string* lte = NULL;
   std::string* gt = NULL;
@@ -366,12 +378,13 @@ NAN_METHOD(Iterator::New) {
         && (node::Buffer::HasInstance(optionsObj->Get(Nan::New("start").ToLocalChecked()))
           || optionsObj->Get(Nan::New("start").ToLocalChecked())->IsString())) {
 
-      startHandle = optionsObj->Get(Nan::New("start").ToLocalChecked()).As<v8::Object>();
+      v8::Local<v8::Value> startBuffer = optionsObj->Get(Nan::New("start").ToLocalChecked());
 
       // ignore start if it has size 0 since a Slice can't have length 0
-      if (StringOrBufferLength(startHandle) > 0) {
-        LD_STRING_OR_BUFFER_TO_SLICE(_start, startHandle, start)
-        start = new leveldb::Slice(_start.data(), _start.size());
+      if (StringOrBufferLength(startBuffer) > 0) {
+        LD_STRING_OR_BUFFER_TO_COPY(_start, startBuffer, start)
+        start = new leveldb::Slice(_startCh_, _startSz_);
+        startStr = _startCh_;
       }
     }
 
@@ -383,8 +396,9 @@ NAN_METHOD(Iterator::New) {
 
       // ignore end if it has size 0 since a Slice can't have length 0
       if (StringOrBufferLength(endBuffer) > 0) {
-        LD_STRING_OR_BUFFER_TO_SLICE(_end, endBuffer, end)
-        end = new std::string(_end.data(), _end.size());
+        LD_STRING_OR_BUFFER_TO_COPY(_end, endBuffer, end)
+        end = new std::string(_endCh_, _endSz_);
+        delete[] _endCh_;
       }
     }
 
@@ -406,10 +420,18 @@ NAN_METHOD(Iterator::New) {
 
       // ignore end if it has size 0 since a Slice can't have length 0
       if (StringOrBufferLength(ltBuffer) > 0) {
-        LD_STRING_OR_BUFFER_TO_SLICE(_lt, ltBuffer, lt)
-        lt = new std::string(_lt.data(), _lt.size());
-        if (reverse)
-          start = new leveldb::Slice(_lt.data(), _lt.size());
+        LD_STRING_OR_BUFFER_TO_COPY(_lt, ltBuffer, lt)
+        lt = new std::string(_ltCh_, _ltSz_);
+        delete[] _ltCh_;
+        if (reverse) {
+          if (startStr != NULL) {
+            delete[] startStr;
+            startStr = NULL;
+          }
+          if (start != NULL)
+            delete start;
+          start = new leveldb::Slice(lt->data(), lt->size());
+        }
       }
     }
 
@@ -421,10 +443,18 @@ NAN_METHOD(Iterator::New) {
 
       // ignore end if it has size 0 since a Slice can't have length 0
       if (StringOrBufferLength(lteBuffer) > 0) {
-        LD_STRING_OR_BUFFER_TO_SLICE(_lte, lteBuffer, lte)
-        lte = new std::string(_lte.data(), _lte.size());
-        if (reverse)
-          start = new leveldb::Slice(_lte.data(), _lte.size());
+        LD_STRING_OR_BUFFER_TO_COPY(_lte, lteBuffer, lte)
+        lte = new std::string(_lteCh_, _lteSz_);
+        delete[] _lteCh_;
+        if (reverse) {
+          if (startStr != NULL) {
+            delete[] startStr;
+            startStr = NULL;
+          }
+          if (start != NULL)
+            delete start;
+          start = new leveldb::Slice(lte->data(), lte->size());
+        }
       }
     }
 
@@ -436,10 +466,18 @@ NAN_METHOD(Iterator::New) {
 
       // ignore end if it has size 0 since a Slice can't have length 0
       if (StringOrBufferLength(gtBuffer) > 0) {
-        LD_STRING_OR_BUFFER_TO_SLICE(_gt, gtBuffer, gt)
-        gt = new std::string(_gt.data(), _gt.size());
-        if (!reverse)
-          start = new leveldb::Slice(_gt.data(), _gt.size());
+        LD_STRING_OR_BUFFER_TO_COPY(_gt, gtBuffer, gt)
+        gt = new std::string(_gtCh_, _gtSz_);
+        delete[] _gtCh_;
+        if (!reverse) {
+          if (startStr != NULL) {
+            delete[] startStr;
+            startStr = NULL;
+          }
+          if (start != NULL)
+            delete start;
+          start = new leveldb::Slice(gt->data(), gt->size());
+        }
       }
     }
 
@@ -451,10 +489,18 @@ NAN_METHOD(Iterator::New) {
 
       // ignore end if it has size 0 since a Slice can't have length 0
       if (StringOrBufferLength(gteBuffer) > 0) {
-        LD_STRING_OR_BUFFER_TO_SLICE(_gte, gteBuffer, gte)
-        gte = new std::string(_gte.data(), _gte.size());
-        if (!reverse)
-          start = new leveldb::Slice(_gte.data(), _gte.size());
+        LD_STRING_OR_BUFFER_TO_COPY(_gte, gteBuffer, gte)
+        gte = new std::string(_gteCh_, _gteSz_);
+        delete[] _gteCh_;
+        if (!reverse) {
+          if (startStr != NULL) {
+            delete[] startStr;
+            startStr = NULL;
+          }
+          if (start != NULL)
+            delete start;
+          start = new leveldb::Slice(gte->data(), gte->size());
+        }
       }
     }
 
@@ -482,7 +528,6 @@ NAN_METHOD(Iterator::New) {
     , fillCache
     , keyAsBuffer
     , valueAsBuffer
-    , startHandle
     , highWaterMark
   );
   iterator->Wrap(info.This());
diff --git a/src/iterator.h b/src/iterator.h
index f38c58c..bed53f8 100644
--- a/src/iterator.h
+++ b/src/iterator.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015 LevelDOWN contributors
+/* Copyright (c) 2012-2016 LevelDOWN contributors
  * See list at <https://github.com/level/leveldown#contributing>
  * MIT License <https://github.com/level/leveldown/blob/master/LICENSE.md>
  */
@@ -44,7 +44,6 @@ public:
     , bool fillCache
     , bool keyAsBuffer
     , bool valueAsBuffer
-    , v8::Local<v8::Object> &startHandle
     , size_t highWaterMark
   );
 
@@ -82,8 +81,6 @@ public:
   AsyncWorker* endWorker;
 
 private:
-  Nan::Persistent<v8::Object> persistentHandle;
-
   bool Read (std::string& key, std::string& value);
   bool GetIterator ();
 
diff --git a/src/iterator_async.cc b/src/iterator_async.cc
index 6da6e65..8bc9079 100644
--- a/src/iterator_async.cc
+++ b/src/iterator_async.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015 LevelDOWN contributors
+/* Copyright (c) 2012-2016 LevelDOWN contributors
  * See list at <https://github.com/level/leveldown#contributing>
  * MIT License <https://github.com/level/leveldown/blob/master/LICENSE.md>
  */
@@ -33,6 +33,7 @@ void NextWorker::Execute () {
 }
 
 void NextWorker::HandleOKCallback () {
+  Nan::HandleScope scope;
   size_t idx = 0;
 
   size_t arraySize = result.size() * 2;
diff --git a/src/iterator_async.h b/src/iterator_async.h
index d4fa47b..2e0b2dc 100644
--- a/src/iterator_async.h
+++ b/src/iterator_async.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015 LevelDOWN contributors
+/* Copyright (c) 2012-2016 LevelDOWN contributors
  * See list at <https://github.com/level/leveldown#contributing>
  * MIT License <https://github.com/level/leveldown/blob/master/LICENSE.md>
  */
diff --git a/src/leveldown.cc b/src/leveldown.cc
index fc95c61..bb545ce 100644
--- a/src/leveldown.cc
+++ b/src/leveldown.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015 LevelDOWN contributors
+/* Copyright (c) 2012-2016 LevelDOWN contributors
  * See list at <https://github.com/level/leveldown#contributing>
  * MIT License <https://github.com/level/leveldown/blob/master/LICENSE.md>
  */
diff --git a/src/leveldown.h b/src/leveldown.h
index 43dbaa0..98c22da 100644
--- a/src/leveldown.h
+++ b/src/leveldown.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015 LevelDOWN contributors
+/* Copyright (c) 2012-2016 LevelDOWN contributors
  * See list at <https://github.com/level/leveldown#contributing>
  * MIT License <https://github.com/level/leveldown/blob/master/LICENSE.md>
  */
@@ -66,6 +66,25 @@ static inline void DisposeStringOrBufferFromSlice(
   }                                                                            \
   leveldb::Slice to(to ## Ch_, to ## Sz_);
 
+#define LD_STRING_OR_BUFFER_TO_COPY(to, from, name)                            \
+  size_t to ## Sz_;                                                            \
+  char* to ## Ch_;                                                             \
+  if (!from->ToObject().IsEmpty()                                              \
+      && node::Buffer::HasInstance(from->ToObject())) {                        \
+    to ## Sz_ = node::Buffer::Length(from->ToObject());                        \
+    to ## Ch_ = new char[to ## Sz_];                                           \
+    memcpy(to ## Ch_, node::Buffer::Data(from->ToObject()), to ## Sz_);        \
+  } else {                                                                     \
+    v8::Local<v8::String> to ## Str = from->ToString();                        \
+    to ## Sz_ = to ## Str->Utf8Length();                                       \
+    to ## Ch_ = new char[to ## Sz_];                                           \
+    to ## Str->WriteUtf8(                                                      \
+        to ## Ch_                                                              \
+      , -1                                                                     \
+      , NULL, v8::String::NO_NULL_TERMINATION                                  \
+    );                                                                         \
+  }
+
 #define LD_RETURN_CALLBACK_OR_ERROR(callback, msg)                             \
   if (!callback.IsEmpty() && callback->IsFunction()) {                         \
     v8::Local<v8::Value> argv[] = {                                            \
diff --git a/src/leveldown_async.cc b/src/leveldown_async.cc
index dfaa5a3..e9b79d6 100644
--- a/src/leveldown_async.cc
+++ b/src/leveldown_async.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015 LevelDOWN contributors
+/* Copyright (c) 2012-2016 LevelDOWN contributors
  * See list at <https://github.com/level/leveldown#contributing>
  * MIT License <https://github.com/level/leveldown/blob/master/LICENSE.md>
  */
diff --git a/src/leveldown_async.h b/src/leveldown_async.h
index 53196e5..d93881b 100644
--- a/src/leveldown_async.h
+++ b/src/leveldown_async.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015 LevelDOWN contributors
+/* Copyright (c) 2012-2016 LevelDOWN contributors
  * See list at <https://github.com/level/leveldown#contributing>
  * MIT License <https://github.com/level/leveldown/blob/master/LICENSE.md>
  */
diff --git a/test/compression-test.js b/test/compression-test.js
index af86e2c..2844c4d 100644
--- a/test/compression-test.js
+++ b/test/compression-test.js
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015 LevelUP contributors
+/* Copyright (c) 2012-2016 LevelUP contributors
  * See list at <https://github.com/level/leveldown#contributing>
  * MIT License <https://github.com/level/leveldown/blob/master/LICENSE.md>
  */
diff --git a/test/iterator-recursion-test.js b/test/iterator-recursion-test.js
index db18dab..716626e 100644
--- a/test/iterator-recursion-test.js
+++ b/test/iterator-recursion-test.js
@@ -21,13 +21,6 @@ var db
 
 test('setUp common', testCommon.setUp)
 
-test('setUp db', function (t) {
-  db = leveldown(testCommon.location())
-  db.open(function () {
-    db.batch(sourceData, t.end.bind(t))
-  })
-})
-
 test('try to create an iterator with a blown stack', function (t) {
   // Reducing the stack size down from the default 984 for the child node
   // process makes it easier to trigger the bug condition. But making it too low
@@ -47,6 +40,14 @@ test('try to create an iterator with a blown stack', function (t) {
   })
 })
 
+test('setUp db', function (t) {
+  db = leveldown(testCommon.location())
+  db.open(function (err) {
+    t.error(err)
+    db.batch(sourceData, t.end.bind(t))
+  })
+})
+
 test('iterate over a large iterator with a large watermark', function (t) {
   var iterator = db.iterator({
         highWaterMark: 10000000
diff --git a/test/repair-test.js b/test/repair-test.js
index 17f3514..c878bde 100644
--- a/test/repair-test.js
+++ b/test/repair-test.js
@@ -25,9 +25,12 @@ test('test callback-less, 1-arg, repair() throws', function (t) {
   t.end()
 })
 
-test('test repair non-existant directory returns error', function (t) {
+test('test repair non-existent directory returns error', function (t) {
   leveldown.repair('/1/2/3/4', function (err) {
-    t.ok(/no such/i.test(err), 'error on callback')
+    if (process.platform !== 'win32')
+      t.ok(/no such file or directory/i.test(err), 'error on callback')
+    else
+      t.ok(/IO error/i.test(err), 'error on callback')
     t.end()
   })
 })

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