2013-05-19 04:27:44 +00:00
EMDB
====
2012-09-30 17:42:44 +00:00
2013-05-19 04:27:44 +00:00
EMDB is a NIF library for the [Memory-Mapped Database ](http://highlandsun.com/hyc/mdb/ ) database, aka. MDB.
2012-09-30 17:42:44 +00:00
2013-05-19 04:27:44 +00:00
The main purpose of this package is to provide an Erlang API for this excellent BTREE implementation. Secondly to build an alternative Riak/KV [backend ](http://wiki.basho.com/Storage-Backends.html ) and Riak's AAE feature based on this. Finally it'd be nice to build an ETS-compatible API (ala "lets" for LevelDB) to ease adoption in other places where DETS is just not up to the task.
Requirements
------------
* Erlang R14B04+
* GCC 4.2+ or MS VisualStudio 2010+
Build
-----
$ make
API
---
The following functions were implemented:
2012-09-30 17:42:44 +00:00
2012-09-30 20:16:46 +00:00
* `open/1` : equivalent to `emdb:open(DirName, 10485760)` .
2012-09-30 20:55:45 +00:00
* `open/2` : equivalent to `emdb:open(DirName, 10485760, 0)` .
2012-09-30 20:16:46 +00:00
* `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 ](http://gitorious.org/mdb/mdb/blobs/master/libraries/libmdb/mdb.h ))
* EnvFlags: database environment flags (see [map.hrl ](http://gitorious.org/mdb/mdb/blobs/master/libraries/libmdb/mdb.h )). The possible values are defined in **emdb.hrl** .
2012-09-30 17:42:44 +00:00
* `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.
2013-05-19 04:27:44 +00:00
* `update/2` or `upd/2` : inserts Key with value Val into the database if the key is not present, otherwise updates Key to value Val.
2012-09-30 17:42:44 +00:00
* `drop/1` : deletes all key-value pairs in the database.
2013-05-19 04:19:01 +00:00
Usage
-----
2012-09-30 17:42:44 +00:00
2013-05-19 04:27:44 +00:00
```
2013-05-19 04:19:01 +00:00
$ make
2012-09-30 17:42:44 +00:00
$ ./start.sh
2013-05-19 04:19:01 +00:00
%% create a new database
1> {ok, Handle} = emdb:open("/tmp/emdb1").
2012-09-30 17:42:44 +00:00
2013-05-19 04:19:01 +00:00
%% insert the key < < "a">> with value < < "1">>
2> ok = emdb:put(Handle, < < "a">>, < < "1">>).
2012-09-30 17:42:44 +00:00
2013-05-19 04:19:01 +00:00
%% try to re-insert the same key < < "a">>
3> key_exist = emdb:put(Handle, < < "a">>, < < "2">>).
2012-09-30 17:42:44 +00:00
2013-05-19 04:19:01 +00:00
%% add a new key-value pair
4> ok = emdb:put(Handle, < < "b">>, < < "2">>).
2012-09-30 17:42:44 +00:00
2013-05-19 04:19:01 +00:00
%% search a non-existing key < < "c">>
5> none = emdb:get(Handle, < < "c">>).
2012-09-30 17:42:44 +00:00
2013-05-19 04:19:01 +00:00
%% retrieve the value for key < < "b">>
6> {ok, < < "2">>} = emdb:get(Handle, < < "b">>).
2012-09-30 17:42:44 +00:00
2013-05-19 04:19:01 +00:00
%% retrieve the value for key < < "a">>
7> {ok, < < "1">>} = emdb:get(Handle, < < "a">>).
2012-09-30 17:42:44 +00:00
2013-05-19 04:19:01 +00:00
%% delete key < < "b">>
8> ok = emdb:del(Handle, < < "b">>).
2012-09-30 17:42:44 +00:00
%% search a non-existing key < < "b">>
2013-05-19 04:19:01 +00:00
9> none = emdb:get(Handle, < < "b">>).
%% delete a non-existing key < < "z">>
10> none = emdb:del(Handle, < < "z">>).
2012-09-30 17:42:44 +00:00
2013-05-19 04:19:01 +00:00
%% ensure key < < "a">>'s value is still < < "1">>
11> {ok, < < "1">>} = emdb:get(Handle, < < "a">>).
2012-09-30 20:55:45 +00:00
2012-09-30 17:42:44 +00:00
%% update the value for key < < "a">>
2013-05-19 04:19:01 +00:00
12> ok = emdb:update(Handle, < < "a">>, < < "7">>).
2012-09-30 17:42:44 +00:00
%% check the new value for key < < "a">>
2013-05-19 04:19:01 +00:00
13> {ok, < < "7">>} = emdb:get(Handle, < < "a">>).
2012-09-30 17:42:44 +00:00
2013-05-19 04:19:01 +00:00
%% delete all key-value pairs in the database
14> ok = emdb:drop(Handle).
2012-09-30 17:42:44 +00:00
2013-05-19 04:19:01 +00:00
%% try to retrieve key < < "a">> value
15> none = emdb:get(Handle, < < "a">>).
2012-09-30 17:42:44 +00:00
2013-05-19 04:19:01 +00:00
%% close the database
16> ok = emdb:close(Handle).
2012-09-30 17:42:44 +00:00
2012-09-30 20:16:46 +00:00
...
2012-09-30 17:42:44 +00:00
2013-05-19 04:19:01 +00:00
17> q().
2013-05-19 04:27:44 +00:00
```
2013-05-19 04:19:01 +00:00
#### Note:
2013-05-19 04:27:44 +00:00
The code below creates a new database with **80GB** MapSize, **avoids fsync** after each commit (for an "ACI" but not "D" database we trade durability for speed) and uses the experimental **MDB_FIXEDMAP** .
2013-05-19 04:19:01 +00:00
2013-05-19 04:27:44 +00:00
```
2013-05-19 04:19:01 +00:00
{ok, Handle} = emdb:open("/tmp/emdb2", 85899345920, ?MDB_NOSYNC bor ?MDB_FIXEDMAP).
2013-05-19 04:27:44 +00:00
```
2012-09-30 17:42:44 +00:00
2013-05-19 04:19:01 +00:00
Performance
-----------
2013-05-19 04:27:44 +00:00
See the [microbench ](http://highlandsun.com/hyc/mdb/microbench/ ) against:
2013-05-19 04:19:01 +00:00
* Google's LevelDB (which is slower and can stall unlike Basho's fork of LevelDB)
* SQLite3
2012-09-30 17:42:44 +00:00
* Kyoto TreeDB
2013-05-19 04:19:01 +00:00
* BerkeleyDB 5.x
2012-09-30 17:42:44 +00:00
2013-05-19 04:27:44 +00:00
MDB performs mmap's the database, so unless your dataset is < 2 ^ 32 bytes you ' ll
need to run on a 64-bit arch system.
2012-09-30 17:42:44 +00:00
2013-05-19 04:19:01 +00:00
Supported Operating Systems
--------------
2012-09-30 17:42:44 +00:00
2013-05-19 04:27:44 +00:00
Should work on:
2012-09-30 17:42:44 +00:00
* Linux
* OSX
* FreeBSD
* Windows
2013-05-19 04:19:01 +00:00
TODO
----
2012-09-30 17:42:44 +00:00
2013-05-19 04:19:01 +00:00
* Fold over keys and/or values
* Unit tests
* PropEr testing
2012-09-30 17:42:44 +00:00
* Bulk "writing"
2013-05-19 04:19:01 +00:00
* basho_bench driver
* EQC, PULSE testing
* Key expirey
2013-05-19 04:27:44 +00:00
* renaming
* emdb -> lmdb
* emdb.c -> lmdb_nif.c
* improve stats
* txn API
* cursor API
* config
* use async_nif affinity
* riak_kv backend
* use dups
* 2i
* aae alternative
2013-05-19 04:19:01 +00:00
Status
2012-09-30 17:42:44 +00:00
------
2012-09-30 17:33:43 +00:00
2013-05-19 04:27:44 +00:00
Work in progress, not production quality and not supported by Basho Technologies.
2013-05-19 04:19:01 +00:00
LICENSE
-------
EMDB is Copyright (C) 2012-2013 by Aleph Archives and Basho Technologies, Inc., and released under the [OpenLDAP ](http://www.OpenLDAP.org/license.html ) License.