README.md (3877B)
1 # ppad-lmdb 2 3 [](https://hackage.haskell.org/package/ppad-lmdb) 4  5 [](https://docs.ppad.tech/lmdb) 6 7 Bindings to [LMDB][lmdb] (Lightning Memory-Mapped Database), which is an 8 embedded ACID key-value store. 9 10 This library exposes a minimal subset of the LMDB API, mainly supporting 11 LMDB environments, transactions, basic row operations (get, put, del), 12 and range scans. 13 14 ## Usage 15 16 A sample GHCi session: 17 18 ``` 19 > :set -XOverloadedStrings 20 > import qualified Database.LMDB as L 21 > 22 > -- envMapSize caps the on-disk size; the default (10 MiB) is 23 > -- intentionally small. writes past it fail with LMDBMapFull, 24 > -- so set it to something appropriate for your workload 25 > let flags = L.defaultEnvFlags 26 > { L.envNoSubdir = True 27 > , L.envMapSize = 256 * 1024 * 1024 -- 256 MiB 28 > } 29 > 30 > -- populate the env in a write transaction 31 > L.withEnv "/tmp/mydb" flags $ \env -> 32 > L.withWriteTxn env $ \txn -> do 33 > dbi <- L.openDbi txn Nothing True 34 > L.put txn dbi "apple" "red" 35 > L.put txn dbi "banana" "yellow" 36 > L.put txn dbi "cherry" "red" 37 > 38 > -- point lookup 39 > L.withEnv "/tmp/mydb" flags $ \env -> 40 > L.withReadTxn env $ \txn -> do 41 > dbi <- L.openDbi txn Nothing False 42 > L.get txn dbi "banana" 43 Just "yellow" 44 > 45 > -- range scan; every entry with key >= "b" 46 > L.withEnv "/tmp/mydb" flags $ \env -> 47 > L.withReadTxn env $ \txn -> do 48 > dbi <- L.openDbi txn Nothing False 49 > L.withCursor txn dbi $ \cur -> do 50 > let go acc Nothing = pure (reverse acc) 51 > go acc (Just kv) = L.cursorNext cur >>= go (kv : acc) 52 > L.cursorSeek cur "b" >>= go [] 53 [("banana","yellow"),("cherry","red")] 54 ``` 55 56 ## Performance 57 58 Current benchmark figures on an M4 Silicon MacBook Air look like (use 59 `cabal bench` to run the benchmark suite): 60 61 ``` 62 benchmarking put/1k inserts (one txn) 63 time 559.5 μs (557.5 μs .. 562.0 μs) 64 1.000 R² (0.999 R² .. 1.000 R²) 65 mean 561.8 μs (559.6 μs .. 567.0 μs) 66 std dev 11.34 μs (5.445 μs .. 21.32 μs) 67 68 benchmarking put/10k inserts (one txn) 69 time 4.026 ms (4.016 ms .. 4.037 ms) 70 1.000 R² (1.000 R² .. 1.000 R²) 71 mean 4.013 ms (4.005 ms .. 4.022 ms) 72 std dev 26.80 μs (22.08 μs .. 36.75 μs) 73 74 benchmarking get/1k random hits 75 time 307.1 μs (306.3 μs .. 308.1 μs) 76 1.000 R² (1.000 R² .. 1.000 R²) 77 mean 308.0 μs (307.3 μs .. 309.4 μs) 78 std dev 3.368 μs (1.893 μs .. 5.357 μs) 79 80 benchmarking get/10k random hits 81 time 2.882 ms (2.872 ms .. 2.893 ms) 82 1.000 R² (1.000 R² .. 1.000 R²) 83 mean 2.884 ms (2.879 ms .. 2.889 ms) 84 std dev 16.25 μs (13.40 μs .. 21.54 μs) 85 86 benchmarking cursor/scan 10k entries 87 time 1.249 ms (1.245 ms .. 1.258 ms) 88 0.999 R² (0.996 R² .. 1.000 R²) 89 mean 1.251 ms (1.245 ms .. 1.281 ms) 90 std dev 35.00 μs (5.595 μs .. 82.99 μs) 91 ``` 92 93 ## Documentation 94 95 Haddocks (API documentation, etc.) are hosted at 96 [docs.ppad.tech/lmdb](https://docs.ppad.tech/lmdb). 97 98 ## Development 99 100 You'll require [Nix][nixos] with [flake][flake] support enabled. Enter a 101 development shell with: 102 103 ``` 104 $ nix develop 105 ``` 106 107 Then do e.g.: 108 109 ``` 110 $ cabal repl ppad-lmdb 111 ``` 112 113 to get a REPL for the main library. 114 115 [lmdb]: https://www.symas.com/lmdb 116 [nixos]: https://nixos.org/ 117 [flake]: https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html