Skip to content

Commit

Permalink
feature: Support setting size of LRU-cache
Browse files Browse the repository at this point in the history
  • Loading branch information
kesla committed Jan 3, 2013
1 parent 936674b commit 9237111
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 1 deletion.
6 changes: 6 additions & 0 deletions README.md
Expand Up @@ -116,6 +116,8 @@ db.get('foo', function (err, value) {

* `'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`)*: The size (in bytes) of the in-memory [LRU](http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used) cache with frequently used uncompressed block contents.

* `'encoding'` *(string, default: `'utf8'`)*: The encoding of the keys and values passed through Node.js' `Buffer` implementation (see [Buffer#toString()](http://nodejs.org/docs/latest/api/buffer.html#buffer_buf_tostring_encoding_start_end))
<p><code>'utf8'</code> is the default encoding for both keys and values so you can simply pass in strings and expect strings from your <code>get()</code> operations. You can also pass <code>Buffer</code> objects as keys and/or values and conversion will be performed.</p>
<p>Supported encodings are: hex, utf8, ascii, binary, base64, ucs2, utf16le.</p>
Expand Down Expand Up @@ -161,6 +163,8 @@ If you provide a `'sync'` value of `true` in your `options` object, LevelDB will

Encoding of the `key` objects will adhere to `encoding` option(s) provided to <a href="#ctor"><code>levelup()</code></a>, although you can provide alternative encoding settings in the options for `get()` (it's recommended that you stay consistent in your encoding of keys and values in a single store).

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

--------------------------------------------------------
<a name="del"></a>
### db.del(key[, options][, callback])
Expand Down Expand Up @@ -269,6 +273,8 @@ Additionally, you can supply an options object as the first parameter to `readSt

* `'limit'` *(number, default: `-1`)*: limit the number of results collected by this stream. 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.

--------------------------------------------------------
<a name="keyStream"></a>
### db.keyStream([options])
Expand Down
4 changes: 4 additions & 0 deletions src/database.cc
Expand Up @@ -125,6 +125,7 @@ Handle<Value> Database::Open (const Arguments& args) {
BOOLEAN_OPTION_VALUE(optionsObj, createIfMissing)
BOOLEAN_OPTION_VALUE(optionsObj, errorIfExists)
BOOLEAN_OPTION_VALUE(optionsObj, compression)
UINT32_OPTION_VALUE(optionsObj, cacheSize, 8 << 20)
Persistent<Function> callback = Persistent<Function>::New(Local<Function>::Cast(args[2]));

OpenWorker* worker = new OpenWorker(
Expand All @@ -134,6 +135,7 @@ Handle<Value> Database::Open (const Arguments& args) {
, createIfMissing
, errorIfExists
, compression
, cacheSize
);
AsyncQueueWorker(worker);

Expand Down Expand Up @@ -196,12 +198,14 @@ Handle<Value> Database::Get (const Arguments& args) {
STRING_OR_BUFFER_TO_SLICE(key, keyBuffer)
Local<Object> optionsObj = Local<Object>::Cast(args[1]);
BOOLEAN_OPTION_VALUE_DEFTRUE(optionsObj, asBuffer)
BOOLEAN_OPTION_VALUE_DEFTRUE(optionsObj, fillCache)

ReadWorker* worker = new ReadWorker(
database
, callback
, key
, asBuffer
, fillCache
, keyBuffer
);
AsyncQueueWorker(worker);
Expand Down
2 changes: 2 additions & 0 deletions src/database.h
Expand Up @@ -17,8 +17,10 @@ using namespace leveldb;
LU_OPTION ( createIfMissing ); // for open()
LU_OPTION ( errorIfExists ); // for open()
LU_OPTION ( compression ); // for open()
LU_OPTION ( cacheSize ); // for open()
LU_OPTION ( sync ); // for put() and delete()
LU_OPTION ( asBuffer ); // for get()
LU_OPTION ( fillCache ); // for get() and readStream()
LU_STR ( key );
LU_STR ( value );
LU_STR ( type );
Expand Down
5 changes: 5 additions & 0 deletions src/database_async.h
Expand Up @@ -8,6 +8,7 @@
#include <node.h>
#include "async.h"
#include "batch.h"
#include "leveldb/cache.h"

using namespace std;
using namespace v8;
Expand All @@ -22,13 +23,15 @@ class OpenWorker : public AsyncWorker {
, bool createIfMissing
, bool errorIfExists
, bool compression
, uint32_t cacheSize
) : AsyncWorker(database, callback)
, location(location)
{
options = new Options();
options->create_if_missing = createIfMissing;
options->error_if_exists = errorIfExists;
options->compression = compression ? kSnappyCompression : kNoCompression;
options->block_cache = NewLRUCache(cacheSize);
};

virtual ~OpenWorker ();
Expand Down Expand Up @@ -79,11 +82,13 @@ class ReadWorker : public IOWorker {
, Persistent<Function> callback
, Slice key
, bool asBuffer
, bool fillCache
, Persistent<Value> keyPtr
) : IOWorker(database, callback, key, keyPtr)
, asBuffer(asBuffer)
{
options = new ReadOptions();
options->fill_cache = fillCache;
};

virtual ~ReadWorker ();
Expand Down
3 changes: 2 additions & 1 deletion src/iterator.cc
Expand Up @@ -139,11 +139,12 @@ Handle<Value> levelup::Iterator::New (const Arguments& args) {
BOOLEAN_OPTION_VALUE_DEFTRUE(optionsObj, values)
BOOLEAN_OPTION_VALUE_DEFTRUE(optionsObj, keyAsBuffer)
BOOLEAN_OPTION_VALUE_DEFTRUE(optionsObj, valueAsBuffer)
BOOLEAN_OPTION_VALUE(optionsObj, fillCache)
int limit = -1;
if (args[1]->ToObject()->Has(option_limit)) {
limit = Local<Integer>::Cast(args[1]->ToObject()->Get(option_limit))->Value();
}
Iterator* iterator = new Iterator(database, start, end, reverse, keys, values, limit, keyAsBuffer, valueAsBuffer);
Iterator* iterator = new Iterator(database, start, end, reverse, keys, values, limit, fillCache, keyAsBuffer, valueAsBuffer);
iterator->Wrap(args.This());

return args.This();
Expand Down
3 changes: 3 additions & 0 deletions src/iterator.h
Expand Up @@ -23,6 +23,7 @@ LU_OPTION ( keys );
LU_OPTION ( values );
LU_OPTION ( keyAsBuffer );
LU_OPTION ( valueAsBuffer );
LU_OPTION ( fillCache );

Handle<Value> CreateIterator (const Arguments& args);

Expand All @@ -43,6 +44,7 @@ class Iterator : public node::ObjectWrap {
, bool keys
, bool values
, int limit
, bool fillCache
, bool keyAsBuffer
, bool valueAsBuffer
) : database(database)
Expand All @@ -56,6 +58,7 @@ class Iterator : public node::ObjectWrap {
, valueAsBuffer(valueAsBuffer)
{
options = new ReadOptions();
options->fill_cache = fillCache;
dbIterator = NULL;
count = 0;
};
Expand Down
2 changes: 2 additions & 0 deletions src/levelup.h
Expand Up @@ -39,6 +39,8 @@
bool opt = optionsObj->Has(option_ ## opt) && optionsObj->Get(option_ ## opt)->BooleanValue();
#define BOOLEAN_OPTION_VALUE_DEFTRUE(optionsObj, opt) \
bool opt = !optionsObj->Has(option_ ## opt) || optionsObj->Get(option_ ## opt)->BooleanValue();
#define UINT32_OPTION_VALUE(optionsObj, opt, default) \
uint32_t opt = optionsObj->Has(option_ ## opt) ? optionsObj->Get(option_ ## opt)->Uint32Value() : default;

void RunCallback (v8::Persistent<v8::Function> callback, v8::Local<v8::Value> argv[], int length);

Expand Down

0 comments on commit 9237111

Please sign in to comment.