1PMEMKV(3) PMEMKV Programmer's Manual PMEMKV(3)
2
3
4
6 pmemkv - Key/Value Datastore for Persistent Memory
7
9 #include <libpmemkv.h>
10
11 typedef int pmemkv_get_kv_callback(const char *key, size_t keybytes, const char *value,
12 size_t valuebytes, void *arg);
13 typedef void pmemkv_get_v_callback(const char *value, size_t valuebytes, void *arg);
14
15 int pmemkv_open(const char *engine, pmemkv_config *config, pmemkv_db **db);
16 void pmemkv_close(pmemkv_db *kv);
17
18 int pmemkv_count_all(pmemkv_db *db, size_t *cnt);
19 int pmemkv_count_above(pmemkv_db *db, const char *k, size_t kb, size_t *cnt);
20 int pmemkv_count_below(pmemkv_db *db, const char *k, size_t kb, size_t *cnt);
21 int pmemkv_count_between(pmemkv_db *db, const char *k1, size_t kb1, const char *k2,
22 size_t kb2, size_t *cnt);
23
24 int pmemkv_get_all(pmemkv_db *db, pmemkv_get_kv_callback *c, void *arg);
25 int pmemkv_get_above(pmemkv_db *db, const char *k, size_t kb, pmemkv_get_kv_callback *c,
26 void *arg);
27 int pmemkv_get_below(pmemkv_db *db, const char *k, size_t kb, pmemkv_get_kv_callback *c,
28 void *arg);
29 int pmemkv_get_between(pmemkv_db *db, const char *k1, size_t kb1, const char *k2,
30 size_t kb2, pmemkv_get_kv_callback *c, void *arg);
31
32 int pmemkv_exists(pmemkv_db *db, const char *k, size_t kb);
33
34 int pmemkv_get(pmemkv_db *db, const char *k, size_t kb, pmemkv_get_v_callback *c,
35 void *arg);
36 int pmemkv_get_copy(pmemkv_db *db, const char *k, size_t kb, char *buffer,
37 size_t buffer_size, size_t *value_size);
38 int pmemkv_put(pmemkv_db *db, const char *k, size_t kb, const char *v, size_t vb);
39
40 int pmemkv_remove(pmemkv_db *db, const char *k, size_t kb);
41
42 int pmemkv_defrag(pmemkv_db *db, double start_percent, double amount_percent);
43
44 const char *pmemkv_errormsg(void);
45
46 For pmemkv configuration API description see libpmemkv_config(3). For
47 pmemkv iterator API description see libpmemkv_iterator(3). For general
48 pmemkv information, engine descriptions and bindings details see libp‐
49 memkv(7).
50
52 Keys and values stored in a pmemkv database can be arbitrary binary da‐
53 ta and can contain multiple null characters. Every function which ac‐
54 cepts key expects const char *k pointer to data and its size as size_t.
55
56 Some of the functions (mainly range-query API) are not guaranteed to be
57 implemented by all engines. If an engine does not support a certain
58 function, it will return PMEMKV_STATUS_NOT_SUPPORTED.
59
60 Note: There are no explicit upper_bound/lower_bound functions. If you
61 want to obtain an element(s) above or below the selected key, you can
62 use pmemkv_get_above() or pmemkv_get_below(). See descriptions of
63 these functions for details.
64
65 int pmemkv_open(const char *engine, pmemkv_config *config, pmemkv_db
66 **db);
67 Opens the pmemkv database and stores a pointer to a pmemkv_db
68 instance in *db. The engine parameter specifies the engine name
69 (see libpmemkv(7) for the list of available engines). The con‐
70 fig parameter specifies configuration (see libpmemkv_config(3)
71 for details). Pmemkv takes ownership of the config parameter -
72 this means that pmemkv_config_delete() must NOT be called after
73 open (successful or failed).
74
75 void pmemkv_close(pmemkv_db *kv);
76 Closes pmemkv database.
77
78 int pmemkv_count_all(pmemkv_db *db, size_t *cnt);
79 Stores in *cnt the number of records in db.
80
81 int pmemkv_count_above(pmemkv_db *db, const char *k, size_t kb, size_t
82 *cnt);
83 Stores in *cnt the number of records in db whose keys are
84 greater than the key k of length kb. Order of the elements is
85 specified by a comparator (see libpmemkv(7)).
86
87 int pmemkv_count_below(pmemkv_db *db, const char *k, size_t kb, size_t
88 *cnt);
89 Stores in *cnt the number of records in db whose keys are less
90 than the key k of length kb. Order of the elements is specified
91 by a comparator (see libpmemkv(7)).
92
93 int pmemkv_count_between(pmemkv_db *db, const char *k1, size_t kb1,
94 const char *k2, size_t kb2, size_t *cnt);
95 Stores in *cnt the number of records in db whose keys are
96 greater than key k1 (of length kb1) and less than key k2 (of
97 length kb2). Order of the elements is specified by a comparator
98 (see libpmemkv(7)).
99
100 int pmemkv_get_all(pmemkv_db *db, pmemkv_get_kv_callback *c, void
101 *arg);
102 Executes function c for every record stored in db. Arguments
103 passed to the function are: pointer to a key, size of the key,
104 pointer to a value, size of the value and arg specified by the
105 user. Function c can stop iteration by returning non-zero val‐
106 ue. In that case pmemkv_get_all() returns PMEMKV_STA‐
107 TUS_STOPPED_BY_CB. Returning 0 continues iteration. Order of
108 the elements is specified by a comparator (see libpmemkv(7)).
109
110 int pmemkv_get_above(pmemkv_db *db, const char *k, size_t kb,
111 pmemkv_get_kv_callback *c, void *arg);
112 Executes function c for every record stored in db whose keys are
113 greater than key k (of length kb). Arguments passed to c are:
114 pointer to a key, size of the key, pointer to a value, size of
115 the value and arg specified by the user. Function c can stop
116 iteration by returning non-zero value. In that case
117 pmemkv_get_above() returns PMEMKV_STATUS_STOPPED_BY_CB. Return‐
118 ing 0 continues iteration. Order of the elements is specified
119 by a comparator (see libpmemkv(7)).
120
121 int pmemkv_get_below(pmemkv_db *db, const char *k, size_t kb,
122 pmemkv_get_kv_callback *c, void *arg);
123 Executes function c for every record stored in db whose keys are
124 less than key k (of length kb). Arguments passed to c are:
125 pointer to a key, size of the key, pointer to a value, size of
126 the value and arg specified by the user. Function c can stop
127 iteration by returning non-zero value. In that case
128 pmemkv_get_below() returns PMEMKV_STATUS_STOPPED_BY_CB. Return‐
129 ing 0 continues iteration. Order of the elements is specified
130 by a comparator (see libpmemkv(7)).
131
132 int pmemkv_get_between(pmemkv_db *db, const char *k1, size_t kb1, const
133 char *k2, size_t kb2, pmemkv_get_kv_callback *c, void *arg);
134 Executes function c for every record stored in db whose keys are
135 greater than key k1 (of length kb1) and less than key k2 (of
136 length kb2). Arguments passed to c are: pointer to a key, size
137 of the key, pointer to a value, size of the value and arg speci‐
138 fied by the user. Function c can stop iteration by returning
139 non-zero value. In that case pmemkv_get_between() returns
140 PMEMKV_STATUS_STOPPED_BY_CB. Returning 0 continues iteration.
141 Order of the elements is specified by a comparator (see libp‐
142 memkv(7)).
143
144 int pmemkv_exists(pmemkv_db *db, const char *k, size_t kb);
145 Checks existence of record with key k of length kb. If record
146 is present PMEMKV_STATUS_OK is returned, otherwise PMEMKV_STA‐
147 TUS_NOT_FOUND is returned. Other possible return values are de‐
148 scribed in the ERRORS section.
149
150 int pmemkv_get(pmemkv_db *db, const char *k, size_t kb,
151 pmemkv_get_v_callback *c, void *arg);
152 Executes function c on record with key k (of length kb). If
153 record is present and no error occurred the function returns
154 PMEMKV_STATUS_OK. If record does not exist PMEMKV_STA‐
155 TUS_NOT_FOUND is returned. Other possible return values are de‐
156 scribed in the ERRORS section. Function c is called with the
157 following parameters: pointer to a value, size of the value and
158 arg specified by the user. Value points to the location where
159 data is actually stored (no copy occurs). This function is
160 guaranteed to be implemented by all engines.
161
162 int pmemkv_get_copy(pmemkv_db *db, const char *k, size_t kb, char *buf‐
163 fer, size_t buffer_size, size_t *value_size);
164 Copies value of record with key k of length kb to user provided
165 buffer. buffer points to the value buffer, buffer_size speci‐
166 fies its size and *value_size is filled in by this function. If
167 the value doesn’t fit in the provided buffer then this function
168 returns PMEMKV_STATUS_UNKNOWN_ERROR. Otherwise, in absence of
169 any errors, PMEMKV_STATUS_OK is returned. Other possible return
170 values are described in the ERRORS section. This function is
171 guaranteed to be implemented by all engines.
172
173 int pmemkv_put(pmemkv_db *db, const char *k, size_t kb, const char *v,
174 size_t vb);
175 Inserts a key-value pair into pmemkv database. kb is the length
176 of key k and vb is the length of value v. When this function
177 returns, caller is free to reuse both buffers. This function is
178 guaranteed to be implemented by all engines.
179
180 int pmemkv_remove(pmemkv_db *db, const char *k, size_t kb);
181 Removes record with key k of length kb. This function is guar‐
182 anteed to be implemented by all engines.
183
184 int pmemkv_defrag(pmemkv_db *db, double start_percent, double
185 amount_percent);
186 Defragments approximately `amount_percent' percent of elements
187 in the database starting from `start_percent' percent of ele‐
188 ments.
189
190 const char *pmemkv_errormsg(void);
191 Returns a human readable string describing the last error.
192
193 ERRORS
194 Each function, except for pmemkv_close() and pmemkv_errormsg(), returns
195 one of the following status codes:
196
197 • PMEMKV_STATUS_OK – no error
198
199 • PMEMKV_STATUS_UNKNOWN_ERROR – unknown error
200
201 • PMEMKV_STATUS_NOT_FOUND – record not found
202
203 • PMEMKV_STATUS_NOT_SUPPORTED – function is not implemented by current
204 engine
205
206 • PMEMKV_STATUS_INVALID_ARGUMENT – argument to function has wrong value
207
208 • PMEMKV_STATUS_CONFIG_PARSING_ERROR – parsing data to config failed
209
210 • PMEMKV_STATUS_CONFIG_TYPE_ERROR – config item has different type than
211 expected
212
213 • PMEMKV_STATUS_STOPPED_BY_CB – iteration was stopped by user’s call‐
214 back
215
216 • PMEMKV_STATUS_OUT_OF_MEMORY – operation failed because there is not
217 enough memory (or space on the device)
218
219 • PMEMKV_STATUS_WRONG_ENGINE_NAME – engine name does not match any
220 available engine
221
222 • PMEMKV_STATUS_TRANSACTION_SCOPE_ERROR – an error with the scope of
223 the libpmemobj transaction
224
225 • PMEMKV_STATUS_DEFRAG_ERROR – the defragmentation process failed (pos‐
226 sibly in the middle of a run)
227
228 Status returned from a function can change in a future version of a li‐
229 brary to a more specific one. For example, if a function returns
230 PMEMKV_STATUS_UNKNOWN_ERROR, it is possible that in future versions it
231 will return PMEMKV_STATUS_INVALID_ARGUMENT. Recommended way to check
232 for an error is to compare status with PMEMKV_STATUS_OK.
233
235 The following example is taken from examples/pmemkv_basic_c directory.
236
237 Basic pmemkv usage in C:
238
239 #include <assert.h>
240 #include <libpmemkv.h>
241 #include <stdio.h>
242 #include <stdlib.h>
243 #include <string.h>
244
245 #define ASSERT(expr) \
246 do { \
247 if (!(expr)) \
248 puts(pmemkv_errormsg()); \
249 assert(expr); \
250 } while (0)
251
252 #define LOG(msg) puts(msg)
253 #define MAX_VAL_LEN 64
254
255 static const uint64_t SIZE = 1024UL * 1024UL * 1024UL;
256
257 int get_kv_callback(const char *k, size_t kb, const char *value, size_t value_bytes,
258 void *arg)
259 {
260 printf(" visited: %s\n", k);
261
262 return 0;
263 }
264
265 int main(int argc, char *argv[])
266 {
267 if (argc < 2) {
268 fprintf(stderr, "Usage: %s file\n", argv[0]);
269 exit(1);
270 }
271
272 /* See libpmemkv_config(3) for more detailed example of config creation */
273 LOG("Creating config");
274 pmemkv_config *cfg = pmemkv_config_new();
275 ASSERT(cfg != NULL);
276
277 int s = pmemkv_config_put_path(cfg, argv[1]);
278 ASSERT(s == PMEMKV_STATUS_OK);
279 s = pmemkv_config_put_size(cfg, SIZE);
280 ASSERT(s == PMEMKV_STATUS_OK);
281 s = pmemkv_config_put_create_if_missing(cfg, true);
282 ASSERT(s == PMEMKV_STATUS_OK);
283
284 /* Alternatively create_or_error_if_exists flag can be set, to fail if file exists
285 * For differences between the two flags, see manpage libpmemkv(7). */
286 /* s = pmemkv_config_put_create_or_error_if_exists(cfg, true); */
287
288 LOG("Opening pmemkv database with 'cmap' engine");
289 pmemkv_db *db = NULL;
290 s = pmemkv_open("cmap", cfg, &db);
291 ASSERT(s == PMEMKV_STATUS_OK);
292 ASSERT(db != NULL);
293
294 LOG("Putting new key");
295 const char *key1 = "key1";
296 const char *value1 = "value1";
297 s = pmemkv_put(db, key1, strlen(key1), value1, strlen(value1));
298 ASSERT(s == PMEMKV_STATUS_OK);
299
300 size_t cnt;
301 s = pmemkv_count_all(db, &cnt);
302 ASSERT(s == PMEMKV_STATUS_OK);
303 ASSERT(cnt == 1);
304
305 LOG("Reading key back");
306 char val[MAX_VAL_LEN];
307 s = pmemkv_get_copy(db, key1, strlen(key1), val, MAX_VAL_LEN, NULL);
308 ASSERT(s == PMEMKV_STATUS_OK);
309 ASSERT(!strcmp(val, "value1"));
310
311 LOG("Iterating existing keys");
312 const char *key2 = "key2";
313 const char *value2 = "value2";
314 const char *key3 = "key3";
315 const char *value3 = "value3";
316 pmemkv_put(db, key2, strlen(key2), value2, strlen(value2));
317 pmemkv_put(db, key3, strlen(key3), value3, strlen(value3));
318 pmemkv_get_all(db, &get_kv_callback, NULL);
319
320 LOG("Removing existing key");
321 s = pmemkv_remove(db, key1, strlen(key1));
322 ASSERT(s == PMEMKV_STATUS_OK);
323 ASSERT(pmemkv_exists(db, key1, strlen(key1)) == PMEMKV_STATUS_NOT_FOUND);
324
325 LOG("Defragmenting the database");
326 s = pmemkv_defrag(db, 0, 100);
327 ASSERT(s == PMEMKV_STATUS_OK);
328
329 LOG("Closing database");
330 pmemkv_close(db);
331
332 return 0;
333 }
334
335 Common usage mistake
336 Common mistake in pmemkv API usage (especially when using C++ API) is
337 to dereference pointer to the data stored in pmemkv outside of a call‐
338 back function scope.
339
340 std::string value;
341 const char* ptr;
342 size_t sz;
343 kv->get("key1", [&](string_view v) {
344 /* Save pointer to the data to use it later outside of a callback scope */
345 ptr = v.data();
346 sz = v.size();
347 });
348 kv->remove("key");
349 /* ERROR!
350 * Using this pointer outside of a callback function may cause access to some random data
351 * or a segmentation fault. At that point, ptr should be considered as invalid.
352 */
353 value.append(ptr, sz);
354
356 libpmemkv(7), libpmemkv_config(3), libpmemkv_iterator(3) and
357 <https://pmem.io>
358
359
360
361PMEMKV - pmemkv version 1.5.0 2022-01-28 PMEMKV(3)