Git Product home page Git Product logo

leveldown's Introduction

leveldown

๐Ÿ“Œ This module will soon be deprecated, because it is superseded by classic-level.

level badge npm Node version Test Coverage Standard Common Changelog Donate

Table of Contents

Click to expand

Introduction

This module was originally part of levelup but was later extracted and now serves as a stand-alone binding for LevelDB.

It is strongly recommended that you use levelup in preference to leveldown unless you have measurable performance reasons to do so. levelup is optimised for usability and safety. Although we are working to improve the safety of the leveldown interface it is still easy to crash your Node process if you don't do things in just the right way.

See the section on safety below for details of known unsafe operations with leveldown.

Supported Platforms

We aim to support at least Active LTS and Current Node.js releases, Electron 5.0.0, as well as any future Node.js and Electron releases thanks to N-API. The minimum node version for leveldown is 10.12.0. Conversely, for node >= 12, the minimum leveldown version is 5.0.0.

The leveldown npm package ships with prebuilt binaries for popular 64-bit platforms as well as ARM, M1, Android and Alpine (musl) and is known to work on:

  • Linux (including ARM platforms such as Raspberry Pi and Kindle)
  • Mac OS (10.7 and later)
  • Solaris (SmartOS & Nodejitsu)
  • FreeBSD
  • Windows

When installing leveldown, node-gyp-build will check if a compatible binary exists and fallback to a compile step if it doesn't. In that case you'll need a valid node-gyp installation.

If you don't want to use the prebuilt binary for the platform you are installing on, specify the --build-from-source flag when you install. One of:

npm install --build-from-source
npm install leveldown --build-from-source

If you are working on leveldown itself and want to re-compile the C++ code, run npm run rebuild.

Notes

  • If you get compilation errors on Node.js 12, please ensure you have leveldown >= 5. This can be checked by running npm ls leveldown.
  • On Linux flavors with an old glibc (Debian 8, Ubuntu 14.04, RHEL 7, CentOS 7) you must either update leveldown to >= 5.3.0 or use --build-from-source.
  • On Alpine 3 it was previously necessary to use --build-from-source. This is no longer the case.
  • The Android prebuilds are made for and built against Node.js core rather than the nodejs-mobile fork.

API

If you are upgrading: please see UPGRADING.md.

db = leveldown(location)

Returns a new leveldown instance. location is a String pointing to the LevelDB location to be opened.

db.open([options, ]callback)

Open the store. The callback function will be called with no arguments when the database has been successfully opened, or with a single error argument if the open operation failed for any reason.

options

The optional options argument may contain:

  • createIfMissing (boolean, default: true): If true, will initialise an empty database at the specified location if one doesn't already exist. If false and a database doesn't exist you will receive an error in your open() callback and your database won't open.

  • errorIfExists (boolean, default: false): If true, you will receive an error in your open() callback if the database exists at the specified location.

  • compression (boolean, default: true): If true, all compressible data will be run through the Snappy compression algorithm before being stored. Snappy is very fast and shouldn't gain much speed by disabling so leave this on unless you have good reason to turn it off.

  • cacheSize (number, default: 8 * 1024 * 1024 = 8MB): The size (in bytes) of the in-memory LRU cache with frequently used uncompressed block contents.

Advanced options

The following options are for advanced performance tuning. Modify them only if you can prove actual benefit for your particular application.

  • writeBufferSize (number, default: 4 * 1024 * 1024 = 4MB): The maximum size (in bytes) of the log (in memory and stored in the .log file on disk). Beyond this size, LevelDB will convert the log data to the first level of sorted table files. From the LevelDB documentation:

Larger values increase performance, especially during bulk loads. Up to two write buffers may be held in memory at the same time, so you may wish to adjust this parameter to control memory usage. Also, a larger write buffer will result in a longer recovery time the next time the database is opened.

  • blockSize (number, default 4096 = 4K): The approximate size of the blocks that make up the table files. The size related to uncompressed data (hence "approximate"). Blocks are indexed in the table file and entry-lookups involve reading an entire block and parsing to discover the required entry.

  • 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 'maxFileSize'.

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

  • maxFileSize (number, default: 2* 1024 * 1024 = 2MB): The maximum amount of bytes to write to a file before switching to a new one. From the LevelDB documentation:

... if your filesystem is more efficient with larger files, you could consider increasing the value. The downside will be longer compactions and hence longer latency/performance hiccups. Another reason to increase this parameter might be when you are initially populating a large database.

db.close(callback)

close() is an instance method on an existing database object. The underlying LevelDB database will be closed and the callback function will be called with no arguments if the operation is successful or with a single error argument if the operation failed for any reason.

leveldown waits for any pending operations to finish before closing. For example:

db.put('key', 'value', function (err) {
  // This happens first
})

db.close(function (err) {
  // This happens second
})

db.put(key, value[, options], callback)

Store a new entry or overwrite an existing entry.

The key and value objects may either be strings or Buffers. Other object types are converted to strings with the toString() method. Keys may not be null or undefined and objects converted with toString() should not result in an empty-string. Values may not be null or undefined. Values of '', [] and Buffer.alloc(0) (and any object resulting in a toString() of one of these) will be stored as a zero-length character array and will therefore be retrieved as either '' or Buffer.alloc(0) depending on the type requested.

A richer set of data-types is catered for in levelup.

options

The only property currently available on the options object is sync (boolean, default: false). If you provide a sync value of true in your options object, LevelDB will perform a synchronous write of the data; although the operation will be asynchronous as far as Node is concerned. Normally, LevelDB passes the data to the operating system for writing and returns immediately, however a synchronous write will use fsync() or equivalent so your callback won't be triggered until the data is actually on disk. Synchronous filesystem writes are significantly slower than asynchronous writes but if you want to be absolutely sure that the data is flushed then you can use { sync: true }.

The callback function will be called with no arguments if the operation is successful or with a single error argument if the operation failed for any reason.

db.get(key[, options], callback)

Get a value from the LevelDB store by key.

The key object may either be a string or a Buffer and cannot be undefined or null. Other object types are converted to strings with the toString() method and the resulting string may not be a zero-length. A richer set of data-types is catered for in levelup.

Values fetched via get() that are stored as zero-length character arrays (null, undefined, '', [], Buffer.alloc(0)) will return as empty-String ('') or Buffer.alloc(0) when fetched with asBuffer: true (see below).

options

The optional options object may contain:

  • asBuffer (boolean, default: true): Used to determine whether to return the value of the entry as a string or a Buffer. 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: false } and you'll avoid this conversion cost.
  • 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.

The callback function will be called with a single error if the operation failed for any reason, including if the key was not found. 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.

db.getMany(keys[, options][, callback])

Get multiple values from the store by an array of keys. The optional options object may contain asBuffer and fillCache, as described in get().

The callback function will be called with an Error if the operation failed for any reason. If successful the first argument will be null and the second argument will be an array of values with the same order as keys. If a key was not found, the relevant value will be undefined.

If no callback is provided, a promise is returned.

db.del(key[, options], callback)

Delete an entry. The key object may either be a string or a Buffer and cannot be undefined or null. Other object types are converted to strings with the toString() method and the resulting string may not be a zero-length. A richer set of data-types is catered for in levelup.

options

The only property currently available on the options object is sync (boolean, default: false). See db.put() for details about this option.

The callback function will be called with no arguments if the operation is successful or with a single error argument if the operation failed for any reason.

db.batch(operations[, options], callback) (array form)

Perform multiple put and/or del operations in bulk. The operations argument must be an Array containing a list of operations to be executed sequentially, although as a whole they are performed as an atomic operation.

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 where the key or value (in the case of 'put') is 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 [], '' or Buffer.alloc(0) will be stored as a zero-length character array and therefore be fetched during reads as either '' or Buffer.alloc(0) depending on how they are requested. See levelup for full documentation on how this works in practice.

The optional options argument may contain:

  • sync (boolean, default: false). See db.put() for details about this option.

The callback function will be called with no arguments if the batch is successful or with an Error if the batch failed for any reason.

db.batch() (chained form)

Returns a new chainedBatch instance.

db.approximateSize(start, end, callback)

approximateSize() is an instance method on an existing database object. Used to get the approximate number of bytes of file system space used by the range [start..end). The result may not include recently written data.

The start and end parameters may be strings or Buffers representing keys in the LevelDB store.

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 approximate size as a Number.

db.compactRange(start, end, callback)

compactRange() is an instance method on an existing database object. Used to manually trigger a database compaction in the range [start..end).

The start and end parameters may be strings or Buffers representing keys in the LevelDB store.

The callback function will be called with no arguments if the operation is successful or with a single error argument if the operation failed for any reason.

db.getProperty(property)

getProperty can be used to get internal details from LevelDB. When issued with a valid property string, a readable string will be returned (this method is synchronous).

Currently, the only valid properties are:

  • leveldb.num-files-at-levelN: return the number of files at level N, where N is an integer representing a valid level (e.g. "0").

  • leveldb.stats: returns a multi-line string describing statistics about LevelDB's internal operation.

  • leveldb.sstables: returns a multi-line string describing all of the sstables that make up contents of the current database.

db.iterator([options])

Returns a new iterator instance. Accepts the following range options:

  • gt (greater than), gte (greater than or equal) define the lower bound of the range to be iterated. Only entries where the key is greater than (or equal to) this option will be included in the range. When reverse=true the order will be reversed, but the entries iterated will be the same.
  • lt (less than), lte (less than or equal) define the higher bound of the range to be iterated. Only entries where the key is less than (or equal to) this option will be included in the range. When reverse=true the order will be reversed, but the entries iterated will be the same.
  • reverse (boolean, default: false): iterate entries in reverse order. Beware that a reverse seek can be slower than a forward seek.
  • limit (number, default: -1): limit the number of entries collected by this iterator. This number represents a maximum number of entries and may not be reached if you get to the end of the range first. A value of -1 means there is no limit. When reverse=true the entries with the highest keys will be returned instead of the lowest keys.

In addition to range options, iterator() takes the following options:

  • keys (boolean, default: true): whether to return the key of each entry. If set to false, calls to iterator.next(callback) will yield keys with a value of undefined 1. 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.
  • values (boolean, default: true): whether to return the value of each entry. If set to false, calls to iterator.next(callback) will yield values with a value of undefined1.
  • keyAsBuffer (boolean, default: true): Whether to return the key of each entry as a Buffer or string. Converting from a Buffer to a string incurs a cost so if you need a string (and the key can legitimately become a UTF8 string) then you should fetch it as one.
  • valueAsBuffer (boolean, default: true): Whether to return the value of each entry as a Buffer or string.
  • fillCache (boolean, default: false): whether LevelDB's LRU-cache should be filled with data read.

1 leveldown returns an empty string rather than undefined at the moment.

db.clear([options, ]callback)

Delete all entries or a range. Not guaranteed to be atomic. Accepts the following range options (with the same rules as on iterators):

  • gt (greater than), gte (greater than or equal) define the lower bound of the range to be deleted. Only entries where the key is greater than (or equal to) this option will be included in the range. When reverse=true the order will be reversed, but the entries deleted will be the same.
  • lt (less than), lte (less than or equal) define the higher bound of the range to be deleted. Only entries where the key is less than (or equal to) this option will be included in the range. When reverse=true the order will be reversed, but the entries deleted will be the same.
  • reverse (boolean, default: false): delete entries in reverse order. Only effective in combination with limit, to remove the last N entries.
  • limit (number, default: -1): limit the number of entries to be deleted. This number represents a maximum number of entries and may not be reached if you get to the end of the range first. A value of -1 means there is no limit. When reverse=true the entries with the highest keys will be deleted instead of the lowest keys.

If no options are provided, all entries will be deleted. The callback function will be called with no arguments if the operation was successful or with an Error if it failed for any reason.

chainedBatch

chainedBatch.put(key, value)

Queue a put operation on this batch. This may throw if key or value is invalid, following the same rules as the array form of db.batch().

chainedBatch.del(key)

Queue a del operation on this batch. This may throw if key is invalid.

chainedBatch.clear()

Clear all queued operations on this batch.

chainedBatch.write([options, ]callback)

Commit the queued operations for this batch. All operations will be written atomically, that is, they will either all succeed or fail with no partial commits.

The optional options argument may contain:

  • sync (boolean, default: false). See db.put() for details about this option.

The callback function will be called with no arguments if the batch is successful or with an Error if the batch failed for any reason. After write has been called, no further operations are allowed.

chainedBatch.db

A reference to the db that created this chained batch.

iterator

An iterator allows you to iterate the entire store or a range. It operates on a snapshot of the store, created at the time db.iterator() was called. This means reads on the iterator are unaffected by simultaneous writes.

Iterators can be consumed with for await...of or by manually calling iterator.next() in succession. In the latter mode, iterator.end() must always be called. In contrast, finishing, throwing or breaking from a for await...of loop automatically calls iterator.end().

An iterator reaches its natural end in the following situations:

  • The end of the store has been reached
  • The end of the range has been reached
  • The last iterator.seek() was out of range.

An iterator keeps track of when a next() is in progress and when an end() has been called so it doesn't allow concurrent next() calls, it does allow end() while a next() is in progress and it doesn't allow either next() or end() after end() has been called.

for await...of iterator

Yields arrays containing a key and value. The type of key and value depends on the options passed to db.iterator().

try {
  for await (const [key, value] of db.iterator()) {
    console.log(key)
  }
} catch (err) {
  console.error(err)
}

iterator.next([callback])

Advance the iterator and yield the entry at that key. If an error occurs, the callback function will be called with an Error. Otherwise, the callback receives null, a key and a value. The type of key and value depends on the options passed to db.iterator(). If the iterator has reached its natural end, both key and value will be undefined.

If no callback is provided, a promise is returned for either an array (containing a key and value) or undefined if the iterator reached its natural end.

Note: Always call iterator.end(), even if you received an error and even if the iterator reached its natural end.

iterator.seek(key)

Seek the iterator to a given key or the closest key. Subsequent calls to iterator.next() will yield entries with keys equal to or larger than target, or equal to or smaller than target if the reverse option passed to db.iterator() was true. The same applies to implicit iterator.next() calls in a for await...of loop.

If range options like gt were passed to db.iterator() and target does not fall within that range, the iterator will reach its natural end.

iterator.end([callback])

End iteration and free up underlying resources. The callback function will be called with no arguments on success or with an Error if ending failed for any reason.

If no callback is provided, a promise is returned.

iterator.db

A reference to the db that created this iterator.

leveldown.destroy(location, callback)

Completely remove an existing LevelDB database directory. You can use this function in place of a full directory rm if you want to be sure to only remove LevelDB-related files. If the directory only contains LevelDB files, the directory itself will be removed as well. If there are additional, non-LevelDB files in the directory, those files, and the directory, will be left alone.

The callback will be called when the destroy operation is complete, with a possible error argument.

leveldown.repair(location, callback)

Attempt a restoration of a damaged LevelDB store. From the LevelDB documentation:

If a DB cannot be opened, you may attempt to call this method to resurrect as much of the contents of the database as possible. Some data may be lost, so be careful when calling this function on a database that contains important information.

You will find information on the repair operation in the LOG file inside the store directory.

A repair() can also be used to perform a compaction of the LevelDB log into table files.

The callback will be called when the repair operation is complete, with a possible error argument.

Safety

Database State

Currently leveldown does not track the state of the underlying LevelDB instance. This means that calling open() on an already open database may result in an error. Likewise, calling any other operation on a non-open database may result in an error.

levelup currently tracks and manages state and will prevent out-of-state operations from being send to leveldown. If you use leveldown directly then you must track and manage state for yourself.

Snapshots

leveldown exposes a feature of LevelDB called snapshots. This means that when you do e.g. createReadStream and createWriteStream at the same time, any data modified by the write stream will not affect data emitted from the read stream. In other words, a LevelDB Snapshot captures the latest state at the time the snapshot was created, enabling the snapshot to iterate or read the data without seeing any subsequent writes. Any read not performed on a snapshot will implicitly use the latest state.

Getting Support

You're welcome to open an issue on the GitHub repository if you have a question.

Past and no longer active support channels include the ##leveldb IRC channel on Freenode and the Node.js LevelDB Google Group.

Contributing

Level/leveldown is an OPEN Open Source Project. This means that:

Individuals making significant and valuable contributions are given commit-access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project.

See the Contribution Guide for more details.

Git Submodules

This project uses Git Submodules. This means that you should clone it recursively if you're planning on working on it:

$ git clone --recurse-submodules https://github.com/Level/leveldown.git

Alternatively, you can initialize submodules inside the cloned folder:

$ git submodule update --init --recursive

Publishing

  1. Increment the version: npm version ..
  2. Push to GitHub: git push --follow-tags
  3. Wait for CI to complete
  4. Download prebuilds into ./prebuilds: npm run download-prebuilds
  5. Optionally verify loading a prebuild: npm run test-prebuild
  6. Optionally verify which files npm will include: canadian-pub
  7. Finally: npm publish

Donate

Support us with a monthly donation on Open Collective and help us continue our work.

