PMEMKV(7)
πΈ NAME πΈ
okay so bestie, pmemkv is literally a Key/Value Datastore for Persistent Memory. That's it, that's the name section. And btw, you're reading the PMEMKV Programmer's Manual β it's PMEMKV(7), section 7, very demure, very mindful. π«Ά
β¨ DESCRIPTION β¨
pmemkv is a key-value datastore framework optimized for persistent memory. It ships a native C API and C++ headers. Support for other languages? That's down in the BINDINGS section, keep scrolling bestie. π
It has multiple storage engines, and each one is optimized for a different use case. They differ in implementation and capabilities:
- persistence β this is a trade-off between data preservation and performance; persistent engines retain their content and are power fail/crash safe, but they are slower; volatile engines are faster, but keep their content only until the database is closed (or the application crashes; power fail occurs) π
- concurrency β engines provide a varying degree of write scalability in multi-threaded workloads. Concurrent engines support non-blocking retrievals and, on average, highly scalable updates. For details see the description of individual engines. π₯
- keys' ordering β "sorted" engines support querying above/below the given key. Most sorted engines also support passing a custom comparator object (see
libpmemkv_config(3)). By default, pmemkv stores elements in binary order (comparison is done using a function equivalent tostd::string::compare).
Persistent engines usually use libpmemobj++ and PMDK to access NVDIMMs. They can work with files on DAX filesystem (fsdax) or DAX device. π
π ENGINES π
Here's the lineup, no cap:
cmapβ Concurrent hash map β Persistent: Yes Β· Concurrent: Yes Β· Sorted: Novcmapβ Volatile concurrent hash map β Persistent: No Β· Concurrent: Yes Β· Sorted: Novsmapβ Volatile sorted hash map β Persistent: No Β· Concurrent: No Β· Sorted: Yesblackholeβ Accepts everything, returns nothing β Persistent: No Β· Concurrent: Yes Β· Sorted: No
The most mature and recommended engine to use for persistent use-cases is cmap. It provides good performance results and stability. It's giving main character energy. β¨
Each engine can be manually turned on and off at build time, using CMake options. All engines listed here are enabled and ready to use. slay.
To configure an engine, pmemkv_config is used (libpmemkv_config(3)). Below is a list of engines along with config parameters they expect. Each parameter has a corresponding function (pmemkv_config_put_path, pmemkv_config_put_comparator, etc.), which guarantees type safety. For example to insert path parameter to the config, user should call pmemkv_config_put_path(). For some use cases, like creating config from parsed input, it may be more convenient to insert parameters by their type instead of name. Each parameter has a certain type and may be inserted to a config using appropriate function (pmemkv_config_put_string, pmemkv_config_put_int64, etc.). For example, to insert a parameter of type string, pmemkv_config_put_string function may be used. Those two ways of inserting parameters into config may be used interchangeably. π
For description of pmemkv core API see libpmemkv(3).
π cmap
A persistent concurrent engine, backed by a hashmap that allows calling get, put, and remove concurrently from multiple threads and ensures good scalability. Rest of the methods (e.g. range query methods) are not thread-safe and should not be called from more than one thread. Data stored using this engine is persistent and guaranteed to be consistent in case of any kind of interruption (crash / power loss / etc).
Internally this engine uses persistent concurrent hashmap and persistent string from libpmemobj-cpp library (for details see <https://github.com/pmem/libpmemobj-cpp>). Persistent string is used as a type of a key and a value. Engine's functions should not be called within libpmemobj transactions (improper call by user will result thrown exception). β οΈ not me warning you twice
This engine requires the following config parameters (see libpmemkv_config(3) for details how to set them):
pathβ Path to a database file or to a poolset file (seepoolset(5)for details). Note that when using poolset file,sizeshould be0. It's used to open or create pool (layout"pmemkv").- type:
string
- type:
create_if_missingβ If1, pmemkv tries to open the pool and if that doesn't succeed, it creates it. If0, pmemkv will rely oncreate_or_error_if_existsflag setting. If bothcreate_*flags will be false - pmemkv will open the pool (unless the path does not exist - then it'll fail).- type:
uint64_t - default value:
0
- type:
create_or_error_if_existsβ If1, pmemkv creates the file (but it will fail if path exists). If0, pmemkv will rely oncreate_if_missingflag setting. If bothcreate_*flags will be false - pmemkv will open the pool (unless the path does not exist - then it'll fail).- type:
uint64_t - default value:
0
- type:
sizeβ Only needed if any of the above flags is1. It specifies size of the database [in bytes] to create.- type:
uint64_t - min value:
8388608(8MB)
- type:
oidβ Pointer to oid (for details seelibpmemobj(7)) which points to engine data. Ifoidis null, engine will allocate new data, otherwise it will use existing one.- type:
object
- type:
The following table shows four possible combinations of parameters (where - means "cannot be set"):
path: set Β·create_if_missing:0Β·create_or_error_if_exists:0Β·size: N/A Β·oid:-path: set Β·create_if_missing:1Β·create_or_error_if_exists:-Β·size: set Β·oid:-path: set Β·create_if_missing:-Β·create_or_error_if_exists:1Β·size: set Β·oid:-path:-Β·create_if_missing: N/A Β·create_or_error_if_exists: N/A Β·size: N/A Β·oid: set
- ad 1: If none of the flags are set (default flags' value is false), pmemkv will only try to open the file and it fails if the path does not exist. Size is ignored.
- ad 2: If
create_if_missingflag is set, pmemkv will try to open the file (based on path) and if it doesn't succeed, pmemkv tries to create the file. Flagcreate_or_error_if_existscan't be set (or it should be set to0). - ad 3: If
create_or_error_if_existsflag is set, pmemkv will try to create the file (and fails if it exists). Flagcreate_if_missingcan't be set (or it should be set to0). - ad 4: If
oidis set, path should not be set. Both flags and size are ignored.
A database file or a poolset file can also be created using pmempool utility (see pmempool-create(1)). When using pmempool create, "pmemkv" should be passed as layout for cmap engine and "pmemkv_<engine-name>" for other engines (e.g. "pmemkv_stree" for stree engine). Only PMEMOBJ pools are supported. π«Ά
π¦ vcmap
A volatile concurrent engine, backed by memkind. Data written using this engine is lost after database is closed. π
This engine is built on top of tbb::concurrent_hash_map data structure and uses PMEM C++ allocator to allocate memory. std::basic_string is used as a type of a key and a value. Memkind and TBB packages are required.
This engine requires the following config parameters (see libpmemkv_config(3) for details how to set them):
pathβ Path to an existing directory- type:
string
- type:
sizeβ Specifies size of the database [in bytes]- type:
uint64_t - min value:
16777216(16MB) (valueMEMKIND_PMEM_MIN_SIZEis specified inmemkind.h)
- type:
π§ vsmap
A volatile single-threaded sorted engine, backed by memkind. Data written using this engine is lost after database is closed. (same heartbreak, different engine)
This engine is built on top of std::map and uses PMEM C++ allocator to allocate memory. std::basic_string is used as a type of a key and a value. Memkind package is required.
This engine requires the following config parameters (see libpmemkv_config(3) for details how to set them):
pathβ Path to an existing directory- type:
string
- type:
sizeβ Specifies size of the database [in bytes]- type:
uint64_t - min value:
16777216(16MB) (valueMEMKIND_PMEM_MIN_SIZEis specified inmemkind.h)
- type:
comparatorβ (optional) Specified comparator used by the engine- type:
object
- type:
π blackhole
A volatile engine that accepts an unlimited amount of data, but never returns anything. Internally, blackhole does not use a persistent pool or any durable structure. The intended use of this engine is to profile and tune high-level bindings, and similar cases when persistence should be intentionally skipped. No additional packages are required. No supported configuration parameters. it's literally the void, it ate and left no crumbs π³οΈβ¨
π§ͺ Experimental engines
There are also more engines in various states of development, for details see <https://github.com/pmem/pmemkv/blob/master/doc/ENGINES-experimental.md>. Some of them (radix, tree3, stree and csmap) requires the config parameters like cmap and similarly to cmap should not be used within libpmemobj transaction(s). β οΈ
π BINDINGS π
Bindings for other languages are available on GitHub. Currently they support only subset of native API. (yes, subset, read it again bestie)
Existing bindings:
- Java - for details see <https://github.com/pmem/pmemkv-java>
- Node.js - for details see <https://github.com/pmem/pmemkv-nodejs>
- Python - for details see <https://github.com/pmem/pmemkv-python>
- Ruby - for details see <https://github.com/pmem/pmemkv-ruby>
π SEE ALSO π
libpmemkv(3), libpmemkv_config(3), libpmemkv_iterator(3), pmempool(1), libpmemobj(7) and <https://pmem.io>
okay that's the whole page bestie, go forth and persist π
and for the sign-off: this lil masterpiece is PMEMKV β pmemkv version 1.5.0, dated 2022-03-09, and it lives on the PMEMKV(7) page. periodt. π πΈπ¦
π¦ where this page comes from
- ubuntu jammy: libpmemkv-dev 1.5.0-4build1 Β· BSD-3
- π the page's license: BSD-3-Clause
- Copyright 2019-2022, Intel Corporation
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms