1PMEMKV_ITERATOR(3)        PMEMKV Programmer's Manual        PMEMKV_ITERATOR(3)
2
3
4

NAME

6       pmemkv_iterator - Iterator API for libpmemkv
7
8       This API is EXPERIMENTAL and might change.
9

SYNOPSIS

11              #include <libpmemkv.h>
12
13              int pmemkv_iterator_new(pmemkv_db *db, pmemkv_iterator **it);
14              int pmemkv_write_iterator_new(pmemkv_db *db, pmemkv_write_iterator **it);
15
16              void pmemkv_iterator_delete(pmemkv_iterator *it);
17              void pmemkv_write_iterator_delete(pmemkv_write_iterator *it);
18
19              int pmemkv_iterator_seek(pmemkv_iterator *it, const char *k, size_t kb);
20              int pmemkv_iterator_seek_lower(pmemkv_iterator *it, const char *k, size_t kb);
21              int pmemkv_iterator_seek_lower_eq(pmemkv_iterator *it, const char *k, size_t kb);
22              int pmemkv_iterator_seek_higher(pmemkv_iterator *it, const char *k, size_t kb);
23              int pmemkv_iterator_seek_higher_eq(pmemkv_iterator *it, const char *k, size_t kb);
24
25              int pmemkv_iterator_seek_to_first(pmemkv_iterator *it);
26              int pmemkv_iterator_seek_to_last(pmemkv_iterator *it);
27
28              int pmemkv_iterator_is_next(pmemkv_iterator *it);
29              int pmemkv_iterator_next(pmemkv_iterator *it);
30              int pmemkv_iterator_prev(pmemkv_iterator *it);
31
32              int pmemkv_iterator_key(pmemkv_iterator *it, const char **k, size_t *kb);
33
34              int pmemkv_iterator_read_range(pmemkv_iterator *it, size_t pos, size_t n,
35                                  const char **data, size_t *rb);
36              int pmemkv_write_iterator_write_range(pmemkv_write_iterator *it, size_t pos, size_t n,
37                                  char **data, size_t *wb);
38
39              int pmemkv_write_iterator_commit(pmemkv_write_iterator *it);
40              void pmemkv_write_iterator_abort(pmemkv_write_iterator *it);
41
42       For  general  description  of  pmemkv  and  available engines see libp‐
43       memkv(7).  For description of pmemkv core API see libpmemkv(3).
44

DESCRIPTION