License

MIT

leveldown builds on the excellent work of the LevelDB and Snappy teams from Google and additional contributors. LevelDB and Snappy are both issued under the New BSD License. A large portion of leveldown Windows support comes from the Windows LevelDB port (archived) by Krzysztof Kowalczyk (@kjk). If you're using leveldown on Windows, you should give him your thanks!

leveldown's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

leveldown's Issues

File lock issues in leveldb

Leveldb tests seem to have problems with file locking
Full output here
db\corruption_test.cc:115: failed: 36 >= 68
db\c_test.cc:243: open: IO error: LockFile /LOCK: Access is denied.
db\db_test.cc:478: IO error: DeleteFile C:\Users\ANTON\AppData\Local\Temp/db_test/000005.sst: The process cannot access the file because it is being used by another process.

Don't create Persistent handles too early

Just browsing the code looking for the leak mentioned in Level/levelup#140 and it occurs to me that there are a bunch of places where we create a Persistent handle early and use it to early-return an error. This isn't a common case, you'd have to be doing something like db.get(undefined) to trigger this kind of error, but that would still create an unacceptable leak.

I think we need to move as many Persistent handle creations down to the lowest point possible. Note particularly that every use of LD_METHOD_SETUP_COMMON creates a v8::Persistent<v8::Function> which may be used to return an error before even getting to the async work. Better to use a Local handle and then wrap it in a Persistent down where we call the async worker.

error if I close while a create read stream is running/started

this comes in a few flavors,
if you create close before the stream is 'ready',
then it will not have an iterator. (this is probably fixed by my previous commit, that is coming into 0.9)

next, if it happens while the stream is still reading,
readStream tries to call next() after end().

I'm gonna get something to eat, and then I'll add a test for this after.

Iterator#dispose

what sort of error can happen in iterator.dispose(cb)?

var i = db.iterator()

i.dispose(function (err) {
  //?  
})

if there is an error should I try disposing again? do I even care? I don't need the iterator any more,
so as long as it's gone now, that is all I need to know. Could iterator.dispose() take no callback?

RocksDB not compiling on OS X

I know this is a very early release.. but these are the errors:


../deps/leveldb/leveldb-rocksdb/include/rocksdb/status.h:24:21: error: use of undeclared identifier 'nullptr'
  Status() : state_(nullptr) { }
                    ^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/status.h:58:39: error: use of undeclared identifier 'nullptr'
  bool ok() const { return (state_ == nullptr); }
                                      ^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/status.h:105:23: error: use of undeclared identifier 'nullptr'
    return (state_ == nullptr) ? kOk : static_cast<Code>(state_[4]);
                      ^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/status.h:113:25: error: use of undeclared identifier 'nullptr'
  state_ = (s.state_ == nullptr) ? nullptr : CopyState(s.state_);
                        ^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/status.h:113:36: error: use of undeclared identifier 'nullptr'
  state_ = (s.state_ == nullptr) ? nullptr : CopyState(s.state_);
                                   ^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/status.h:120:27: error: use of undeclared identifier 'nullptr'
    state_ = (s.state_ == nullptr) ? nullptr : CopyState(s.state_);
                          ^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/status.h:120:38: error: use of undeclared identifier 'nullptr'
    state_ = (s.state_ == nullptr) ? nullptr : CopyState(s.state_);
                                     ^
In file included from ../deps/leveldb/leveldb-rocksdb/db/version_set_reduce_num_levels.cc:10:
In file included from ../deps/leveldb/leveldb-rocksdb/db/version_set.h:26:
In file included from ../deps/leveldb/leveldb-rocksdb/db/dbformat.h:13:
In file included from ../deps/leveldb/leveldb-rocksdb/include/rocksdb/db.h:13:
In file included from ../deps/leveldb/leveldb-rocksdb/include/rocksdb/options.h:14:
In file included from ../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:43:
../deps/leveldb/leveldb-rocksdb/include/rocksdb/arena.h:28:11: warning: 'const' type qualifier on return type has no effect [-Wignored-qualifiers]
  virtual const size_t ApproximateMemoryUsage() = 0;
          ^~~~~~
../deps/leveldb/leveldb-rocksdb/include/rocksdb/arena.h:31:11: warning: 'const' type qualifier on return type has no effect [-Wignored-qualifiers]
  virtual const size_t MemoryAllocatedBytes() = 0;
          ^~~~~~
