Bindings to LMDB (Lightning Memory-Mapped Database), which is an embedded ACID key-value store.
This library exposes a minimal subset of the LMDB API, mainly supporting LMDB environments, transactions, basic row operations (get, put, del), and range scans.
A sample GHCi session:
> :set -XOverloadedStrings
> import qualified Database.LMDB as L
>
> -- envMapSize caps the on-disk size; the default (10 MiB) is
> -- intentionally small. writes past it fail with LMDBMapFull,
> -- so set it to something appropriate for your workload
> let flags = L.defaultEnvFlags
> { L.envNoSubdir = True
> , L.envMapSize = 256 * 1024 * 1024 -- 256 MiB
> }
>
> env <- L.open "/tmp/mydb" flags
>
> -- open (here, creating) the default database once, and reuse the
> -- handle for the life of the env
> dbi <- L.openDbi env Nothing True
>
> -- populate it in a write transaction
> L.withWriteTxn env $ \txn -> do
> L.put txn dbi "apple" "red"
> L.put txn dbi "banana" "yellow"
> L.put txn dbi "cherry" "red"
>
> -- point lookup
> L.withReadTxn env $ \txn -> L.get txn dbi "banana"
Just "yellow"
>
> -- range scan; every entry with key >= "b"
> L.withReadTxn env $ \txn ->
> L.withCursor txn dbi $ \cur -> do
> let go acc Nothing = pure (reverse acc)
> go acc (Just kv) = L.cursorNext cur >>= go (kv : acc)
> L.cursorSeek cur "b" >>= go []
[("banana","yellow"),("cherry","red")]
>
> L.close env
Current benchmark figures on an M4 Silicon MacBook Air look like (use
cabal bench to run the benchmark suite):
benchmarking put/1k overwrites (one txn)
time 310.2 μs (307.7 μs .. 313.2 μs)
1.000 R² (0.999 R² .. 1.000 R²)
mean 309.5 μs (308.3 μs .. 311.2 μs)
std dev 4.826 μs (3.832 μs .. 6.495 μs)
benchmarking put/10k overwrites (one txn)
time 1.558 ms (1.552 ms .. 1.565 ms)
1.000 R² (1.000 R² .. 1.000 R²)
mean 1.559 ms (1.555 ms .. 1.565 ms)
std dev 15.19 μs (10.05 μs .. 26.05 μs)
benchmarking get/1k random hits
time 191.4 μs (187.7 μs .. 197.4 μs)
0.996 R² (0.992 R² .. 0.999 R²)
mean 192.3 μs (190.2 μs .. 195.4 μs)
std dev 8.446 μs (5.533 μs .. 14.14 μs)
variance introduced by outliers: 43% (moderately inflated)
benchmarking get/10k random hits
time 1.882 ms (1.863 ms .. 1.902 ms)
0.999 R² (0.999 R² .. 0.999 R²)
mean 1.891 ms (1.878 ms .. 1.905 ms)
std dev 46.24 μs (39.46 μs .. 60.16 μs)
variance introduced by outliers: 11% (moderately inflated)
benchmarking cursor/scan 10k entries
time 302.7 μs (300.2 μs .. 305.1 μs)
1.000 R² (0.999 R² .. 1.000 R²)
mean 304.3 μs (302.6 μs .. 306.1 μs)
std dev 5.916 μs (5.067 μs .. 7.345 μs)
variance introduced by outliers: 12% (moderately inflated)
Haddocks (API documentation, etc.) are hosted at docs.ppad.tech/lmdb.
You'll require Nix with flake support enabled. Enter a development shell with:
$ nix develop
Then do e.g.:
$ cabal repl ppad-lmdb
to get a REPL for the main library.