An Erlang NIF for the "Lightening MDB" BTREE used in OpenLDAP.
Find a file
2012-09-30 23:20:29 +02:00
c_src avoid copying value twice during a get/1 (Howard Chu) 2012-09-30 23:20:29 +02:00
include add open/2 and open/3 2012-09-30 22:20:15 +02:00
src add open/2 and open/3 2012-09-30 22:16:46 +02:00
3rdLibs initial release 2012-09-30 19:42:44 +02:00
ChangeLog initial release 2012-09-30 19:42:44 +02:00
LICENSE initial release 2012-09-30 19:42:44 +02:00
Makefile initial release 2012-09-30 19:42:44 +02:00
README.md avoid copying value twice during a get/1 (Howard Chu) 2012-09-30 23:20:29 +02:00
rebar initial release 2012-09-30 19:42:44 +02:00
rebar.config initial release 2012-09-30 19:42:44 +02:00
start.sh initial release 2012-09-30 19:42:44 +02:00

EMDB

EMDB is a NIF library for the Memory-Mapped Database database, aka. MDB.

The main purpose of this package is to provide a very fast Riak backend.

But this module could also be used as a general key-value store to replace:

Requirements

  • Erlang R14B04+
  • GCC 4.2+ or MS VisualStudio 2010+

Build

$ make

API

The following functions were implemented:

  • open/1: equivalent to emdb:open(DirName, 10485760).
  • open/2: equivalent to emdb:open(DirName, 10485760, 0).
  • open/3: creates a new MDB database. This call also re-open an already existing one. Arguments are:
    • DirName: database directory name
    • MapSize: database map size (see map.hrl)
    • EnvFlags: database environment flags (see map.hrl). The possible values are defined in emdb.hrl.
  • close/2: closes the database
  • put/2: inserts Key with value Val into the database. Assumes that the key is not present, 'key_exit' is returned otherwise.
  • get/1: retrieves the value stored with Key in the database.
  • del/1: Removes the key-value with key Key from database.
  • update/2: inserts Key with value Val into the database if the key is not present, otherwise updates Key to value Val.
  • drop/1: deletes all key-value pairs in the database.

Usage

$ make

$ ./start.sh

%% create a new database
1> {ok, Handle} = emdb:open("/tmp/emdb1").

%% insert the key <<"a">> with value <<"1">>
2> ok = Handle:put(<<"a">>, <<"1">>).

%% try to re-insert the same key <<"a">>
3> key_exist = Handle:put(<<"a">>, <<"2">>).

%% add a new key-value pair
4> ok = Handle:put(<<"b">>, <<"2">>).

%% search a non-existing key <<"c">>
5> none = Handle:get(<<"c">>).

%% retrieve the value for key <<"b">>
6> {ok, <<"2">>} = Handle:get(<<"b">>).

%% retrieve the value for key <<"a">>
7> {ok, <<"1">>} = Handle:get(<<"a">>).

%% delete key <<"b">>
8> ok = Handle:del(<<"b">>).

%% search a non-existing key <<"b">>
9> none = Handle:get(<<"b">>).

%% delete a non-existing key <<"z">>
10> none = Handle:del(<<"z">>).

%% ensure key <<"a">>'s value is still <<"1">>
11> {ok, <<"1">>} = Handle:get(<<"a">>).
%% update the value for key <<"a">>
12> ok = Handle:update(<<"a">>, <<"7">>).

%% check the new value for key <<"a">>
13> {ok, <<"7">>} = Handle:get(<<"a">>).

%% delete all key-value pairs in the database
14> ok = Handle:drop().

%% try to retrieve key <<"a">> value
15> none = Handle:get(<<"a">>).

%% close the database
16> ok = Handle:close().

...

17> q().  

####Note: The code below creates a new database with 80GB MapSize, avoid fsync after each commit (for max speed) and use the experimental MDB_FIXEDMAP.

{ok, Handle} = emdb:open("/tmp/emdb2", 85899345920, ?MDB_NOSYNC bor ?MDB_FIXEDMAP).

Performance

For maximum speed, this library use only binaries for both keys and values.

See the impressive microbench against:

  • Google's LevelDB
  • SQLite
  • Kyoto TreeDB
  • BerkeleyDB

MDB performs better on 64-bit arch.

Supported OSes

Should work on 32/64-bit architectures:

  • Linux
  • OSX
  • FreeBSD
  • Windows

TODO

  • Unit tests
  • PropEr testing
  • Bulk "writing"

Volunteers are always welcome!

Status

Work in progress. Don't use it in production!

LICENSE

EMDB is Copyright (C) 2012 by Aleph Archives, and released under the OpenLDAP License.