PMEMKV_CONFIG(3)
π PMEMKV_CONFIG β like, the whole vibe π
Welcome to the pmemkv_config manual page, bestie!! This is part of the PMEMKV Programmer's Manual (yes that's the manual name, it's giving β¨officialβ¨) and it's literally the Configuration API for libpmemkv. Grab a snack, we're doing this. π
πΈ NAME πΈ
pmemkv_config β the Configuration API for libpmemkv, aka the lil clipboard where you write down all your settings before you hand them to pmemkv. π
β¨ SYNOPSIS β¨
okay so here's the whole lineup, no cap:
#include <libpmemkv.h>
pmemkv_config *pmemkv_config_new(void);
void pmemkv_config_delete(pmemkv_config *config);
int pmemkv_config_put_size(pmemkv_config *config, uint64_t value);
int pmemkv_config_put_path(pmemkv_config *config, const char *value);
int **deprecated** pmemkv_config_put_force_create(pmemkv_config *config,
bool value);
int pmemkv_config_put_create_or_error_if_exists(pmemkv_config *config, bool value);
int pmemkv_config_put_create_if_missing(pmemkv_config *config, bool value)
int pmemkv_config_put_comparator(pmemkv_config *config, pmemkv_comparator *comparator);
int pmemkv_config_put_oid(pmemkv_config *config, PMEMoid *oid);
int pmemkv_config_put_data(pmemkv_config *config, const char *key, const void *value,
size_t value_size);
int pmemkv_config_put_object(pmemkv_config *config, const char *key, void *value,
void (*deleter)(void *));
int pmemkv_config_put_object_cb(pmemkv_config *config, const char *key, void *value,
void *(*getter)(void *), void (*deleter)(void *));
int pmemkv_config_put_uint64(pmemkv_config *config, const char *key, uint64_t value);
int pmemkv_config_put_int64(pmemkv_config *config, const char *key, int64_t value);
int pmemkv_config_put_string(pmemkv_config *config, const char *key, const char *value);
int pmemkv_config_get_data(pmemkv_config *config, const char *key, const void **value,
size_t *value_size);
int pmemkv_config_get_object(pmemkv_config *config, const char *key, void **value);
int pmemkv_config_get_uint64(pmemkv_config *config, const char *key, uint64_t *value);
int pmemkv_config_get_int64(pmemkv_config *config, const char *key, int64_t *value);
int pmemkv_config_get_string(pmemkv_config *config, const char *key, const char **value);
pmemkv_comparator *pmemkv_comparator_new(pmemkv_compare_function *fn, const char *name,
void *arg);
void pmemkv_comparator_delete(pmemkv_comparator *comparator);
π«Ά quick heads up: that**deprecated**onpmemkv_config_put_force_create? Yeah, it's deprecated, we're gonna talk about it later, don't @ me.
For the general deets on pmemkv and all the engines you can pick from, go read libpmemkv(7). And for the lowdown on the pmemkv core API, that's libpmemkv(3). iykyk. π
part 2 coming right up, don't go anywhere π
β¨ DESCRIPTION β¨
okay so bestie, listen π β a pmemkv database gets configured through a pmemkv_config structure. Think of it like a little purse π where you stash your settings: it stores mappings of keys (those are null-terminated strings, no cap) to values.
and a value can be any of these cuties:
uint64_tint64_t- c-style string
- binary data
- pointer to an object (with an accompanying deleter function) β yes she brings her own cleanup crew π
It also delivers methods to store and read configuration items provided by a user. Once the config object is all set (every required parameter in place, nothing missing π), it can be passed to the pmemkv_open() method.
Which options a pmemkv database actually needs? That's specific to the engine, bestie β every engine has documented all its supported config parameters (please see libpmemkv(7) for the details π).
π± pmemkv_config_new
pmemkv_config *pmemkv_config_new(void);
Creates an instance of configuration for a pmemkv database. On failure, NULL is returned. so if you get NULL, that's not a vibe check you passed π
ποΈ pmemkv_config_delete
void pmemkv_config_delete(pmemkv_config *config);
Deletes a pmemkv_config. Should be called ONLY for configs which were not passed to pmemkv_open (because that function moves ownership of the config over to the database β she's not yours anymore, periodt π
).
π pmemkv_config_put_size
int pmemkv_config_put_size(pmemkv_config *config, uint64_t value);
Puts a value to a config at key size β it's required when creating a new database pool. This function provides type safety for the size parameter. slay π₯
π£οΈ pmemkv_config_put_path
int pmemkv_config_put_path(pmemkv_config *config, const char *value);
Puts a value to a config at key path. It's a path to a database file or to a poolset file (see poolset(5) for details), to open or create.
heads up bestie β οΈ note that when using a poolset file,sizeshould be0.
This function provides type safety for the path parameter.
π°οΈ pmemkv_config_put_force_create
int pmemkv_config_put_force_create(pmemkv_config *config, bool value);
It is deprecated and kept for compatibility only π¬ It's an alias for pmemkv_config_put_create_or_error_if_exists β use that one instead, fr fr.
π pmemkv_config_put_create_or_error_if_exists
int pmemkv_config_put_create_or_error_if_exists(pmemkv_config *config, bool value);
Puts a value to a config at key create_or_error_if_exists. This flag is mutually exclusive with create_if_missing. It works only with engines supporting this flag, and it means:
- If
true: pmemkv creates the pool, unless it exists β then it fails π - If
false: pmemkv</p> opens the pool, unless the path does not exist β then it fails π
False by default.
π£ pmemkv_config_put_create_if_missing
int pmemkv_config_put_create_if_missing(pmemkv_config *config, bool value);
Puts a value to a config at key create_if_missing. This flag is mutually exclusive with create_or_error_if_exists. It works only with engines supporting this flag, and it means:
- If
true: pmemkv tries to open the pool, and if that doesn't succeed it means there's (most likely) no pool to use β so it tries to create it π«Ά - If
false: pmemkv opens the pool, unless the path does not exist β then it fails π
False by default.
π§ pmemkv_config_put_comparator
int pmemkv_config_put_comparator(pmemkv_config *config, pmemkv_comparator *comparator);
Puts a comparator object into a config. To create an instance of a pmemkv_comparator object, the pmemkv_comparator_new() function should be used. iykyk β¨
π pmemkv_config_put_oid
int pmemkv_config_put_oid(pmemkv_config *config, PMEMoid *oid);
Puts a PMEMoid object into a config (for details see libpmemkv(7)).
π’ pmemkv_config_put_uint64
int pmemkv_config_put_uint64(pmemkv_config *config, const char *key, uint64_t value);
Puts the uint64_t value to pmemkv_config at key key.
π’ pmemkv_config_put_int64
int pmemkv_config_put_int64(pmemkv_config *config, const char *key, int64_t value);
Puts the int64_t value to pmemkv_config at key key.
π pmemkv_config_put_string
int pmemkv_config_put_string(pmemkv_config *config, const char *key, const char *value);
Puts a null-terminated string into pmemkv_config. The string is copied to the config β she's keeping a lil' copy for herself, obsessed π
𧬠pmemkv_config_put_data
int pmemkv_config_put_data(pmemkv_config *config, const char *key, const void *value, size_t value_size);
Puts a copy of the binary data pointed to by value into pmemkv_config. value_size specifies the size of the data.
π¦ pmemkv_config_put_object
int pmemkv_config_put_object(pmemkv_config *config, const char *key, void *value, void (*deleter)(void *));
Puts value into pmemkv_config. value can point to an arbitrary object. The deleter parameter specifies the function which will be called for value when the config is destroyed (using pmemkv_config_delete). so like, she'll clean up after herself when the time comes π§Ήβ¨
πͺ pmemkv_config_put_object_cb
int pmemkv_config_put_object_cb(pmemkv_config *config, const char *key, void *value, void *(*getter)(void *), void (*deleter)(void *));
Extended version of pmemkv_config_put_object. It accepts one additional argument β a getter callback. This callback interprets the custom object (value) and returns a pointer which is expected by pmemkv.
Calling pmemkv_config_put_object_cb with getter implemented as:
void *getter(void *arg) { return arg; }
is equivalent to calling pmemkv_config_put_object. same energy, different font π
π pmemkv_config_get_uint64
int pmemkv_config_get_uint64(pmemkv_config *config, const char *key, uint64_t *value);
Gets the value of a config item with key key. The value is copied to the variable pointed to by value.
π pmemkv_config_get_int64
int pmemkv_config_get_int64(pmemkv_config *config, const char *key, int64_t *value);
Gets the value of a config item with key key. The value is copied to the variable pointed to by value.
π pmemkv_config_get_string
int pmemkv_config_get_string(pmemkv_config *config, const char *key, const char **value);
Gets a pointer to a null-terminated string. The string is not copied π«π After a successful call, value points to the string stored in pmemkv_config.
𧬠pmemkv_config_get_data
int pmemkv_config_get_data(pmemkv_config *config, const char *key, const void **value, size_t *value_size);
Gets a pointer to binary data. The data is not copied. After a successful call, *value points to the data stored in pmemkv_config and value_size holds the size of the data.
π¦ pmemkv_config_get_object
int pmemkv_config_get_object(pmemkv_config *config, const char *key, const void **value);
Gets a pointer to an object. After a successful call, *value points to the object.
π¨ the type-matching rule (do NOT skip this bestie)
Config items stored in pmemkv_config which were put using a specific function can be obtained only using the corresponding pmemkv_config_get_ function β for example, config items put using pmemkv_config_put_object can only be obtained using pmemkv_config_get_object. no mix-and-match, she said what she said π
The exception from this rule are the functions for uint64 and int64. If a value put by pmemkv_config_put_int64 is in uint64_t range, it can be obtained using pmemkv_config_get_uint64 β and vice versa. see, they're flexible like that π¦
π§ pmemkv_comparator_new
pmemkv_comparator *pmemkv_comparator_new(pmemkv_compare_function *fn, const char *name, void *arg);
Creates an instance of a comparator object. Accepts a comparison function fn, name and arg. In case of persistent engines, name is stored within the engine. An attempt to open a database which was created with a different comparator of a different name will fail with PMEMKV_STATUS_COMPARATOR_MISMATCH π arg is saved in the comparator and passed to the comparison function on each invocation.
Neither fn nor name can be NULL. π«
fn should perform a three-way comparison. Return values:
- a negative value if the first key is less than the second one
- zero if both keys are the same
- a positive value if the first key is greater than the second one
The comparison function should be thread safe β it can be called from multiple threads. no chaotic energy allowed, she multi-tasks responsibly π§
On failure, NULL is returned.
ποΈ pmemkv_comparator_delete
void pmemkv_comparator_delete(pmemkv_comparator *comparator);
Removes the comparator object. Should be called ONLY for comparators which were not put to config (because the config takes ownership of the comparator β again, she's not yours anymore π).
To set a comparator for the database use pmemkv_config_put_object:
pmemkv_comparator *cmp = pmemkv_comparator_new(&compare_fn, "my_comparator", NULL);
pmemkv_config_put_object(cfg, "comparator", cmp, (void (*)(void *)) & pmemkv_comparator_delete);
π ERRORS π
Every function, except for pmemkv_config_new() and pmemkv_config_delete(), returns a status. Possible return values are:
PMEMKV_STATUS_OKβ no error, we ate and left no crumbs π₯PMEMKV_STATUS_UNKNOWN_ERRORβ unknown error πPMEMKV_STATUS_NOT_FOUNDβ record (or config item) not found π΅οΈPMEMKV_STATUS_CONFIG_PARSING_ERRORβ parsing data to config failed πPMEMKV_STATUS_CONFIG_TYPE_ERRORβ config item has a different type than expected π«
π EXAMPLE π
These cuties are straight out of the examples/pmemkv_config_c directory, so you know they're legit. π
πΈ BASIC EXAMPLE πΈ
This one's the classic β using the basic config functions to set parameters by what they do, like pmemkv_config_put_path() or pmemkv_config_put_size(). It's giving "I just want my config set up and I don't need it to be fancy." π
#include <assert.h>
#include <libpmemkv.h>
#include <libpmemobj/pool_base.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ASSERT(expr) \
do { \
if (!(expr)) \
puts(pmemkv_errormsg()); \
assert(expr); \
} while (0)
static const uint64_t SIZE = 1024UL * 1024UL * 1024UL;
int key_length_compare(const char *key1, size_t keybytes1, const char *key2,
size_t keybytes2, void *arg)
{
if (keybytes2 < keybytes1)
return -1;
else if (keybytes2 > keybytes1)
return 1;
else
return 0;
}
int main(int argc, char *argv[])
{
if (argc < 2) {
fprintf(stderr, "Usage: %s file\n", argv[0]);
exit(1);
}
/* Create config */
pmemkv_config *config = pmemkv_config_new();
ASSERT(config != NULL);
/* Add path parameter to config. Meaning of this is dependent on chosen engine.
* E.g. if config is used with cmap engine,
* it is a path to a database file or to a poolset file. However for
* vcmap it is a path to an existing directory */
int status = pmemkv_config_put_path(config, argv[1]);
ASSERT(status == PMEMKV_STATUS_OK);
/* Specifies size of the database */
status = pmemkv_config_put_size(config, SIZE);
ASSERT(status == PMEMKV_STATUS_OK);
/* Specifies value of create_if_missing flag.
* Alternatively, another flag - 'create_or_error_if_exists' can be set using:
* `pmemkv_config_put_create_or_error_if_exists`
* For differences between the two, see manpage libpmemkv(7). */
status = pmemkv_config_put_create_if_missing(config, true);
ASSERT(status == PMEMKV_STATUS_OK);
/* Specifies comparator used by the engine */
pmemkv_comparator *cmp =
pmemkv_comparator_new(&key_length_compare, "key_length_compare", NULL);
ASSERT(cmp != NULL);
status = pmemkv_config_put_comparator(config, cmp);
ASSERT(status == PMEMKV_STATUS_OK);
/* Adds pointer to oid (for details see libpmemkv(7)) to the config */
PMEMoid oid;
status = pmemkv_config_put_oid(config, &oid);
ASSERT(status == PMEMKV_STATUS_OK);
pmemkv_config_delete(config);
return 0;
}
π¦ TYPE BASED CONFIGURATION EXAMPLE π¦
And this one is the glow-up β setting and getting data based on the actual data type, like pmemkv_config_put_int64() or pmemkv_config_put_object(). Lowkey obsessed with how tidy this is. β¨
#include <assert.h>
#include <libpmemkv.h>
#include <libpmemkv_json_config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ASSERT(expr) \
do { \
if (!(expr)) \
puts(pmemkv_errormsg()); \
assert(expr); \
} while (0)
/* deleter for int pointer */
void free_int_ptr(void *ptr)
{
free(ptr);
}
int main()
{
pmemkv_config *config = pmemkv_config_new();
ASSERT(config != NULL);
/* Put int64_t value */
int status = pmemkv_config_put_int64(config, "size", 1073741824);
ASSERT(status == PMEMKV_STATUS_OK);
char buffer[] = "ABC";
/* Put binary data stored in buffer */
status = pmemkv_config_put_data(config, "binary", buffer, 3);
ASSERT(status == PMEMKV_STATUS_OK);
const void *data;
size_t data_size;
/* Get pointer to binary data stored in config */
status = pmemkv_config_get_data(config, "binary", &data, &data_size);
ASSERT(status == PMEMKV_STATUS_OK);
ASSERT(data_size == 3);
ASSERT(((const char *)data)[0] == 'A');
int *int_ptr = malloc(sizeof(int));
ASSERT(int_ptr != NULL);
*int_ptr = 10;
/* Put pointer to dynamically allocated object, free_int_ptr is called on
* pmemkv_config_delete */
status = pmemkv_config_put_object(config, "int_ptr", int_ptr, &free_int_ptr);
ASSERT(status == PMEMKV_STATUS_OK);
int *get_int_ptr;
/* Get pointer to object stored in config */
status = pmemkv_config_get_object(config, "int_ptr", (void **)&get_int_ptr);
ASSERT(status == PMEMKV_STATUS_OK);
ASSERT(*get_int_ptr == 10);
pmemkv_config_delete(config);
pmemkv_config *config_from_json = pmemkv_config_new();
ASSERT(config_from_json != NULL);
/* Parse JSON and put all items found into config_from_json */
status = pmemkv_config_from_json(config_from_json, "{\"path\":\"/dev/shm\",\
\"size\":1073741824,\
\"subconfig\":{\
\"size\":1073741824\
}\
}");
ASSERT(status == PMEMKV_STATUS_OK);
const char *path;
status = pmemkv_config_get_string(config_from_json, "path", &path);
ASSERT(status == PMEMKV_STATUS_OK);
ASSERT(strcmp(path, "/dev/shm") == 0);
pmemkv_config *subconfig;
/* Get pointer to nested configuration "subconfig" */
status = pmemkv_config_get_object(config_from_json, "subconfig",
(void **)&subconfig);
ASSERT(status == PMEMKV_STATUS_OK);
size_t sub_size;
status = pmemkv_config_get_uint64(subconfig, "size", &sub_size);
ASSERT(status == PMEMKV_STATUS_OK);
ASSERT(sub_size == 1073741824);
pmemkv_config_delete(config_from_json);
return 0;
}
π SEE ALSO π
Go read these next, bestie β they're the friend group of this page, fr fr:
And that's a wrap on PMEMKV_CONFIG(3)! π«Ά This one shipped as part of pmemkv version 1.5.0, dated 2022-03-09. Thanks for reading all three parts, you're literally the main character. πβ¨π
π¦ 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