In file included from ../deps/leveldb/leveldb-rocksdb/db/version_set_reduce_num_levels.cc:10:
In file included from ../deps/leveldb/leveldb-rocksdb/db/version_set.h:26:
In file included from ../deps/leveldb/leveldb-rocksdb/db/dbformat.h:13:
In file included from ../deps/leveldb/leveldb-rocksdb/include/rocksdb/db.h:13:
In file included from ../deps/leveldb/leveldb-rocksdb/include/rocksdb/options.h:14:
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:117:16: error: no type named 'shared_ptr' in namespace 'std'
  virtual std::shared_ptr<Iterator> GetIterator() = 0;
          ~~~~~^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:117:26: error: expected member name or ';' after declaration specifiers
  virtual std::shared_ptr<Iterator> GetIterator() = 0;
  ~~~~~~~~~~~~~~~~~~~~~~~^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:122:16: error: no type named 'shared_ptr' in namespace 'std'
  virtual std::shared_ptr<Iterator> GetIterator(const Slice& user_key) {
          ~~~~~^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:122:26: error: expected member name or ';' after declaration specifiers
  virtual std::shared_ptr<Iterator> GetIterator(const Slice& user_key) {
  ~~~~~~~~~~~~~~~~~~~~~~~^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:150:16: error: no type named 'shared_ptr' in namespace 'std'
  virtual std::shared_ptr<MemTableRep> CreateMemTableRep(
          ~~~~~^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:150:26: error: expected member name or ';' after declaration specifiers
  virtual std::shared_ptr<MemTableRep> CreateMemTableRep(
  ~~~~~~~~~~~~~~~~~~~~~~~^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:167:16: error: no type named 'shared_ptr' in namespace 'std'
  virtual std::shared_ptr<MemTableRep> CreateMemTableRep(
          ~~~~~^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:167:26: error: expected member name or ';' after declaration specifiers
  virtual std::shared_ptr<MemTableRep> CreateMemTableRep(
  ~~~~~~~~~~~~~~~~~~~~~~~^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:169:36: warning: 'override' keyword is a C++11 extension [-Wc++11-extensions]
  virtual const char* Name() const override {
                                   ^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:177:16: error: no type named 'shared_ptr' in namespace 'std'
  virtual std::shared_ptr<MemTableRep> CreateMemTableRep(
          ~~~~~^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:177:26: error: expected member name or ';' after declaration specifiers
  virtual std::shared_ptr<MemTableRep> CreateMemTableRep(
  ~~~~~~~~~~~~~~~~~~~~~~~^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:179:36: warning: 'override' keyword is a C++11 extension [-Wc++11-extensions]
  virtual const char* Name() const override {
                                   ^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:214:16: error: no type named 'shared_ptr' in namespace 'std'
  virtual std::shared_ptr<MemTableRep> CreateMemTableRep(
          ~~~~~^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:214:26: error: expected member name or ';' after declaration specifiers
  virtual std::shared_ptr<MemTableRep> CreateMemTableRep(
  ~~~~~~~~~~~~~~~~~~~~~~~^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:217:36: warning: 'override' keyword is a C++11 extension [-Wc++11-extensions]
  virtual const char* Name() const override {
                                   ^
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:239:36: warning: 'override' keyword is a C++11 extension [-Wc++11-extensions]
  virtual const char* Name() const override {

RocksDB compilation fails on Ubuntu (Precise Penguin)

make: Entering directory `/data/Downloads/node_modules/rockslevel/node_modules/rocksdb/build'
  CXX(target) Release/obj.target/leveldb/deps/leveldb/leveldb-rocksdb/db/version_set_reduce_num_levels.o
In file included from ../deps/leveldb/leveldb-rocksdb/include/rocksdb/options.h:14:0,
                 from ../deps/leveldb/leveldb-rocksdb/include/rocksdb/db.h:13,
                 from ../deps/leveldb/leveldb-rocksdb/db/dbformat.h:13,
                 from ../deps/leveldb/leveldb-rocksdb/db/version_set.h:26,
                 from ../deps/leveldb/leveldb-rocksdb/db/version_set_reduce_num_levels.cc:10:
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:168:40: error: expected ';' at end of member declaration
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:168:42: error: 'override' does not name a type
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:169:30: error: expected ';' at end of member declaration
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:169:36: error: 'override' does not name a type
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:178:40: error: expected ';' at end of member declaration
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:178:42: error: 'override' does not name a type
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:179:30: error: expected ';' at end of member declaration
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:179:36: error: 'override' does not name a type
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:215:40: error: expected ';' at end of member declaration
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:215:42: error: 'override' does not name a type
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:217:30: error: expected ';' at end of member declaration
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:217:36: error: 'override' does not name a type
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:239:30: error: expected ';' at end of member declaration
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:239:36: error: 'override' does not name a type
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:256:40: error: expected ';' at end of member declaration
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:256:42: error: 'override' does not name a type
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:258:30: error: expected ';' at end of member declaration
../deps/leveldb/leveldb-rocksdb/include/rocksdb/memtablerep.h:258:36: error: 'override' does not name a type
In file included from ../deps/leveldb/leveldb-rocksdb/include/rocksdb/options.h:20:0,
                 from ../deps/leveldb/leveldb-rocksdb/include/rocksdb/db.h:13,
                 from ../deps/leveldb/leveldb-rocksdb/db/dbformat.h:13,
                 from ../deps/leveldb/leveldb-rocksdb/db/version_set.h:26,
                 from ../deps/leveldb/leveldb-rocksdb/db/version_set_reduce_num_levels.cc:10:
../deps/leveldb/leveldb-rocksdb/include/rocksdb/table_stats.h:26:24: sorry, unimplemented: non-static data member initializers
../deps/leveldb/leveldb-rocksdb/include/rocksdb/table_stats.h:26:24: error: ISO C++ forbids in-class initialization of non-const static member 'data_size'
../deps/leveldb/leveldb-rocksdb/include/rocksdb/table_stats.h:28:25: sorry, unimplemented: non-static data member initializers
../deps/leveldb/leveldb-rocksdb/include/rocksdb/table_stats.h:28:25: error: ISO C++ forbids in-class initialization of non-const static member 'index_size'
../deps/leveldb/leveldb-rocksdb/include/rocksdb/table_stats.h:30:27: sorry, unimplemented: non-static data member initializers
../deps/leveldb/leveldb-rocksdb/include/rocksdb/table_stats.h:30:27: error: ISO C++ forbids in-class initialization of non-const static member 'raw_key_size'
../deps/leveldb/leveldb-rocksdb/include/rocksdb/table_stats.h:32:29: sorry, unimplemented: non-static data member initializers
../deps/leveldb/leveldb-rocksdb/include/rocksdb/table_stats.h:32:29: error: ISO C++ forbids in-class initialization of non-const static member 'raw_value_size'
../deps/leveldb/leveldb-rocksdb/include/rocksdb/table_stats.h:34:30: sorry, unimplemented: non-static data member initializers
../deps/leveldb/leveldb-rocksdb/include/rocksdb/table_stats.h:34:30: error: ISO C++ forbids in-class initialization of non-const static member 'num_data_blocks'
../deps/leveldb/leveldb-rocksdb/include/rocksdb/table_stats.h:36:26: sorry, unimplemented: non-static data member initializers
../deps/leveldb/leveldb-rocksdb/include/rocksdb/table_stats.h:36:26: error: ISO C++ forbids in-class initialization of non-const static member 'num_entries'
In file included from ../deps/leveldb/leveldb-rocksdb/include/rocksdb/db.h:15:0,
                 from ../deps/leveldb/leveldb-rocksdb/db/dbformat.h:13,
                 from ../deps/leveldb/leveldb-rocksdb/db/version_set.h:26,
                 from ../deps/leveldb/leveldb-rocksdb/db/version_set_reduce_num_levels.cc:10:
../deps/leveldb/leveldb-rocksdb/include/rocksdb/transaction_log.h:55:44: sorry, unimplemented: non-static data member initializers
../deps/leveldb/leveldb-rocksdb/include/rocksdb/transaction_log.h:55:44: error: ISO C++ forbids in-class initialization of non-const static member 'sequence'
make: *** [Release/obj.target/leveldb/deps/leveldb/leveldb-rocksdb/db/version_set_reduce_num_levels.o] Error 1
make: Leaving directory `/data/Downloads/node_modules/rockslevel/node_modules/rocksdb/build'

drop optional args

Can we make optional arguments really optional? Like options and callbacks?

In C that's not hard and the performance loss should be subliminal. The implementation will grow a but but it will be way more comfortable to use.

[email protected] not support windows

wn\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(22): error C2146: syntax error : missing ';' befo
re identifier 'len2' [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.v
cxproj]
leveldb-1.11.0\util\status.cc(22): error C2086: 'const int uint32_t' : redefini
tion [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(21) : see declaration of 'uint32_t'
leveldb-1.11.0\util\status.cc(22): error C2065: 'len2' : undeclared identifier
[C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(23): error C4430: missing type specifier - int as
sumed. Note: C++ does not support default-int [C:\sqlite32\node_modules\leveldo
wn\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(23): error C2146: syntax error : missing ';' befo
re identifier 'size' [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.v
cxproj]
leveldb-1.11.0\util\status.cc(23): error C2086: 'const int uint32_t' : redefini
tion [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(21) : see declaration of 'uint32_t'
leveldb-1.11.0\util\status.cc(23): error C2065: 'size' : undeclared identifier
[C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(23): error C2065: 'len1' : undeclared identifier
[C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(23): error C2065: 'len2' : undeclared identifier
[C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(23): error C2065: 'len2' : undeclared identifier
[C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(24): error C2065: 'size' : undeclared identifier
[C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(25): error C2065: 'size' : undeclared identifier
[C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(25): error C2065: 'size' : undeclared identifier
[C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(25): error C2070: ''unknown-type'': illegal sizeo
f operand [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(27): error C2065: 'len1' : undeclared identifier
[C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(28): error C2065: 'len2' : undeclared identifier
[C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(29): error C2065: 'len1' : undeclared identifier
[C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(30): error C2065: 'len1' : undeclared identifier
[C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(31): error C2065: 'len1' : undeclared identifier
[C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(31): error C2065: 'len2' : undeclared identifier
[C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(62): error C3861: 'snprintf': identifier not foun
d [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(68): error C2065: 'uint32_t' : undeclared identif
ier [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(68): error C2146: syntax error : missing ';' befo
re identifier 'length' [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb
.vcxproj]
leveldb-1.11.0\util\status.cc(68): error C2065: 'length' : undeclared identifie
r [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(69): error C2065: 'length' : undeclared identifie
r [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(69): error C2065: 'length' : undeclared identifie
r [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(69): error C2070: ''unknown-type'': illegal sizeo
f operand [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\status.cc(70): error C2065: 'length' : undeclared identifie
r [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
block_builder.cc
leveldb-1.11.0\util\comparator.cc(69): error C2653: 'port' : is not a class or
namespace name [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj
]
leveldb-1.11.0\util\comparator.cc(69): error C2146: syntax error : missing ';'
before identifier 'once' [C:\sqlite32\node_modules\leveldown\deps\leveldb\level
db.vcxproj]
leveldb-1.11.0\util\comparator.cc(69): error C4430: missing type specifier - in
t assumed. Note: C++ does not support default-int [C:\sqlite32\node_modules\lev
eldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\comparator.cc(69): error C4430: missing type specifier - in
t assumed. Note: C++ does not support default-int [C:\sqlite32\node_modules\lev
eldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\util\comparator.cc(69): error C2065: 'LEVELDB_ONCE_INIT' : undec
lared identifier [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxpr
oj]
leveldb-1.11.0\util\comparator.cc(77): error C2653: 'port' : is not a class or
namespace name [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj
]
leveldb-1.11.0\util\comparator.cc(77): error C3861: 'InitOnce': identifier not
found [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
table_builder.cc
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/mutexlock.h
(25): error C2653: 'port' : is not a class or namespace name [C:\sqlite32\node_
modules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/mutexlock.h
(25): error C2653: 'port' : is not a class or namespace name [C:\sqlite32\node_
modules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/mutexlock.h
(25): error C2061: syntax error : identifier 'Mutex' [C:\sqlite32\node_modules
leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/mutexlock.h
(32): error C2653: 'port' : is not a class or namespace name [C:\sqlite32\node_
modules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/mutexlock.h
(32): error C2143: syntax error : missing ';' before '*' [C:\sqlite32\node_modu
les\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/mutexlock.h
(32): error C4430: missing type specifier - int assumed. Note: C++ does not sup
port default-int [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxpr
oj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/mutexlock.h
(32): error C4430: missing type specifier - int assumed. Note: C++ does not sup
port default-int [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxpr
oj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/mutexlock.h
(25): error C2065: 'mu' : undeclared identifier [C:\sqlite32\node_modules\level
down\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/mutexlock.h
(25): error C2614: 'leveldb::MutexLock' : illegal member initialization: 'mu_'
is not a base or member [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveld
b.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/mutexlock.h
(27): error C2039: 'mu_' : is not a member of 'leveldb::MutexLock' [C:\sqlite32
\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/m
utexlock.h(23) : see declaration of 'leveldb::MutexLock'
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/mutexlock.h
(27): error C2227: left of '->Lock' must point to class/struct/union/generic ty
pe [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/mutexlock.h
(29): error C2039: 'mu_' : is not a member of 'leveldb::MutexLock' [C:\sqlite32
\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/m
utexlock.h(23) : see declaration of 'leveldb::MutexLock'
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/mutexlock.h
(29): error C2227: left of '->Unlock' must point to class/struct/union/generic
type [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\helpers\memenv\memenv.cc(136): error C2653: 'port' : is not a cl
ass or namespace name [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.
vcxproj]
leveldb-1.11.0\helpers\memenv\memenv.cc(136): error C2146: syntax error : missi
ng ';' before identifier 'refs_mutex_' [C:\sqlite32\node_modules\leveldown\deps
\leveldb\leveldb.vcxproj]
leveldb-1.11.0\helpers\memenv\memenv.cc(136): error C4430: missing type specifi
er - int assumed. Note: C++ does not support default-int [C:\sqlite32\node_modu
les\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\helpers\memenv\memenv.cc(136): error C4430: missing type specifi
er - int assumed. Note: C++ does not support default-int [C:\sqlite32\node_modu
les\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\helpers\memenv\memenv.cc(28): error C2065: 'refs_mutex_' : undec
lared identifier [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxpr
oj]
leveldb-1.11.0\helpers\memenv\memenv.cc(37): error C2065: 'refs_mutex_' : undec
lared identifier [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxpr
oj]
two_level_iterator.cc
leveldb-1.11.0\helpers\memenv\memenv.cc(374): error C2653: 'port' : is not a cl
ass or namespace name [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.
vcxproj]
leveldb-1.11.0\helpers\memenv\memenv.cc(374): error C2146: syntax error : missi
ng ';' before identifier 'mutex_' [C:\sqlite32\node_modules\leveldown\deps\leve
ldb\leveldb.vcxproj]
leveldb-1.11.0\helpers\memenv\memenv.cc(374): error C4430: missing type specifi
er - int assumed. Note: C++ does not support default-int [C:\sqlite32\node_modu
les\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\helpers\memenv\memenv.cc(374): error C4430: missing type specifi
er - int assumed. Note: C++ does not support default-int [C:\sqlite32\node_modu
les\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\helpers\memenv\memenv.cc(242): error C2065: 'mutex_' : undeclare
d identifier [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\helpers\memenv\memenv.cc(254): error C2065: 'mutex_' : undeclare
d identifier [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\helpers\memenv\memenv.cc(266): error C2065: 'mutex_' : undeclare
d identifier [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\helpers\memenv\memenv.cc(280): error C2065: 'mutex_' : undeclare
d identifier [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\helpers\memenv\memenv.cc(286): error C2065: 'mutex_' : undeclare
d identifier [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\helpers\memenv\memenv.cc(311): error C2065: 'mutex_' : undeclare
d identifier [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\helpers\memenv\memenv.cc(329): error C2065: 'mutex_' : undeclare
d identifier [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\helpers\memenv\memenv.cc(340): error C2065: 'mutex_' : undeclare
d identifier [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
merger.cc
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(59
): error C2653: 'port' : is not a class or namespace name [C:\sqlite32\node_mod
ules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(59
): error C2065: 'kLittleEndian' : undeclared identifier [C:\sqlite32\node_modul
es\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(73
): error C2653: 'port' : is not a class or namespace name [C:\sqlite32\node_mod
ules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(73
): error C2065: 'kLittleEndian' : undeclared identifier [C:\sqlite32\node_modul
es\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\table\filter_block.cc(100): warning C4018: '<=' : signed/unsigne
d mismatch [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(59
): error C2653: 'port' : is not a class or namespace name [C:\sqlite32\node_mod
ules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(59
): error C2065: 'kLittleEndian' : undeclared identifier [C:\sqlite32\node_modul
es\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(73
): error C2653: 'port' : is not a class or namespace name [C:\sqlite32\node_mod
ules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(73
): error C2065: 'kLittleEndian' : undeclared identifier [C:\sqlite32\node_modul
es\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(59
): error C2653: 'port' : is not a class or namespace name [C:\sqlite32\node_mod
ules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(59
): error C2065: 'kLittleEndian' : undeclared identifier [C:\sqlite32\node_modul
es\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(73
): error C2653: 'port' : is not a class or namespace name [C:\sqlite32\node_mod
ules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(73
): error C2065: 'kLittleEndian' : undeclared identifier [C:\sqlite32\node_modul
es\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\table\format.cc(121): error C2653: 'port' : is not a class or na
mespace name [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\table\format.cc(121): error C3861: 'Snappy_GetUncompressedLength
': identifier not found [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveld
b.vcxproj]
leveldb-1.11.0\table\format.cc(126): error C2653: 'port' : is not a class or na
mespace name [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\table\format.cc(126): error C3861: 'Snappy_Uncompress': identifi
er not found [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(59
): error C2653: 'port' : is not a class or namespace name [C:\sqlite32\node_mod
ules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(59
): error C2065: 'kLittleEndian' : undeclared identifier [C:\sqlite32\node_modul
es\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(73
): error C2653: 'port' : is not a class or namespace name [C:\sqlite32\node_mod
ules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(73
): error C2065: 'kLittleEndian' : undeclared identifier [C:\sqlite32\node_modul
es\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(59
): error C2653: 'port' : is not a class or namespace name [C:\sqlite32\node_mod
ules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(59
): error C2065: 'kLittleEndian' : undeclared identifier [C:\sqlite32\node_modul
es\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(73
): error C2653: 'port' : is not a class or namespace name [C:\sqlite32\node_mod
ules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(73
): error C2065: 'kLittleEndian' : undeclared identifier [C:\sqlite32\node_modul
es\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(59
): error C2653: 'port' : is not a class or namespace name [C:\sqlite32\node_mod
ules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(59
): error C2065: 'kLittleEndian' : undeclared identifier [C:\sqlite32\node_modul
es\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(73
): error C2653: 'port' : is not a class or namespace name [C:\sqlite32\node_mod
ules\leveldown\deps\leveldb\leveldb.vcxproj]
C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb-1.11.0\util/coding.h(73
): error C2065: 'kLittleEndian' : undeclared identifier [C:\sqlite32\node_modul
es\leveldown\deps\leveldb\leveldb.vcxproj]
leveldb-1.11.0\table\table_builder.cc(158): error C2653: 'port' : is not a clas
s or namespace name [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vc
xproj]
leveldb-1.11.0\table\table_builder.cc(158): error C3861: 'Snappy_Compress': ide
ntifier not found [C:\sqlite32\node_modules\leveldown\deps\leveldb\leveldb.vcxp
roj]
snappy.cc
snappy-stubs-internal.cc
snappy-sinksource.cc
c:\sqlite32\node_modules\leveldown\deps\snappy\snappy-1.1.0\snappy-stubs-intern
al.h : warning C4819: The file contains a character that cannot be represented
in the current code page (936). Save the file in Unicode format to prevent data
loss [C:\sqlite32\node_modules\leveldown\deps\snappy\snappy.vcxproj]
c:\sqlite32\node_modules\leveldown\deps\snappy\snappy-1.1.0\snappy-stubs-intern
al.h : warning C4819: The file contains a character that cannot be represented
in the current code page (936). Save the file in Unicode format to prevent data
loss [C:\sqlite32\node_modules\leveldown\deps\snappy\snappy.vcxproj]
snappy.vcxproj -> C:\sqlite32\node_modules\leveldown\build\Release\snappy.li
b
gyp ERR! build error
gyp ERR! stack Error: C:\windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe failed with exit code: 1
gyp ERR! stack at ChildProcess.onExit (C:\Program Files (x86)\nodejs\node_mo
dules\npm\node_modules\node-gyp\lib\build.js:267:23)
gyp ERR! stack at ChildProcess.EventEmitter.emit (events.js:98:17)
gyp ERR! stack at Process.ChildProcess._handle.onexit (child_process.js:789:
12)
gyp ERR! System Windows_NT 6.1.7601
gyp ERR! command "node" "C:\Program Files (x86)\nodejs\node_modules\npm\nod
e_modules\node-gyp\bin\node-gyp.js" "rebuild"
gyp ERR! cwd C:\sqlite32\node_modules\leveldown
gyp ERR! node -v v0.10.11
gyp ERR! node-gyp -v v0.10.0
gyp ERR! not ok
npm ERR! weird error 1
npm ERR! not ok code 0

today i update [email protected] it throws this errow ,but [email protected] is all right

auto-cleanup iterators when db is closed

iterator.end() must be called on each iterator, otherwise when you clean up a database you can land in a segfault.

Proposal is to collect Iterator instances in the main Database instance and when you call close() it ends any iterators that haven't already been closed.

Tests

Currently devoid of tests as they are all in LevelUP. Need to implement a new set just for LevelDOWN.

Iterator#next

Can it be one callback?

Say instead of end pass null, null, null to the next callback.

This way we won't have a "either one or the other callback gets called" situation.

Implement write_buffer_size option

Supplied when you open a database; default is 4MB. Controls the size of the memtable (which is backed by the log file). When it reaches this size a compaction into level0 (and higher if the number is big enough) sst files will take place. Can make it faster for inputting large amounts of data in one go.

node-gyp rebuild error (as part of PouchDB)

I got this error on a Windows7 machine with the latest version of node-gyp for 64 bit windows machines.

G:\wwwroot\NodeWork\node_modules\pouchdb\node_modules\level\node_modules\leveldown>node "C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bin....\node_modules\node-gyp\bin\node-gyp.js" rebuild
npm http GET http://registry.npmjs.org/pouchdb
npm http 200 http://registry.npmjs.org/pouchdb
npm http GET http://registry.npmjs.org/pouchdb/-/pouchdb-1.0.0.tgz
npm http 200 http://registry.npmjs.org/pouchdb/-/pouchdb-1.0.0.tgz
npm http GET http://registry.npmjs.org/pouchdb-mapreduce/0.2.0
npm http GET http://registry.npmjs.org/level
npm http 200 http://registry.npmjs.org/pouchdb-mapreduce/0.2.0
npm http 200 http://registry.npmjs.org/level
npm http GET http://registry.npmjs.org/pouchdb-mapreduce/-/pouchdb-mapreduce-0.2.0.tgz
npm http GET http://registry.npmjs.org/level/-/level-0.18.0.tgz
npm http 200 http://registry.npmjs.org/pouchdb-mapreduce/-/pouchdb-mapreduce-0.2.0.tgz
npm http 200 http://registry.npmjs.org/level/-/level-0.18.0.tgz
npm http GET http://registry.npmjs.org/request
npm http 200 http://registry.npmjs.org/request
npm http GET http://registry.npmjs.org/request/-/request-2.28.0.tgz
npm http 200 http://registry.npmjs.org/request/-/request-2.28.0.tgz
npm http GET http://registry.npmjs.org/pouchdb-collate/0.1.0
npm http GET http://registry.npmjs.org/level-packager
npm http GET http://registry.npmjs.org/tunnel-agent
npm http GET http://registry.npmjs.org/aws-sign2
npm http GET http://registry.npmjs.org/oauth-sign
npm http GET http://registry.npmjs.org/json-stringify-safe
npm http GET http://registry.npmjs.org/http-signature
npm http GET http://registry.npmjs.org/node-uuid
npm http 200 http://registry.npmjs.org/pouchdb-collate/0.1.0
npm http GET http://registry.npmjs.org/qs
npm http 200 http://registry.npmjs.org/aws-sign2
npm http 200 http://registry.npmjs.org/oauth-sign
npm http 200 http://registry.npmjs.org/tunnel-agent
npm http 200 http://registry.npmjs.org/json-stringify-safe
npm http 200 http://registry.npmjs.org/level-packager
npm http GET http://registry.npmjs.org/leveldown
npm http GET http://registry.npmjs.org/form-data
npm http GET http://registry.npmjs.org/tough-cookie
npm http GET http://registry.npmjs.org/mime
npm http 200 http://registry.npmjs.org/http-signature
npm http 200 http://registry.npmjs.org/node-uuid
npm http 200 http://registry.npmjs.org/form-data
npm http 200 http://registry.npmjs.org/qs
npm http 200 http://registry.npmjs.org/mime
npm http 200 http://registry.npmjs.org/tough-cookie
npm http GET http://registry.npmjs.org/forever-agent
npm http GET http://registry.npmjs.org/pouchdb-collate/-/pouchdb-collate-0.1.0.tgz
npm http 200 http://registry.npmjs.org/forever-agent
npm http GET http://registry.npmjs.org/level-packager/-/level-packager-0.18.0.tgz
npm http 200 http://registry.npmjs.org/pouchdb-collate/-/pouchdb-collate-0.1.0.tgz
npm http 200 http://registry.npmjs.org/leveldown
npm http 200 http://registry.npmjs.org/level-packager/-/level-packager-0.18.0.tgz
npm http GET http://registry.npmjs.org/leveldown/-/leveldown-0.10.2.tgz
npm http GET http://registry.npmjs.org/hawk
npm http 200 http://registry.npmjs.org/leveldown/-/leveldown-0.10.2.tgz
npm http 200 http://registry.npmjs.org/hawk
npm http GET http://registry.npmjs.org/combined-stream
npm http 200 http://registry.npmjs.org/combined-stream
npm http GET http://registry.npmjs.org/punycode
npm http 200 http://registry.npmjs.org/punycode
npm http GET http://registry.npmjs.org/async
npm http 200 http://registry.npmjs.org/async
npm http GET http://registry.npmjs.org/ctype/0.5.2
npm http GET http://registry.npmjs.org/asn1/0.1.11
npm http GET http://registry.npmjs.org/assert-plus/0.1.2
npm http 200 http://registry.npmjs.org/ctype/0.5.2
npm http 200 http://registry.npmjs.org/asn1/0.1.11
npm http GET http://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz
npm http 200 http://registry.npmjs.org/assert-plus/0.1.2
npm http GET http://registry.npmjs.org/assert-plus/-/assert-plus-0.1.2.tgz
npm http 200 http://registry.npmjs.org/assert-plus/-/assert-plus-0.1.2.tgz
npm http 200 http://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz
npm http GET http://registry.npmjs.org/ctype/-/ctype-0.5.2.tgz
npm http 200 http://registry.npmjs.org/ctype/-/ctype-0.5.2.tgz
npm http GET http://registry.npmjs.org/sntp
npm http GET http://registry.npmjs.org/boom
npm http GET http://registry.npmjs.org/cryptiles
npm http GET http://registry.npmjs.org/hoek
npm http 200 http://registry.npmjs.org/cryptiles
npm http 200 http://registry.npmjs.org/boom
npm http 200 http://registry.npmjs.org/sntp
npm http 200 http://registry.npmjs.org/hoek
npm http GET http://registry.npmjs.org/delayed-stream/0.0.5
npm http 200 http://registry.npmjs.org/delayed-stream/0.0.5
npm http GET http://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz
npm http 200 http://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz
npm http GET http://registry.npmjs.org/bindings
npm http GET http://registry.npmjs.org/nan
npm http GET http://registry.npmjs.org/levelup
npm http 200 http://registry.npmjs.org/bindings
npm http 200 http://registry.npmjs.org/nan
npm http GET http://registry.npmjs.org/nan/-/nan-0.6.0.tgz
npm http 200 http://registry.npmjs.org/levelup
npm http GET http://registry.npmjs.org/levelup/-/levelup-0.18.2.tgz
npm http 200 http://registry.npmjs.org/nan/-/nan-0.6.0.tgz
npm http 200 http://registry.npmjs.org/levelup/-/levelup-0.18.2.tgz
Traceback (most recent call last):
File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\gyp_main.py", line 18, in
sys.exit(gyp.script_main())
File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp__init__.py", line 534, in script_main
return main(sys.argv[1:])
File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp__init__.py", line 527, in main
return gyp_main(args)
File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp__init__.py", line 503, in gyp_main
options.circular_check)
File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp__init__.py", line 98, in Load
generator.CalculateVariables(default_variables, params)
File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\generator\msvs.py", line 1798, in CalculateVariables
generator_flags.get('msvs_version', 'auto'))
File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\MSVSVersion.py", line 400, in SelectVisualStudioVersion
versions = _DetectVisualStudioVersions(version_map[version], 'e' in version)
File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\MSVSVersion.py", line 337, in _DetectVisualStudioVersions
path = _RegistryGetValue(keys[index], 'InstallDir')
File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\MSVSVersion.py", line 175, in _RegistryGetValue
text = _RegistryQuery(key, value)
File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\MSVSVersion.py", line 157, in _RegistryQuery
text = _RegistryQueryBase('Sysnative', key, value)
File "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\MSVSVersion.py", line 128, in _RegistryQueryBase
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
File "C:\Python27\lib\subprocess.py", line 703, in init
errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "C:\Python27\lib\subprocess.py", line 829, in _get_handles
p2cread = _subprocess.GetStdHandle(_subprocess.STD_INPUT_HANDLE)
WindowsError: [Error 6] The handle is invalid
gypnpm http GET http://registry.npmjs.org/xtend
npm http GET http://registry.npmjs.org/concat-stream
npm http GET http://registry.npmjs.org/errno
npm http GET http://registry.npmjs.org/deferred-leveldown
npm http GET http://registry.npmjs.org/semver
npm http GET http://registry.npmjs.org/bops
npm http GET http://registry.npmjs.org/readable-stream
npm http GET http://registry.npmjs.org/prr
npm http 200 http://registry.npmjs.org/xtend
npm http 200 http://registry.npmjs.org/concat-stream
npm http 200 http://registry.npmjs.org/errno
npm http 200 http://registry.npmjs.org/deferred-leveldown
npm http GET http://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-0.1.0.tgz
npm http 200 http://registry.npmjs.org/prr
npm http 200 http://registry.npmjs.org/semver
npm http 200 http://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-0.1.0.tgz
npm http 200 http://registry.npmjs.org/bops
npm http GET http://registry.npmjs.org/bops/-/bops-0.1.1.tgz
npm http 200 http://registry.npmjs.org/readable-stream
npm http 200 http://registry.npmjs.org/bops/-/bops-0.1.1.tgz
npm http GET http://registry.npmjs.org/bops
npm http 200 http://registry.npmjs.org/bops
npm http GET http://registry.npmjs.org/abstract-leveldown
npm http 200 http://registry.npmjs.org/abstract-leveldown
npm http GET http://registry.npmjs.org/object-keys
npm http 200 http://registry.npmjs.org/object-keys
npm http GET http://registry.npmjs.org/base64-js/0.0.2
npm http 200 http://registry.npmjs.org/base64-js/0.0.2
npm http GET http://registry.npmjs.org/base64-js/-/base64-js-0.0.2.tgz
npm http 200 http://registry.npmjs.org/base64-js/-/base64-js-0.0.2.tgz
npm http GET http://registry.npmjs.org/to-utf8/0.0.1
npm http 200 http://registry.npmjs.org/to-utf8/0.0.1
npm http GET http://registry.npmjs.org/to-utf8/-/to-utf8-0.0.1.tgz
npm http 200 http://registry.npmjs.org/to-utf8/-/to-utf8-0.0.1.tgz
npm ERR! [email protected] install: node-gyp rebuild
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is most likely a problem with the leveldown package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node-gyp rebuild
npm ERR! You can get their info via:
npm ERR! npm owner ls leveldown
npm ERR! There is likely additional logging output above.

npm ERR! System Windows_NT 6.1.7601
npm ERR! command "C:\Program Files\nodejs\node.exe" "C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js" "install" "pouchdb" "--save"
npm ERR! cwd G:\wwwroot\NodeWork
npm ERR! node -v v0.10.23
npm ERR! npm -v 1.3.17
npm ERR! code ELIFECYCLE
npm

Crash in 'put' in an unopened database

I was trying to reproduce the spurious crashes I get, and I found that putting something into a non-opened database leads to a nice segfault on node v0.10.5.

var leveldown = require("leveldown")
  , db = leveldown("./db")
  , i

for(i=0; i < 100; i++) {
  db.put("a" + i, "b" + i, function(err) {
    if (err) throw err
  });
}

iterator Seek

Please expose the iterator's seek and prev methods. Would be nice to be able to seek on an already created iterator.

Unable to build when path has a space in it

I'm currently on a train, so i'm not able to look into this properly - but I wanted to make a note with what I did.

OS X 10.8.4
npm 1.3.8
Directory name actually had two spaces in it (~/Google Drive/Stainlessed/Talks/AMQP Workshop/conglomerate)

npm install level --save

Relevant section of output

CXX(target) Release/obj.target/leveldown/src/leveldown_async.o
clang: error: no such file or directory: 'Drive/Stainlessed/Talks/AMQP'
clang: error: no such file or directory: 'Workshop/conglomerate/node_modules/level/node_modules/leveldown/node_modules/nan'

I've since realised that it's a bit daft having this inside my google drive folder, and moved it :)

Implement GetProperty

Here's a fun undocumented API that we could expose:

  //  "leveldb.num-files-at-level<N>" - return the number of files at level <N>,
  //     where <N> is an ASCII representation of a level number (e.g. "0").
  //  "leveldb.stats" - returns a multi-line string that describes statistics
  //     about the internal operation of the DB.
  //  "leveldb.sstables" - returns a multi-line string that describes all
  //     of the sstables that make up the db contents.
  virtual bool GetProperty(const Slice& property, std::string* value) = 0;

Reverse Iterators should 'skip to previous' when start key doesn't exist

LevelDB only does 'skip to next' when start key doesn't exist but when you want to iterate in reverse you want your start point to be the previous closest key where your actual start doesn't exist.
We can detect and handle this situation for reverse Iterators. Edge case is end-of-database which will cause !Valid().

memory leak

This may be related to the previous issue for levelup (Level/levelup#140), but I get high memory usage when calling db.get() lots of times when the key is not the same each time. In this example, I use a unique key, each exists in the db, when called 5000000 times memory usage goes above 500M within seconds.

https://gist.github.com/kylegetson/5599592

I'm working on a web service that will wrap levelup, and I expect many millions of gets/puts.

It seems like in some cases the memory is cleaned up, might be related to calling put.
https://gist.github.com/kylegetson/5599722

Let leveldown use abstract-leveldown

We could potenitally avoid some logic duplication by letting leveldown use abstract-leveldow.

index.js would then end up with something like this:

var util = require('util')
  , AbstractLevelDOWN = require('./').AbstractLevelDOWN

function LevelDOWN (location) {
  if (!(this instanceof LevelDOWN))
    return new LevelDOWN(location)

  AbstractLevelDOWN.call(this, location)
  this._db = require('bindings')('leveldown.node').leveldown(location)
}

util.inherits(LevelDOWN, AbstractLevelDOWN)

LevelDOWN.prototype._open = function(options, callback) {
  this._db.open(options, callback)
}

// etc

module.exports = LevelDOWN

Would it make sense?

database corruption

I've been having some users complain about npmd corrupting the database

dominictarr/npmd#10

do you know if there is any way to reproduce the sorts of database corruption that are repairable?

or any documentation how it happens and what repair does?

can't build on smartos

gcc version: 4.6.1

bad output: make: *** No rule to make target 'Release/obj.target/leveldb/deps/leveldb/leveldb-1.11.0/db/builder.o', needed by 'Release/obj.target/deps/leveldb/leveldb.a'. Stop.

version: 0.6.1, version 0.5.0 works!

help! i need somebody, help! not just anybody, help! you know i need @rvagg, help!

Windows memory leak?

Not entirely sure, but I think there might be a memory leak for leveldown on Windows.

I've been trying to bulk load data into leveldb via batch puts using level on Windows 7. Somewhere between 1.5 and 2 million puts, things come to a halt and the process dies with at out-of-memory fatal exception.

Here's a gist to reproduce the behavior: https://gist.github.com/rickbergfalk/6309444/

Don't process close() until current in-flight async ops are complete

Will involve more tracking like the delete-iterators-on-close work. Each async operation will have to increment a counter when starting and decrement when done, will also need to trigger a possible-close function when done.
Without this, a segfault is possible when you close() while an operation is in-flight.

reading with wrong encoding from levelup can crash process

  1. create a new db, encoding = utf8
  2. stick some stuff in it
  3. open it with levelup, encoding = json
  4. run a readStream

crash

Found by using lev which assumes json encoding by default, on a db that was only utf8. This shouldn't be a way to crash a process.

LevelDB 1.15

https://groups.google.com/forum/#!topic/leveldb/VM5nYLvLVME

  • switched from mmap based writing to simpler stdio based writing. Has a
    minor impact (0.5 microseconds) on microbenchmarks for asynchronous
    writes. Synchronous writes speed up from 30ms to 10ms on linux/ext4.
    Should be much more reliable on diverse platforms.

Revert b3a7793

  • compaction errors now immediately put the database into a read-only
    mode (until it is re-opened). As a downside, a disk going out of
    space and then space being created will require a re-open to recover
    from, whereas previously that would happen automatically. On the
    plus side, many corruption possibilities go away.
  • force the DB to enter an error-state so that all future writes fail
    when a synchronous log write succeeds but the sync fails.

Closing and opening the db become important again, I remember us saying "when would you need to do that anyways".

  • repair now regenerates sstables that exhibit problems
  • fix issue 218 - Use native memory barriers on OSX
  • fix issue 212 - QNX build is broken
  • fix build on iOS with xcode 5
  • make tests compile and pass on windows

store and manage state

db.open() is the only valid operation when a database is not open. db.open() must finish before other operations are permitted. db.close() must prevent any other operations executing until it's complete at which point you can only run db.open() again.

ugh.

Update deps

Both leveldb & snappy have been updated (leveldb 1.7.0 -> 1.9.0, snappy 1.0.5 -> 1.1.0), compared to the versions bundled in leveldown. What is the routine for upgrading dependencies? E.g. are we only upgrading dependencies on minor-version, or would it be possible to get a dependency upgrade in to 0.1.1?

error when installing on osx 10.9

when I try to install leveldown on 10.9, there is error

I also tried compile from leveldb code, also an error there,
does this cause by osx update?

leveldown log

$ npm install leveldown
npm http GET https://registry.npmjs.org/leveldown
npm http 304 https://registry.npmjs.org/leveldown
npm http GET https://registry.npmjs.org/bindings
npm http GET https://registry.npmjs.org/nan
npm http 304 https://registry.npmjs.org/bindings
npm http 304 https://registry.npmjs.org/nan

> [email protected] install /Users/nick/dev-src/js/node_modules/leveldown
> node-gyp rebuild

  CXX(target) Release/obj.target/leveldb/deps/leveldb/leveldb-1.14.0/db/builder.o
In file included from ../deps/leveldb/leveldb-1.14.0/db/builder.cc:5:
In file included from ../deps/leveldb/leveldb-1.14.0/db/builder.h:8:
../deps/leveldb/leveldb-1.14.0/include/leveldb/status.h:16:10: fatal error:
      'string' file not found
#include <string>
         ^
1 error generated.
make: *** [Release/obj.target/leveldb/deps/leveldb/leveldb-1.14.0/db/builder.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/Users/nick/local/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:267:23)
gyp ERR! stack     at ChildProcess.EventEmitter.emit (events.js:98:17)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (child_process.js:789:12)
gyp ERR! System Darwin 13.0.0
gyp ERR! command "node" "/Users/nick/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /Users/nick/dev-src/js/node_modules/leveldown
gyp ERR! node -v v0.10.21
gyp ERR! node-gyp -v v0.10.10
gyp ERR! not ok
npm ERR! weird error 1
npm ERR! not ok code 0

leveldb log

$ make
c++  -dynamiclib -install_name /Users/nick/dev-src/cpp/leveldb/libleveldb.dylib.1 -I. -I./include -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX -O2 -DNDEBUG        -fPIC db/builder.cc db/c.cc db/db_impl.cc db/db_iter.cc db/dbformat.cc db/filename.cc db/log_reader.cc db/log_writer.cc db/memtable.cc db/repair.cc db/table_cache.cc db/version_edit.cc db/version_set.cc db/write_batch.cc table/block.cc table/block_builder.cc table/filter_block.cc table/format.cc table/iterator.cc table/merger.cc table/table.cc table/table_builder.cc table/two_level_iterator.cc util/arena.cc util/bloom.cc util/cache.cc util/coding.cc util/comparator.cc util/crc32c.cc util/env.cc util/env_posix.cc util/filter_policy.cc util/hash.cc util/histogram.cc util/logging.cc util/options.cc util/status.cc  port/port_posix.cc -o libleveldb.dylib.1.14
In file included from db/builder.cc:5:
In file included from ./db/builder.h:8:
./include/leveldb/status.h:16:10: fatal error: 'string' file not found
#include <string>
         ^
1 error generated.
make: *** [libleveldb.dylib.1.14] Error 1

Node leveldown under Ubuntu: undefined symbol error on require

I have node v0.11.9 installed with nvm under Ubuntu 12.04 precise and [email protected] (compiled without warnings), but when I try to load leveldown I get the following error:

$ node
> require ('leveldown')
Error: /home/direvius/learn/leveldb/node_modules/leveldown/build/Release/leveldown.node: undefined symbol: _ZN4node12MakeCallbackEN2v86HandleINS0_6ObjectEEENS1_INS0_8FunctionEEEiPNS1_INS0_5ValueEEE
    at Module.load (module.js:349:32)
    at Function.Module._load (module.js:305:12)
    at Module.require (module.js:357:17)
    at require (module.js:373:17)
    at bindings (/home/direvius/learn/leveldb/node_modules/leveldown/node_modules/bindings/bindings.js:76:44)
    at Object.<anonymous> (/home/direvius/learn/leveldb/node_modules/leveldown/index.js:1:99)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:349:32)
    at Function.Module._load (module.js:305:12)

This question on stackoverflow

multiread

An operation that is like a batch, but for gets, but without the keys being adjacent in order.

I mention this because at campjs @rvagg and I discussed where the boundry between userland and core should be, regarding issues like: #9 (comment)

We couldn't think of many features that you might want to do in the C binding, but we decided that we should evaluate them on a case-by-case basis for a bit, until it becomes clearer.

So this issue is mainly intended for discussion, although it may be useful.

hmm, so for the purposes of discussion, the api is

db.getAll(arrayOfKeys, cb)

Would an operation like this also benefit from crossing the c-js boundry only once,
passing an array each way?

idea for fast bulk inserts

So, I've heard that it's fastest to insert records in reverse because of the skip list.

This is not how data is normally stored... much more often, it's in the other direction.

But, what if you reversed the comparator?

Then the database would think you are inserting everything in reverse!
So, maybe this would "just work" more often?

Another idea: what if you could make a few optimizations to the skip list,
like, remember the last point you inserted, so if you are often inserting a series of sequential values (logging or time series data) then it would only have to search once?

I don't really know that much about skiplists, do they need to be balanced?
Looking at it now, but just guessing at ideas...

does the log file have timestamps/sequence numbers?

And if so, is it possible to access them?

I'm mainly curious at the moment,
thinking about how it might be possible to take modular databases to the next level.

One way of chaining databases is via a log & sequence numbers,
similar to the way that @mikeal does indexes in couchup.

Since leveldb does have a log,
surely it must have log numbers?

It would be interesting to get at the logs directly,
because then you have skipped a step, and thus gained performance (reduced wastage)

benchmarks broken

  • They miss the optimist dependency
  • db-bench.js misses ./random-data
  • write-random.js misses ../../lmdb/
  • write-sorted.js works

can't install on CentOS 5.8

npm install levelup errors with:
make: Entering directory `/usr/local/nextgen/groups/node_modules/levelup/node_modules/leveldown/build'
CXX(target) Release/obj.target/leveldb/deps/leveldb/leveldb-1.9.0/db/builder.o
cc1plus: error: unrecognized command line option "-Wno-unused-but-set-variable"
make: *** [Release/obj.target/leveldb/deps/leveldb/leveldb-1.9.0/db/builder.o] Error 1

complete log:
http://hastebin.com/redukihana.hs

node -v
v0.10.4

cat /etc/redhat-release
CentOS release 5.8 (Final)

g++ -v
Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --disable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=x86_64-redhat-linux
Thread model: posix
gcc version 4.1.2 20080704 (Red Hat 4.1.2-52)

Change in c++ Buffer api

Ran across this and wanted to give you a heads up. Once nodejs/node-v0.x-archive#4964 lands there's no more need to access the Buffer object via ->handle_ (and actually that won't be available). Buffer::New() just returns a new object.

Also, added Buffer::Use() which uses the existing char* instead of making a copy. Just in case you need it.

Implement CompactRange

This is pretty hard-core, but if you've know you've been doing some heavy work in a particular (not too big) key range then you could order a compaction of that range rather than waiting for leveldb to get around to the range (it normally works its way sequentially through the key ranges that make up files at each "level").

Might be handy, but it might also be best to wait for someone to request that we implement this feature?

  // Compact the underlying storage for the key range [*begin,*end].
  // In particular, deleted and overwritten versions are discarded,
  // and the data is rearranged to reduce the cost of operations
  // needed to access the data.  This operation should typically only
  // be invoked by users who understand the underlying implementation.
  //
  // begin==NULL is treated as a key before all keys in the database.
  // end==NULL is treated as a key after all keys in the database.
  // Therefore the following call will compact the entire database:
  //    db->CompactRange(NULL, NULL);
  virtual void CompactRange(const Slice* begin, const Slice* end) = 0;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.