46       Iterators provide methods to iterate over records in db.
47
48       Both iterator types (pmemkv_iterator (read) and  pmemkv_write_iterator)
49       allow  reading record’s key and value.  To use pmemkv_write_iterator as
50       a pmemkv_iterator you need to get its member “iter” (write_it->iter).
51
52       Example of calling pmemkv_iterator_seek_to_first() with  both  iterator
53       types.
54
55              /* read_it is already created, by pmemkv_iterator */
56              int status = pmemkv_iterator_seek_to_first(read_it);
57
58              /* write_it is already created, by pmemkv_write_iterator */
59              int status = pmemkv_iterator_seek_to_first(write_it->iter);
60
61       A pmemkv_write_iterator additionally can modify record’s value transac‐
62       tionally.
63
64       Some of the functions are not guaranteed to be implemented by  all  en‐
65       gines.   If  an engine does not support a certain function, it will re‐
66       turn PMEMKV_STATUS_NOT_SUPPORTED.
67
68       Holding simultaneously in the same thread more than one iterator is un‐
69       defined behavior.
70
71       int pmemkv_iterator_new(pmemkv_db *db, pmemkv_iterator **it);
72              Creates  a  new pmemkv_iterator instance and stores a pointer to
73              it in *it.
74
75       int  pmemkv_write_iterator_new(pmemkv_db   *db,   pmemkv_write_iterator
76       **it);
77              Creates a new pmemkv_write_iterator instance and stores a point‐
78              er to it in *it.
79
80       void pmemkv_iterator_delete(pmemkv_iterator *it);
81              Deletes pmemkv_iterator.
82
83       void pmemkv_write_iterator_delete(pmemkv_write_iterator *it);
84              Deletes pmemkv_write_iterator
85
86       int pmemkv_iterator_seek(pmemkv_iterator *it,  const  char  *k,  size_t
87       kb);
88              Changes  iterator  position  to  the  record with given key k of
89              length kb.  If the record is present and no errors occurred, re‐
90              turns   PMEMKV_STATUS_OK.    If   the  record  does  not  exist,
91              PMEMKV_STATUS_NOT_FOUND is returned and the iterator position is
92              undefined.   It internally aborts all changes made to an element
93              previously pointed by the iterator.
94
95       int  pmemkv_iterator_seek_lower(pmemkv_iterator  *it,  const  char  *k,
96       size_t kb);
97              Changes iterator position to the record with key lower than giv‐
98              en key k of length kb.  If the record is present and  no  errors
99              occurred,  returns PMEMKV_STATUS_OK.  If the record does not ex‐
100              ist, PMEMKV_STATUS_NOT_FOUND is returned and the iterator  posi‐
101              tion  is undefined.  It internally aborts all changes made to an
102              element previously pointed by the iterator.
103
104       int pmemkv_iterator_seek_lower_eq(pmemkv_iterator *it, const  char  *k,
105       size_t kb);
106              Changes  iterator position to the record with key equal or lower
107              than given key k of length kb.  If the record is present and  no
108              errors  occurred,  returns PMEMKV_STATUS_OK.  If the record does
109              not exist, PMEMKV_STATUS_NOT_FOUND is returned and the  iterator
110              position is undefined.  It internally aborts all changes made to
111              an element previously pointed by the iterator.
112
113       int pmemkv_iterator_seek_higher(pmemkv_iterator  *it,  const  char  *k,
114       size_t kb);
115              Changes  iterator  position  to  the record with key higher than
116              given key k of length kb.  If the record is present and  no  er‐
117              rors occurred, returns PMEMKV_STATUS_OK.  If the record does not
118              exist, PMEMKV_STATUS_NOT_FOUND is returned and the iterator  po‐
119              sition  is  undefined.  It internally aborts all changes made to
120              an element previously pointed by the iterator.
121
122       int pmemkv_iterator_seek_higher_eq(pmemkv_iterator *it, const char  *k,
123       size_t kb);
124              Changes iterator position to the record with key equal or higher
125              than given key k of length kb.  If the record is present and  no
126              errors  occurred,  returns PMEMKV_STATUS_OK.  If the record does
127              not exist, PMEMKV_STATUS_NOT_FOUND is returned and the  iterator
128              position is undefined.  It internally aborts all changes made to
129              an element previously pointed by the iterator.
130
131       int pmemkv_iterator_seek_to_first(pmemkv_iterator *it);
132              Changes iterator position to the first record.  If db isn’t emp‐
133              ty,  and no errors occurred, returns PMEMKV_STATUS_OK.  If db is
134              empty, PMEMKV_STATUS_NOT_FOUND is returned and the iterator  po‐
135              sition  is  undefined.  It internally aborts all changes made to
136              an element previously pointed by the iterator.
137
138       int pmemkv_iterator_seek_to_last(pmemkv_iterator *it);
139              Changes iterator position to the last record.  If db isn’t  emp‐
140              ty,  and no errors occurred, returns PMEMKV_STATUS_OK.  If db is
141              empty, PMEMKV_STATUS_NOT_FOUND is returned and the iterator  po‐
142              sition  is  undefined.  It internally aborts all changes made to
143              an element previously pointed by the iterator.
144
145       int pmemkv_iterator_is_next(pmemkv_iterator *it);
146              Checks if there is a next record  available.   If  true  is  re‐
147              turned,  it is guaranteed that pmemkv_iterator_next(it) will re‐
148              turn PMEMKV_STATUS_OK, otherwise iterator is already on the last
149              element  and  pmemkv_iterator_next(it)  will  return PMEMKV_STA‐
150              TUS_NOT_FOUND.
151
152       int pmemkv_iterator_next(pmemkv_iterator *it);
153              Changes iterator position to  the  next  record.   If  the  next
154              record  exists,  returns PMEMKV_STATUS_OK, otherwise PMEMKV_STA‐
155              TUS_NOT_FOUND is returned and the  iterator  position  is  unde‐
156              fined.  It internally aborts all changes made to an element pre‐
157              viously pointed by the iterator.
158
159       int pmemkv_iterator_prev(pmemkv_iterator *it);
160              Changes iterator position to the previous record.  If the previ‐
161              ous   record   exists,   returns   PMEMKV_STATUS_OK,   otherwise
162              PMEMKV_STATUS_NOT_FOUND is returned and the iterator position is
163              undefined.   It internally aborts all changes made to an element
164              previously pointed by the iterator.
165
166       int pmemkv_iterator_key(pmemkv_iterator *it,  const  char  **k,  size_t
167       *kb);
168              Assigns  record’s key’s address to k and key’s length to kb.  If
169              the iterator is on an undefined position, calling this method is
170              undefined behaviour.
171
172       int  pmemkv_iterator_read_range(pmemkv_iterator *it, size_t pos, size_t
173       n, const char **data, size_t *rb);
174              Allows getting record’s value’s range which can  be  only  read.
175              You  can  request for either full value or only value’s subrange
176              (n elements starting from pos).  Assigns pointer to  the  begin‐
177              ning  of  the requested range to data, and number of elements in
178              range to rb.  If n is bigger than length of a value  it’s  auto‐
179              matically  shrunk.  If the iterator is on an undefined position,
180              calling this method is undefined behaviour.
181
182       int pmemkv_write_iterator_write_range(pmemkv_write_iterator *it, size_t
183       pos, size_t n, char **data, size_t *wb);
184              Allows  getting  record’s  value’s  range which can be modified.
185              You can request for either full value or only  value’s  subrange
186              (n  elements  starting from pos).  Assigns pointer to the begin‐
187              ning of the requested range to data, and number of  elements  in
188              range  to  wb.  If n is bigger than length of a value it’s auto‐
189              matically shrunk.  Changes made on a  requested  range  are  not
190              persistent  until  pmemkv_write_iterator_commit() is called.  If
191              the iterator is on an undefined position, calling this method is
192              undefined behaviour.
193
194       int pmemkv_write_iterator_commit(pmemkv_write_iterator *it);
195              Commits  modifications made on the current record.  Calling this
196              method is the only way to save modifications made by the  itera‐
197              tor  on the current record.  You need to call this method before
198              changing the iterator position, otherwise modifications will  be
199              automatically aborted.
200
201       void pmemkv_write_iterator_abort(pmemkv_write_iterator *it);
202              Aborts uncommitted modifications made on the current record.
203
204   ERRORS
205       Each function, except for pmemkv_iterator_delete(), pmemkv_write_itera‐
206       tor_delete() and  pmemkv_write_iterator_abort(),  returns  one  of  the
207       pmemkv status codes.  To check possible options see libpmemkv(3).
208

EXAMPLE

210       The following example is taken from examples/pmemkv_iterator_c directo‐
211       ry.
212
213       Usage of basic iterator functions to iterate over all records and modi‐
214       fy one of them.
215
216              #include "libpmemkv.h"
217
218              #include <assert.h>
219              #include <stdio.h>
220              #include <stdlib.h>
221              #include <string.h>
222
223              #define ASSERT(expr)                                                                     \
224                  do {                                                                             \
225                      if (!(expr))                                                             \
226                          puts(pmemkv_errormsg());                                         \
227                      assert(expr);                                                            \
228                  } while (0)
229
230              #define LOG(msg) puts(msg)
231
232              static const uint64_t SIZE = 1024UL * 1024UL * 1024UL;
233
234              int main(int argc, char *argv[])
235              {
236                  if (argc < 2) {
237                      fprintf(stderr, "Usage: %s file\n", argv[0]);
238                      exit(1);
239                  }
240
241                  const size_t n_elements = 10;
242                  char buffer[64];
243
244                  /* See libpmemkv_config(3) for more detailed example of config creation */
245                  LOG("Creating config");
246                  pmemkv_config *cfg = pmemkv_config_new();
247                  ASSERT(cfg != NULL);
248
249                  int s = pmemkv_config_put_path(cfg, argv[1]);
250                  ASSERT(s == PMEMKV_STATUS_OK);
251                  s = pmemkv_config_put_size(cfg, SIZE);
252                  ASSERT(s == PMEMKV_STATUS_OK);
253                  s = pmemkv_config_put_create_if_missing(cfg, true);
254                  ASSERT(s == PMEMKV_STATUS_OK);
255
256                  LOG("Opening pmemkv database with 'radix' engine");
257                  pmemkv_db *db = NULL;
258                  s = pmemkv_open("radix", cfg, &db);
259                  ASSERT(s == PMEMKV_STATUS_OK);
260                  ASSERT(db != NULL);
261
262                  LOG("Putting new keys");
263                  for (size_t i = 0; i < n_elements; ++i) {
264                      char key[10];
265                      const char *value = "value";
266                      sprintf(key, "key%zu", i);
267                      s = pmemkv_put(db, key, strlen(key), value, strlen(value));
268                      ASSERT(s == PMEMKV_STATUS_OK);
269                  }
270
271                  /* get a new read iterator */
272                  pmemkv_iterator *it;
273                  s = pmemkv_iterator_new(db, &it);
274                  ASSERT(s == PMEMKV_STATUS_OK);
275
276                  LOG("Iterate from first to last element");
277                  s = pmemkv_iterator_seek_to_first(it);
278                  ASSERT(s == PMEMKV_STATUS_OK);
279
280                  size_t element_number = 0;
281                  do {
282                      const char *str;
283                      size_t cnt;
284                      /* read a key */
285                      s = pmemkv_iterator_key(it, &str, &cnt);
286                      ASSERT(s == PMEMKV_STATUS_OK);
287                      sprintf(buffer, "Key %zu = %s", element_number++, str);
288                      LOG(buffer);
289                  } while (pmemkv_iterator_next(it) != PMEMKV_STATUS_NOT_FOUND);
290
291                  /* iterator must be deleted manually */
292                  pmemkv_iterator_delete(it);
293
294                  /* get a new write_iterator */
295                  pmemkv_write_iterator *w_it;
296                  s = pmemkv_write_iterator_new(db, &w_it);
297                  ASSERT(s == PMEMKV_STATUS_OK);
298
299                  /* if you want to get a pmemkv_iterator (read iterator) from a
300                   * pmemkv_write_iterator, you should do: write_it->iter */
301                  s = pmemkv_iterator_seek_to_last(w_it->iter);
302                  ASSERT(s == PMEMKV_STATUS_OK);
303
304                  /* get a write range, to modify last element's value */
305                  char *data;
306                  size_t cnt;
307                  s = pmemkv_write_iterator_write_range(w_it, 0, 5, &data, &cnt);
308                  ASSERT(s == PMEMKV_STATUS_OK);
309
310                  for (size_t i = 0; i < cnt; ++i)
311                      data[i] = 'x';
312
313                  /* commit changes */
314                  s = pmemkv_write_iterator_commit(w_it);
315                  ASSERT(s == PMEMKV_STATUS_OK);
316
317                  /* get a read range, to read modified value */
318                  const char *str;
319                  s = pmemkv_iterator_read_range(w_it->iter, 0, 5, &str, &cnt);
320                  ASSERT(s == PMEMKV_STATUS_OK);
321
322                  /* verify a modified value */
323                  ASSERT(strcmp(str, "xxxxx") == 0);
324                  sprintf(buffer, "Modified value = %s", str);
325                  LOG(buffer);
326
327                  /* iterator must be deleted manually */
328                  pmemkv_write_iterator_delete(w_it);
329
330                  LOG("Closing database");
331                  pmemkv_close(db);
332
333                  return 0;
334              }
335

SEE ALSO

337       libpmemkv(7), libpmemkv(3) and <https://pmem.io>
338
339
340
341PMEMKV - pmemkv version 1.5.0     2022-01-28                PMEMKV_ITERATOR(3)
Impressum