Skip to content

IndigoUnited/node-level-atomics

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

level-atomics

Atomic operators for LevelDB.

Build Status Coverage Status Codacy Badge

Installing

npm install level-atomics

Introduction

This module adds a bunch of typical atomic operations, like insert, replace and counter (increment/decrement) to LevelDB, and adds capacity to multiple parallel operations, like multi gets, multi inserts, and so on.

Core goals

  • All key-value operations should be multi friendly (support multiple operations in one call).
  • All new operations should be atomic.
  • Common operations should be easy to use, and not use Error for common, expected scenarios:
    • get and replace don't return Error if keys don't exist, and instead provide an additional misses argument.
    • insert doesn't return Error if key already exists, and instead provides an existing argument.
    • counter always succeeds, even if key does not exist, and you can provide initial value for those cases.
var level   = require('level');
var atomics = require('level-atomics');

var db = atomics(level('./tmp', {
    valueEncoding: 'json' // not required, but makes it easier to handle numbers
}));

db.get(['a', 'b', 'c'], function (err, res, misses) {
    if (err) {
        return console.error('Something went wrong:', err);
    }

    if (misses.length > 1) {
        console.log('These keys do not exist:', misses);
    } else {
        console.log(res.a);
        console.log(res.b);
        console.log(res.c);
    }
});

db.counter({
    some_key: 10
}, {
    initial: 10
}, function (err, res, misses) {
    if (err) {
        return console.error('Something went wrong:', err);
    }

    console.log(res.some_key); // will log 10
});

API


counter(tuples, [options,] callback) → db

Increments or decrements the keys' numeric value.

Note that JavaScript does not support 64-bit integers. You might receive an inaccurate value if the number is greater than 53-bits (JavaScript's maximum integer precision).

  • tuples: tuple (object with keys and respective deltas).
  • options: Besides the same options as level.put, you have:
    • initial: Initial value for the key if it does not exist (the actual value that will be used, not added to delta). Specifying a value of undefined will cause the operation to fail if key doesn't exist, otherwise this value must be equal to or greater than 0.
  • callback(err, results, misses)
    • results: object with keys and respective values.
    • misses: array of keys that don't exist.

del(keys, [options,] callback) → db

Delete keys.

  • keys: array or string.
  • options: same options as level.del:
  • callback(err)

get(keys, [options,] callback) → db

Retrieve keys.

  • keys: array or string.
  • options: same options as level.get.
  • callback(err, results, misses)
    • results: object with keys and respective values.
    • misses: array of keys that don't exist.

insert(tuples, [options,] callback) → db

Will fail if the key already exists. Any key that already exists is returned in the callback in the existing parameter.

  • tuples: tuple (object with keys and respective values)
  • options: same options as level.put.
  • callback(err, existing)
    • existing: array of keys that already existed, and thus failed to be added.

put(tuples, [options,] callback) → db

Put keys.

  • tuples: tuple (object with keys and respective values)
  • options: same options as level.put.
  • callback(err)

replace(tuples, [options,] callback) → db

Identical to put, but will only succeed if the key exists already (i.e. the inverse of insert).

  • tuples: tuple (object with keys and respective values)
  • options: same options as level.put.
  • callback(err, misses)
    • misses: array of keys that don't exist.

db → original db

This property is the original DB that was wrapped. Useful if, for some reason, you need to access it.


Tuples

A tuple is an object with key and respective values, like so:

{
    a: 1,
    b: 2,
    c: 3
}

Many operations allow you to provide tuples for multi operations. As an example, you could provide the tuple above to insert, and the keys a, b and c would be inserted with the respective values.

As syntax sugar, and to avoid creating temporary objects like this:

// ...

var someKey   = 'foo';
var someValue = 'bar';
var tmp       = {};
tmp[someKey]  = someValue;
db.insert(tmp, function (err, res) {
    // ...
});

// ...

You can instead do the following:

// ...

var someKey   = 'foo';
var someValue = 'bar';

var tuple = require('level-atomics').tuple;

db.insert(tuple(someKey, someValue), function (err, res) {
    // ...
});

//...

You can provide to the tuple helper just a key and a value, or you can provide a couple of arrays of equal length, and tuple will map each of they keys to the respective values, like so:

tuple(['a', 'b', 'c'], [1, 2, 3]);

// will return
//
// {
//   a: 1,
//   b: 2,
//   c: 3
// }