Skip to content
ppad-techPublic

About

Minimal Haskell bindings to LMDB.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

20 Commits

Folders and files

Repository files navigation

ppad-lmdb

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.

Usage

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

Performance

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)

Documentation

Haddocks (API documentation, etc.) are hosted at docs.ppad.tech/lmdb.

Development

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.

About

Minimal Haskell bindings to LMDB.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages