PMEMKV  1.5.0-git40.ga0a3589
This is the C++ documentation for PMEMKV.
libpmemkv.hpp
Go to the documentation of this file.
1 // SPDX-License-Identifier: BSD-3-Clause
2 /* Copyright 2017-2021, Intel Corporation */
3 
4 #ifndef LIBPMEMKV_HPP
5 #define LIBPMEMKV_HPP
6 
7 #include <cassert>
8 #include <functional>
9 #include <iostream>
10 #include <libpmemobj++/slice.hpp>
11 #include <libpmemobj++/string_view.hpp>
12 #include <memory>
13 #include <stdexcept>
14 #include <string>
15 #include <utility>
16 
17 #include "libpmemkv.h"
18 #include <libpmemobj/pool_base.h>
19 
33 namespace pmem
34 {
41 namespace kv
42 {
48 
55 typedef int get_kv_function(string_view key, string_view value);
62 typedef void get_v_function(string_view value);
63 
67 using get_kv_callback = pmemkv_get_kv_callback;
71 using get_v_callback = pmemkv_get_v_callback;
72 
84 enum class status {
85  OK = PMEMKV_STATUS_OK,
86  UNKNOWN_ERROR = PMEMKV_STATUS_UNKNOWN_ERROR,
87  NOT_FOUND = PMEMKV_STATUS_NOT_FOUND,
88  NOT_SUPPORTED = PMEMKV_STATUS_NOT_SUPPORTED,
90  INVALID_ARGUMENT = PMEMKV_STATUS_INVALID_ARGUMENT,
93  PMEMKV_STATUS_CONFIG_PARSING_ERROR,
95  PMEMKV_STATUS_CONFIG_TYPE_ERROR,
97  STOPPED_BY_CB = PMEMKV_STATUS_STOPPED_BY_CB,
100  PMEMKV_STATUS_OUT_OF_MEMORY,
103  PMEMKV_STATUS_WRONG_ENGINE_NAME,
106  PMEMKV_STATUS_TRANSACTION_SCOPE_ERROR,
108  DEFRAG_ERROR = PMEMKV_STATUS_DEFRAG_ERROR,
111  PMEMKV_STATUS_COMPARATOR_MISMATCH,
113 };
114 
124 inline std::ostream &operator<<(std::ostream &os, const status &s)
125 {
126  static const std::string statuses[] = {"OK",
127  "UNKNOWN_ERROR",
128  "NOT_FOUND",
129  "NOT_SUPPORTED",
130  "INVALID_ARGUMENT",
131  "CONFIG_PARSING_ERROR",
132  "CONFIG_TYPE_ERROR",
133  "STOPPED_BY_CB",
134  "OUT_OF_MEMORY",
135  "WRONG_ENGINE_NAME",
136  "TRANSACTION_SCOPE_ERROR",
137  "DEFRAG_ERROR",
138  "COMPARATOR_MISMATCH"};
139 
140  int status_no = static_cast<int>(s);
141  os << statuses[status_no] << " (" << status_no << ")";
142 
143  return os;
144 }
145 
150 class bad_result_access : public std::runtime_error {
151 public:
152  bad_result_access(const char *what_arg) : std::runtime_error(what_arg)
153  {
154  }
155 
156  const char *what() const noexcept final
157  {
158  return std::runtime_error::what();
159  }
160 
161 private:
162 };
163 
174 template <typename T>
175 class result {
176  union {
177  T value;
178  };
179 
181 
182 public:
183  result(const T &val) noexcept(noexcept(T(std::declval<T>())));
184  result(const status &err) noexcept;
185  result(const result &other) noexcept(noexcept(T(std::declval<T>())));
186  result(result &&other) noexcept(noexcept(T(std::declval<T>())));
187  result(T &&val) noexcept(noexcept(T(std::declval<T>())));
188 
189  ~result();
190 
191  result &
192  operator=(const result &other) noexcept(noexcept(std::declval<T>().~T()) &&
193  noexcept(T(std::declval<T>())));
194  result &operator=(result &&other) noexcept(noexcept(std::declval<T>().~T()) &&
195  noexcept(T(std::declval<T>())));
196 
197  bool is_ok() const noexcept;
198 
199  const T &get_value() const &;
200  T &get_value() &;
201 
202  T &&get_value() &&;
203 
204  status get_status() const noexcept;
205 };
206 
212 template <typename T>
213 result<T>::result(const T &val) noexcept(noexcept(T(std::declval<T>())))
214  : value(val), s(status::OK)
215 {
216 }
217 
223 template <typename T>
225 {
226  assert(s != status::OK);
227 }
228 
234 template <typename T>
235 result<T>::result(const result &other) noexcept(noexcept(T(std::declval<T>())))
236  : s(other.s)
237 {
238  if (s == status::OK)
239  new (&value) T(other.value);
240 }
241 
247 template <typename T>
248 result<T>::result(result &&other) noexcept(noexcept(T(std::declval<T>()))) : s(other.s)
249 {
250  if (s == status::OK)
251  new (&value) T(std::move(other.value));
252 
253  other.s = status::UNKNOWN_ERROR;
254 }
255 
259 template <typename T>
261 {
262  if (s == status::OK)
263  value.~T();
264 }
265 
271 template <typename T>
272 result<T> &
273 result<T>::operator=(const result &other) noexcept(noexcept(std::declval<T>().~T()) &&
274  noexcept(T(std::declval<T>())))
275 {
276  if (s == status::OK && other.is_ok())
277  value = other.value;
278  else if (other.is_ok())
279  new (&value) T(other.value);
280  else if (s == status::OK)
281  value.~T();
282 
283  s = other.s;
284 
285  return *this;
286 }
287 
293 template <typename T>
294 result<T> &
295 result<T>::operator=(result &&other) noexcept(noexcept(std::declval<T>().~T()) &&
296  noexcept(T(std::declval<T>())))
297 {
298  if (s == status::OK && other.is_ok())
299  value = std::move(other.value);
300  else if (other.is_ok())
301  new (&value) T(std::move(other.value));
302  else if (s == status::OK)
303  value.~T();
304 
305  s = other.s;
306  other.s = status::UNKNOWN_ERROR;
307 
308  return *this;
309 }
310 
316 template <typename T>
317 result<T>::result(T &&val) noexcept(noexcept(T(std::declval<T>())))
318  : value(std::move(val)), s(status::OK)
319 {
320 }
321 
327 template <typename T>
328 bool result<T>::is_ok() const noexcept
329 {
330  return s == status::OK;
331 }
332 
342 template <typename T>
343 const T &result<T>::get_value() const &
344 {
345  if (s == status::OK)
346  return value;
347  else
348  throw bad_result_access("bad_result_access: value doesn't exist");
349 }
350 
360 template <typename T>
362 {
363  if (s == status::OK)
364  return value;
365  else
366  throw bad_result_access("bad_result_access: value doesn't exist");
367 }
368 
378 template <typename T>
380 {
381  if (s == status::OK) {
383  return std::move(value);
384  } else
385  throw bad_result_access("bad_result_access: value doesn't exist");
386 }
387 
396 template <typename T>
398 {
399  return s;
400 }
401 
402 template <typename T>
403 bool operator==(const result<T> &lhs, const status &rhs)
404 {
405  return lhs.get_status() == rhs;
406 }
407 
408 template <typename T>
409 bool operator==(const status &lhs, const result<T> &rhs)
410 {
411  return lhs == rhs.get_status();
412 }
413 
414 template <typename T>
415 bool operator!=(const result<T> &lhs, const status &rhs)
416 {
417  return lhs.get_status() != rhs;
418 }
419 
420 template <typename T>
421 bool operator!=(const status &lhs, const result<T> &rhs)
422 {
423  return lhs != rhs.get_status();
424 }
425 
445 class config {
446 #define force_create_deprecated \
447  __attribute__((deprecated("use config::put_create_or_error_if_exists instead")))
448 
449 public:
450  config() noexcept;
451  explicit config(pmemkv_config *cfg) noexcept;
452 
453  template <typename T>
454  status put_data(const std::string &key, const T *value,
455  const std::size_t number = 1) noexcept;
456 
457  template <typename T>
458  status put_object(const std::string &key, T *value,
459  void (*deleter)(void *)) noexcept;
460  template <typename T, typename D>
461  status put_object(const std::string &key, std::unique_ptr<T, D> object) noexcept;
462  status put_uint64(const std::string &key, std::uint64_t value) noexcept;
463  status put_int64(const std::string &key, std::int64_t value) noexcept;
464  status put_string(const std::string &key, const std::string &value) noexcept;
465 
466  status put_size(std::uint64_t size) noexcept;
467  status put_path(const std::string &path) noexcept;
468  status put_force_create(bool value) noexcept force_create_deprecated;
469  status put_create_or_error_if_exists(bool value) noexcept;
470  status put_create_if_missing(bool value) noexcept;
471  status put_oid(PMEMoid *oid) noexcept;
472  template <typename Comparator>
473  status put_comparator(Comparator &&comparator);
474 
475  template <typename T>
476  status get_data(const std::string &key, T *&value, std::size_t &number) const
477  noexcept;
478  template <typename T>
479  status get_object(const std::string &key, T *&value) const noexcept;
480 
481  status get_uint64(const std::string &key, std::uint64_t &value) const noexcept;
482  status get_int64(const std::string &key, std::int64_t &value) const noexcept;
483  status get_string(const std::string &key, std::string &value) const noexcept;
484 
485  pmemkv_config *release() noexcept;
486 
487 private:
488  int init() noexcept;
489 
490  std::unique_ptr<pmemkv_config, decltype(&pmemkv_config_delete)> config_;
491 };
492 
508 class tx {
509 public:
510  tx(pmemkv_tx *tx_) noexcept;
511 
512  status put(string_view key, string_view value) noexcept;
513  status remove(string_view key) noexcept;
514  status commit() noexcept;
515  void abort() noexcept;
516 
517 private:
518  std::unique_ptr<pmemkv_tx, decltype(&pmemkv_tx_end)> tx_;
519 };
520 
542 class db {
543  template <bool IsConst>
544  class iterator;
545 
546 public:
549 
550  db() noexcept;
551 
552  status open(const std::string &engine_name, config &&cfg = config{}) noexcept;
553 
554  void close() noexcept;
555 
556  status count_all(std::size_t &cnt) noexcept;
557  status count_above(string_view key, std::size_t &cnt) noexcept;
558  status count_equal_above(string_view key, std::size_t &cnt) noexcept;
559  status count_equal_below(string_view key, std::size_t &cnt) noexcept;
560  status count_below(string_view key, std::size_t &cnt) noexcept;
561  status count_between(string_view key1, string_view key2,
562  std::size_t &cnt) noexcept;
563 
564  status get_all(get_kv_callback *callback, void *arg) noexcept;
565  status get_all(std::function<get_kv_function> f) noexcept;
566 
567  status get_above(string_view key, get_kv_callback *callback, void *arg) noexcept;
568  status get_above(string_view key, std::function<get_kv_function> f) noexcept;
569 
570  status get_equal_above(string_view key, get_kv_callback *callback,
571  void *arg) noexcept;
572  status get_equal_above(string_view key,
573  std::function<get_kv_function> f) noexcept;
574 
575  status get_equal_below(string_view key, get_kv_callback *callback,
576  void *arg) noexcept;
577  status get_equal_below(string_view key,
578  std::function<get_kv_function> f) noexcept;
579 
580  status get_below(string_view key, get_kv_callback *callback, void *arg) noexcept;
581  status get_below(string_view key, std::function<get_kv_function> f) noexcept;
582 
583  status get_between(string_view key1, string_view key2, get_kv_callback *callback,
584  void *arg) noexcept;
585  status get_between(string_view key1, string_view key2,
586  std::function<get_kv_function> f) noexcept;
587 
588  status exists(string_view key) noexcept;
589 
590  status get(string_view key, get_v_callback *callback, void *arg) noexcept;
591  status get(string_view key, std::function<get_v_function> f) noexcept;
592  status get(string_view key, std::string *value) noexcept;
593 
594  status put(string_view key, string_view value) noexcept;
595  status remove(string_view key) noexcept;
596  status defrag(double start_percent = 0, double amount_percent = 100);
597 
598  result<tx> tx_begin() noexcept;
599 
600  result<read_iterator> new_read_iterator();
601  result<write_iterator> new_write_iterator();
602 
603  std::string errormsg();
604 
605 private:
606  std::unique_ptr<pmemkv_db, decltype(&pmemkv_close)> db_;
607 };
608 
630 template <bool IsConst>
631 class db::iterator {
632  using iterator_type = typename std::conditional<IsConst, pmemkv_iterator,
633  pmemkv_write_iterator>::type;
634 
635  template <typename T>
636  class OutputIterator;
637 
638 public:
640 
641  status seek(string_view key) noexcept;
642  status seek_lower(string_view key) noexcept;
643  status seek_lower_eq(string_view key) noexcept;
644  status seek_higher(string_view key) noexcept;
645  status seek_higher_eq(string_view key) noexcept;
646 
647  status seek_to_first() noexcept;
648  status seek_to_last() noexcept;
649 
650  status is_next() noexcept;
651  status next() noexcept;
652  status prev() noexcept;
653 
654  result<string_view> key() noexcept;
655 
657  read_range(size_t pos = 0,
658  size_t n = std::numeric_limits<size_t>::max()) noexcept;
659 
660  template <bool IC = IsConst>
661  typename std::enable_if<!IC, result<pmem::obj::slice<OutputIterator<char>>>>::type
662  write_range(size_t pos = 0,
663  size_t n = std::numeric_limits<size_t>::max()) noexcept;
664 
665  template <bool IC = IsConst>
666  typename std::enable_if<!IC, status>::type commit() noexcept;
667  template <bool IC = IsConst>
668  typename std::enable_if<!IC>::type abort() noexcept;
669 
670 private:
671  std::unique_ptr<
673  typename std::conditional<IsConst, decltype(&pmemkv_iterator_delete),
674  decltype(&pmemkv_write_iterator_delete)>::type>
675  it_;
676 
677  pmemkv_iterator *get_raw_it();
678 };
679 
684 template <bool IsConst>
685 template <typename T>
686 class db::iterator<IsConst>::OutputIterator {
687  struct assign_only;
688 
689 public:
691  using pointer = void;
692  using difference_type = std::ptrdiff_t;
693  using value_type = void;
694  using iterator_category = std::output_iterator_tag;
695 
696  OutputIterator(T *x);
697 
698  reference operator*();
699 
700  OutputIterator &operator++();
701  OutputIterator operator++(int);
702 
703  OutputIterator &operator--();
704  OutputIterator operator--(int);
705 
706  assign_only operator[](difference_type pos);
707 
708  difference_type operator-(const OutputIterator &other) const;
709 
710  bool operator!=(const OutputIterator &other) const;
711 
712 private:
713  struct assign_only {
715 
716  assign_only(T *x);
717 
718  assign_only &operator=(const T &x);
719 
720  private:
721  T *c;
722  };
723 
725 };
726 
727 template <bool IsConst>
728 template <typename T>
730 {
731 }
732 
733 template <bool IsConst>
734 template <typename T>
737 {
738  return ao;
739 }
740 
741 template <bool IsConst>
742 template <typename T>
745 {
746  ao.c += sizeof(T);
747  return *this;
748 }
749 
750 template <bool IsConst>
751 template <typename T>
754 {
755  auto tmp = *this;
756  ++(*this);
757  return tmp;
758 }
759 
760 template <bool IsConst>
761 template <typename T>
764 {
765  ao.c -= sizeof(T);
766  return *this;
767 }
768 
769 template <bool IsConst>
770 template <typename T>
773 {
774  auto tmp = *this;
775  --(*this);
776  return tmp;
777 }
778 
779 template <bool IsConst>
780 template <typename T>
783 {
784  return assign_only(ao.c + pos);
785 }
786 
787 template <bool IsConst>
788 template <typename T>
791 {
792  return this->ao.c - other.ao.c;
793 }
794 
795 template <bool IsConst>
796 template <typename T>
798  const OutputIterator &other) const
799 {
800  return this->ao.c != other.ao.c;
801 }
802 
803 template <bool IsConst>
804 template <typename T>
806 {
807 }
808 
809 template <bool IsConst>
810 template <typename T>
813 {
814  *c = x;
815  return *this;
816 }
817 
818 template <>
819 inline db::iterator<true>::iterator(iterator_type *it) : it_(it, &pmemkv_iterator_delete)
820 {
821 }
822 
823 template <>
825  : it_(it, &pmemkv_write_iterator_delete)
826 {
827 }
828 
842 template <bool IsConst>
844 {
845  return static_cast<status>(
846  pmemkv_iterator_seek(this->get_raw_it(), key.data(), key.size()));
847 }
848 
862 template <bool IsConst>
864 {
865  return static_cast<status>(
866  pmemkv_iterator_seek_lower(this->get_raw_it(), key.data(), key.size()));
867 }
868 
882 template <bool IsConst>
884 {
885  return static_cast<status>(pmemkv_iterator_seek_lower_eq(this->get_raw_it(),
886  key.data(), key.size()));
887 }
888 
902 template <bool IsConst>
904 {
905  return static_cast<status>(
906  pmemkv_iterator_seek_higher(this->get_raw_it(), key.data(), key.size()));
907 }
908 
922 template <bool IsConst>
924 {
925  return static_cast<status>(pmemkv_iterator_seek_higher_eq(
926  this->get_raw_it(), key.data(), key.size()));
927 }
928 
940 template <bool IsConst>
942 {
943  return static_cast<status>(pmemkv_iterator_seek_to_first(this->get_raw_it()));
944 }
945 
957 template <bool IsConst>
959 {
960  return static_cast<status>(pmemkv_iterator_seek_to_last(this->get_raw_it()));
961 }
962 
973 template <bool IsConst>
975 {
976  return static_cast<status>(pmemkv_iterator_is_next(this->get_raw_it()));
977 }
978 
992 template <bool IsConst>
994 {
995  return static_cast<status>(pmemkv_iterator_next(this->get_raw_it()));
996 }
997 
1011 template <bool IsConst>
1013 {
1014  return static_cast<status>(pmemkv_iterator_prev(this->get_raw_it()));
1015 }
1016 
1026 template <bool IsConst>
1028 {
1029  const char *c;
1030  size_t size;
1031  auto s = static_cast<status>(pmemkv_iterator_key(this->get_raw_it(), &c, &size));
1032 
1033  if (s == status::OK)
1034  return {string_view{c, size}};
1035  else
1036  return {s};
1037 }
1038 
1055 template <bool IsConst>
1057  size_t n) noexcept
1058 {
1059  const char *data;
1060  size_t size;
1061  auto s = static_cast<status>(
1062  pmemkv_iterator_read_range(this->get_raw_it(), pos, n, &data, &size));
1063 
1064  if (s == status::OK)
1065  return {string_view{data, size}};
1066  else
1067  return {s};
1068 }
1069 
1089 template <>
1090 template <>
1092 db::iterator<false>::write_range(size_t pos, size_t n) noexcept
1093 {
1094  char *data;
1095  size_t size;
1096  auto s = static_cast<status>(
1097  pmemkv_write_iterator_write_range(this->it_.get(), pos, n, &data, &size));
1098 
1099  if (s == status::OK) {
1100  try {
1101  return {{data, data + size}};
1102  } catch (std::out_of_range &e) {
1103  return {status::INVALID_ARGUMENT};
1104  }
1105  } else
1106  return {s};
1107 }
1108 
1118 template <>
1119 template <>
1121 {
1122  auto s = static_cast<status>(pmemkv_write_iterator_commit(this->it_.get()));
1123  return s;
1124 }
1125 
1129 template <>
1130 template <>
1131 inline void db::iterator<false>::abort() noexcept
1132 {
1133  pmemkv_write_iterator_abort(this->it_.get());
1134 }
1135 
1136 template <>
1137 inline pmemkv_iterator *db::iterator<true>::get_raw_it()
1138 {
1139  return it_.get();
1140 }
1141 
1142 template <>
1143 inline pmemkv_iterator *db::iterator<false>::get_raw_it()
1144 {
1145  return it_.get()->iter;
1146 }
1147 
1154 namespace internal
1155 {
1156 
1157 /*
1158  * Abstracts unique_ptr - exposes only void *get() method and a destructor.
1159  * This class is needed for C callbacks which cannot be templated
1160  * (type of object and deleter must be abstracted away).
1161  */
1164  {
1165  }
1166 
1167  virtual void *get() = 0;
1168 };
1169 
1170 template <typename T, typename D>
1172  unique_ptr_wrapper(std::unique_ptr<T, D> ptr) : ptr(std::move(ptr))
1173  {
1174  }
1175 
1176  void *get() override
1177  {
1178  return ptr.get();
1179  }
1180 
1181  std::unique_ptr<T, D> ptr;
1182 };
1183 
1185 public:
1187  {
1188  }
1189  virtual int compare(string_view key1, string_view key2) = 0;
1190 };
1191 
1192 template <typename Comparator>
1194  comparator_wrapper(const Comparator &cmp) : cmp(cmp)
1195  {
1196  }
1197 
1198  comparator_wrapper(Comparator &&cmp) : cmp(std::move(cmp))
1199  {
1200  }
1201 
1202  int compare(string_view key1, string_view key2) override
1203  {
1204  return cmp.compare(key1, key2);
1205  }
1206 
1207  Comparator cmp;
1208 };
1209 
1212  std::unique_ptr<comparator_base> ptr,
1213  std::unique_ptr<pmemkv_comparator, decltype(pmemkv_comparator_delete) *>
1214  c_cmp)
1215  : ptr(std::move(ptr)), c_cmp(std::move(c_cmp))
1216  {
1217  }
1218 
1219  void *get() override
1220  {
1221  return c_cmp.get();
1222  }
1223 
1224  std::unique_ptr<comparator_base> ptr;
1225  std::unique_ptr<pmemkv_comparator, decltype(pmemkv_comparator_delete) *> c_cmp;
1226 };
1227 
1228 /*
1229  * All functions which will be called by C code must be declared as extern "C"
1230  * to ensure they have C linkage. It is needed because it is possible that
1231  * C and C++ functions use different calling conventions.
1232  */
1233 extern "C" {
1234 static inline void call_up_destructor(void *object)
1235 {
1236  auto *ptr = static_cast<unique_ptr_wrapper_base *>(object);
1237  delete ptr;
1238 }
1239 
1240 static inline void *call_up_get(void *object)
1241 {
1242  auto *ptr = static_cast<unique_ptr_wrapper_base *>(object);
1243  return ptr->get();
1244 }
1245 
1246 static inline int call_comparator_function(const char *k1, size_t kb1, const char *k2,
1247  size_t kb2, void *arg)
1248 {
1249  auto *cmp = static_cast<comparator_base *>(arg);
1250  return cmp->compare(string_view(k1, kb1), string_view(k2, kb2));
1251 }
1252 } /* extern "C" */
1253 } /* namespace internal */
1254 
1258 inline config::config() noexcept : config_(nullptr, &pmemkv_config_delete)
1259 {
1260 }
1261 
1266 inline config::config(pmemkv_config *cfg) noexcept : config_(cfg, &pmemkv_config_delete)
1267 {
1268 }
1269 
1276 inline int config::init() noexcept
1277 {
1278  if (this->config_.get() == nullptr) {
1279  this->config_ = {pmemkv_config_new(), &pmemkv_config_delete};
1280 
1281  if (this->config_.get() == nullptr)
1282  return 1;
1283  }
1284 
1285  return 0;
1286 }
1287 
1298 template <typename T>
1299 inline status config::put_data(const std::string &key, const T *value,
1300  const std::size_t count) noexcept
1301 {
1302  if (init() != 0)
1303  return status::UNKNOWN_ERROR;
1304 
1305  return static_cast<status>(pmemkv_config_put_data(
1306  this->config_.get(), key.data(), (void *)value, count * sizeof(T)));
1307 }
1308 
1319 template <typename T>
1320 inline status config::put_object(const std::string &key, T *value,
1321  void (*deleter)(void *)) noexcept
1322 {
1323  if (init() != 0)
1324  return status::UNKNOWN_ERROR;
1325 
1326  return static_cast<status>(pmemkv_config_put_object(
1327  this->config_.get(), key.data(), (void *)value, deleter));
1328 }
1329 
1338 template <typename T, typename D>
1339 inline status config::put_object(const std::string &key,
1340  std::unique_ptr<T, D> object) noexcept
1341 {
1342  if (init() != 0)
1343  return status::UNKNOWN_ERROR;
1344 
1346 
1347  try {
1348  wrapper = new internal::unique_ptr_wrapper<T, D>(std::move(object));
1349  } catch (std::bad_alloc &e) {
1350  return status::OUT_OF_MEMORY;
1351  } catch (...) {
1352  return status::UNKNOWN_ERROR;
1353  }
1354 
1355  return static_cast<status>(pmemkv_config_put_object_cb(
1356  this->config_.get(), key.data(), (void *)wrapper, internal::call_up_get,
1357  internal::call_up_destructor));
1358 }
1359 
1379 template <typename Comparator>
1380 inline status config::put_comparator(Comparator &&comparator)
1381 {
1382  static_assert(
1383  std::is_same<decltype(std::declval<Comparator>().compare(
1384  std::declval<string_view>(),
1385  std::declval<string_view>())),
1386  int>::value,
1387  "Comparator should implement `int compare(pmem::kv::string_view, pmem::kv::string_view)` method");
1388  static_assert(std::is_convertible<decltype(std::declval<Comparator>().name()),
1389  std::string>::value,
1390  "Comparator should implement `std::string name()` method");
1391 
1392  std::unique_ptr<internal::comparator_base> wrapper;
1393 
1394  try {
1395  wrapper = std::unique_ptr<internal::comparator_base>(
1397  std::forward<Comparator>(comparator)));
1398  } catch (std::bad_alloc &e) {
1399  return status::OUT_OF_MEMORY;
1400  } catch (...) {
1401  return status::UNKNOWN_ERROR;
1402  }
1403 
1404  auto cmp =
1405  std::unique_ptr<pmemkv_comparator, decltype(pmemkv_comparator_delete) *>(
1406  pmemkv_comparator_new(&internal::call_comparator_function,
1407  std::string(comparator.name()).c_str(),
1408  wrapper.get()),
1409  &pmemkv_comparator_delete);
1410  if (cmp == nullptr)
1411  return status::UNKNOWN_ERROR;
1412 
1414 
1415  try {
1416  entry = new internal::comparator_config_entry(std::move(wrapper),
1417  std::move(cmp));
1418  } catch (std::bad_alloc &e) {
1419  return status::OUT_OF_MEMORY;
1420  } catch (...) {
1421  return status::UNKNOWN_ERROR;
1422  }
1423 
1424  return static_cast<status>(pmemkv_config_put_object_cb(
1425  this->config_.get(), "comparator", (void *)entry, internal::call_up_get,
1426  internal::call_up_destructor));
1427 }
1428 
1437 inline status config::put_uint64(const std::string &key, std::uint64_t value) noexcept
1438 {
1439  if (init() != 0)
1440  return status::UNKNOWN_ERROR;
1441 
1442  return static_cast<status>(
1443  pmemkv_config_put_uint64(this->config_.get(), key.data(), value));
1444 }
1445 
1454 inline status config::put_int64(const std::string &key, std::int64_t value) noexcept
1455 {
1456  if (init() != 0)
1457  return status::UNKNOWN_ERROR;
1458 
1459  return static_cast<status>(
1460  pmemkv_config_put_int64(this->config_.get(), key.data(), value));
1461 }
1462 
1471 inline status config::put_string(const std::string &key,
1472  const std::string &value) noexcept
1473 {
1474  if (init() != 0)
1475  return status::UNKNOWN_ERROR;
1476 
1477  return static_cast<status>(
1478  pmemkv_config_put_string(this->config_.get(), key.data(), value.data()));
1479 }
1480 
1488 inline status config::put_size(std::uint64_t size) noexcept
1489 {
1490  return put_uint64("size", size);
1491 }
1492 
1501 inline status config::put_path(const std::string &path) noexcept
1502 {
1503  return put_string("path", path);
1504 }
1505 
1512 inline status config::put_force_create(bool value) noexcept
1513 {
1514  return put_create_or_error_if_exists(value);
1515 }
1516 
1528 {
1529  return put_uint64("create_or_error_if_exists", static_cast<std::uint64_t>(value));
1530 }
1531 
1543 inline status config::put_create_if_missing(bool value) noexcept
1544 {
1545  return put_uint64("create_if_missing", static_cast<std::uint64_t>(value));
1546 }
1547 
1557 inline status config::put_oid(PMEMoid *oid) noexcept
1558 {
1559  if (init() != 0)
1560  return status::UNKNOWN_ERROR;
1561 
1562  return static_cast<status>(pmemkv_config_put_oid(this->config_.get(), oid));
1563 }
1564 
1575 template <typename T>
1576 inline status config::get_data(const std::string &key, T *&value,
1577  std::size_t &count) const noexcept
1578 {
1579  if (this->config_.get() == nullptr)
1580  return status::NOT_FOUND;
1581 
1582  std::size_t size;
1583  auto s = static_cast<status>(pmemkv_config_get_data(
1584  this->config_.get(), key.data(), (const void **)&value, &size));
1585 
1586  if (s != status::OK)
1587  return s;
1588 
1589  count = size / sizeof(T);
1590 
1591  return status::OK;
1592 }
1593 
1603 template <typename T>
1604 inline status config::get_object(const std::string &key, T *&value) const noexcept
1605 {
1606  if (this->config_.get() == nullptr)
1607  return status::NOT_FOUND;
1608 
1609  auto s = static_cast<status>(pmemkv_config_get_object(
1610  this->config_.get(), key.data(), (void **)&value));
1611 
1612  return s;
1613 }
1614 
1623 inline status config::get_uint64(const std::string &key, std::uint64_t &value) const
1624  noexcept
1625 {
1626  if (this->config_.get() == nullptr)
1627  return status::NOT_FOUND;
1628 
1629  return static_cast<status>(
1630  pmemkv_config_get_uint64(this->config_.get(), key.data(), &value));
1631 }
1632 
1641 inline status config::get_int64(const std::string &key, std::int64_t &value) const
1642  noexcept
1643 {
1644  if (this->config_.get() == nullptr)
1645  return status::NOT_FOUND;
1646 
1647  return static_cast<status>(
1648  pmemkv_config_get_int64(this->config_.get(), key.data(), &value));
1649 }
1650 
1659 inline status config::get_string(const std::string &key, std::string &value) const
1660  noexcept
1661 {
1662  if (this->config_.get() == nullptr)
1663  return status::NOT_FOUND;
1664 
1665  const char *data;
1666 
1667  auto s = static_cast<status>(
1668  pmemkv_config_get_string(this->config_.get(), key.data(), &data));
1669 
1670  if (s != status::OK)
1671  return s;
1672 
1673  value = data;
1674 
1675  return status::OK;
1676 }
1677 
1684 inline pmemkv_config *config::release() noexcept
1685 {
1686  return this->config_.release();
1687 }
1688 
1692 inline tx::tx(pmemkv_tx *tx_) noexcept : tx_(tx_, &pmemkv_tx_end)
1693 {
1694 }
1695 
1705 inline status tx::remove(string_view key) noexcept
1706 {
1707  return static_cast<status>(pmemkv_tx_remove(tx_.get(), key.data(), key.size()));
1708 }
1709 
1719 inline status tx::put(string_view key, string_view value) noexcept
1720 {
1721  return static_cast<status>(pmemkv_tx_put(tx_.get(), key.data(), key.size(),
1722  value.data(), value.size()));
1723 }
1724 
1732 inline status tx::commit() noexcept
1733 {
1734  return static_cast<status>(pmemkv_tx_commit(tx_.get()));
1735 }
1736 
1741 inline void tx::abort() noexcept
1742 {
1743  pmemkv_tx_abort(tx_.get());
1744 }
1745 
1746 /*
1747  * All functions which will be called by C code must be declared as extern "C"
1748  * to ensure they have C linkage. It is needed because it is possible that
1749  * C and C++ functions use different calling conventions.
1750  */
1751 extern "C" {
1752 static inline int call_get_kv_function(const char *key, size_t keybytes,
1753  const char *value, size_t valuebytes, void *arg)
1754 {
1755  return (*reinterpret_cast<std::function<get_kv_function> *>(arg))(
1756  string_view(key, keybytes), string_view(value, valuebytes));
1757 }
1758 
1759 static inline void call_get_v_function(const char *value, size_t valuebytes, void *arg)
1760 {
1761  (*reinterpret_cast<std::function<get_v_function> *>(arg))(
1762  string_view(value, valuebytes));
1763 }
1764 
1765 static inline void call_get_copy(const char *v, size_t vb, void *arg)
1766 {
1767  auto c = reinterpret_cast<std::string *>(arg);
1768  c->assign(v, vb);
1769 }
1770 }
1771 
1775 inline db::db() noexcept : db_(nullptr, &pmemkv_close)
1776 {
1777 }
1778 
1787 inline status db::open(const std::string &engine_name, config &&cfg) noexcept
1788 {
1789  pmemkv_db *db;
1790  auto s =
1791  static_cast<status>(pmemkv_open(engine_name.c_str(), cfg.release(), &db));
1792  if (s == pmem::kv::status::OK)
1793  this->db_.reset(db);
1794  return s;
1795 }
1796 
1800 inline void db::close() noexcept
1801 {
1802  this->db_.reset(nullptr);
1803 }
1804 
1812 inline status db::count_all(std::size_t &cnt) noexcept
1813 {
1814  return static_cast<status>(pmemkv_count_all(this->db_.get(), &cnt));
1815 }
1816 
1827 inline status db::count_above(string_view key, std::size_t &cnt) noexcept
1828 {
1829  return static_cast<status>(
1830  pmemkv_count_above(this->db_.get(), key.data(), key.size(), &cnt));
1831 }
1832 
1843 inline status db::count_equal_above(string_view key, std::size_t &cnt) noexcept
1844 {
1845  return static_cast<status>(
1846  pmemkv_count_equal_above(this->db_.get(), key.data(), key.size(), &cnt));
1847 }
1848 
1859 inline status db::count_equal_below(string_view key, std::size_t &cnt) noexcept
1860 {
1861  return static_cast<status>(
1862  pmemkv_count_equal_below(this->db_.get(), key.data(), key.size(), &cnt));
1863 }
1864 
1875 inline status db::count_below(string_view key, std::size_t &cnt) noexcept
1876 {
1877  return static_cast<status>(
1878  pmemkv_count_below(this->db_.get(), key.data(), key.size(), &cnt));
1879 }
1880 
1893  std::size_t &cnt) noexcept
1894 {
1895  return static_cast<status>(pmemkv_count_between(this->db_.get(), key1.data(),
1896  key1.size(), key2.data(),
1897  key2.size(), &cnt));
1898 }
1899 
1912 inline status db::get_all(get_kv_callback *callback, void *arg) noexcept
1913 {
1914  return static_cast<status>(pmemkv_get_all(this->db_.get(), callback, arg));
1915 }
1916 
1927 inline status db::get_all(std::function<get_kv_function> f) noexcept
1928 {
1929  return static_cast<status>(
1930  pmemkv_get_all(this->db_.get(), call_get_kv_function, &f));
1931 }
1932 
1950  void *arg) noexcept
1951 {
1952  return static_cast<status>(
1953  pmemkv_get_above(this->db_.get(), key.data(), key.size(), callback, arg));
1954 }
1955 
1970 inline status db::get_above(string_view key, std::function<get_kv_function> f) noexcept
1971 {
1972  return static_cast<status>(pmemkv_get_above(
1973  this->db_.get(), key.data(), key.size(), call_get_kv_function, &f));
1974 }
1975 
1994  void *arg) noexcept
1995 {
1996  return static_cast<status>(pmemkv_get_equal_above(this->db_.get(), key.data(),
1997  key.size(), callback, arg));
1998 }
1999 
2016  std::function<get_kv_function> f) noexcept
2017 {
2018  return static_cast<status>(pmemkv_get_equal_above(
2019  this->db_.get(), key.data(), key.size(), call_get_kv_function, &f));
2020 }
2021 
2040  void *arg) noexcept
2041 {
2042  return static_cast<status>(pmemkv_get_equal_below(this->db_.get(), key.data(),
2043  key.size(), callback, arg));
2044 }
2045 
2062  std::function<get_kv_function> f) noexcept
2063 {
2064  return static_cast<status>(pmemkv_get_equal_below(
2065  this->db_.get(), key.data(), key.size(), call_get_kv_function, &f));
2066 }
2067 
2085  void *arg) noexcept
2086 {
2087  return static_cast<status>(
2088  pmemkv_get_below(this->db_.get(), key.data(), key.size(), callback, arg));
2089 }
2090 
2105 inline status db::get_below(string_view key, std::function<get_kv_function> f) noexcept
2106 {
2107  return static_cast<status>(pmemkv_get_below(
2108  this->db_.get(), key.data(), key.size(), call_get_kv_function, &f));
2109 }
2110 
2129  get_kv_callback *callback, void *arg) noexcept
2130 {
2131  return static_cast<status>(pmemkv_get_between(this->db_.get(), key1.data(),
2132  key1.size(), key2.data(),
2133  key2.size(), callback, arg));
2134 }
2151  std::function<get_kv_function> f) noexcept
2152 {
2153  return static_cast<status>(
2154  pmemkv_get_between(this->db_.get(), key1.data(), key1.size(), key2.data(),
2155  key2.size(), call_get_kv_function, &f));
2156 }
2157 
2167 inline status db::exists(string_view key) noexcept
2168 {
2169  return static_cast<status>(
2170  pmemkv_exists(this->db_.get(), key.data(), key.size()));
2171 }
2172 
2188 inline status db::get(string_view key, get_v_callback *callback, void *arg) noexcept
2189 {
2190  return static_cast<status>(
2191  pmemkv_get(this->db_.get(), key.data(), key.size(), callback, arg));
2192 }
2193 
2205 inline status db::get(string_view key, std::function<get_v_function> f) noexcept
2206 {
2207  return static_cast<status>(pmemkv_get(this->db_.get(), key.data(), key.size(),
2208  call_get_v_function, &f));
2209 }
2210 
2221 inline status db::get(string_view key, std::string *value) noexcept
2222 {
2223  return static_cast<status>(pmemkv_get(this->db_.get(), key.data(), key.size(),
2224  call_get_copy, value));
2225 }
2226 
2236 inline status db::put(string_view key, string_view value) noexcept
2237 {
2238  return static_cast<status>(pmemkv_put(this->db_.get(), key.data(), key.size(),
2239  value.data(), value.size()));
2240 }
2241 
2250 inline status db::remove(string_view key) noexcept
2251 {
2252  return static_cast<status>(
2253  pmemkv_remove(this->db_.get(), key.data(), key.size()));
2254 }
2255 
2265 inline status db::defrag(double start_percent, double amount_percent)
2266 {
2267  return static_cast<status>(
2268  pmemkv_defrag(this->db_.get(), start_percent, amount_percent));
2269 }
2270 
2277 {
2278  pmemkv_write_iterator *tmp;
2279  auto ret = static_cast<status>(pmemkv_write_iterator_new(db_.get(), &tmp));
2280  if (static_cast<status>(ret) == status::OK)
2281  return {db::iterator<false>{tmp}};
2282  else
2283  return {ret};
2284 }
2285 
2292 {
2293  pmemkv_iterator *tmp;
2294  auto ret = static_cast<status>(pmemkv_iterator_new(db_.get(), &tmp));
2295  if (ret == status::OK)
2296  return {db::iterator<true>{tmp}};
2297  else
2298  return {ret};
2299 }
2300 
2308 inline std::string db::errormsg()
2309 {
2310  return std::string(pmemkv_errormsg());
2311 }
2312 
2318 static inline std::string errormsg()
2319 {
2320  return std::string(pmemkv_errormsg());
2321 }
2322 
2328 inline result<tx> db::tx_begin() noexcept
2329 {
2330  pmemkv_tx *tx_;
2331  auto s = static_cast<status>(pmemkv_tx_begin(db_.get(), &tx_));
2332 
2333  if (s == status::OK)
2334  return result<tx>(tx(tx_));
2335  else
2336  return result<tx>(s);
2337 }
2338 
2339 } /* namespace kv */
2340 } /* namespace pmem */
2341 
2342 #endif /* LIBPMEMKV_HPP */
Defines a type of object to be thrown by result::get_value() when result doesn't contain value.
Definition: libpmemkv.hpp:150
const char * what() const noexcept final
Definition: libpmemkv.hpp:156
bad_result_access(const char *what_arg)
Definition: libpmemkv.hpp:152
Holds configuration parameters for engines.
Definition: libpmemkv.hpp:445
status put_create_or_error_if_exists(bool value) noexcept
Puts create_or_error_if_exists parameter to a config.
Definition: libpmemkv.hpp:1527
status put_force_create(bool value) noexcept force_create_deprecated
It's an alias for config::put_create_or_error_if_exists, kept for compatibility.
Definition: libpmemkv.hpp:1512
status put_uint64(const std::string &key, std::uint64_t value) noexcept
Puts std::uint64_t value to a config.
Definition: libpmemkv.hpp:1437
status put_size(std::uint64_t size) noexcept
Puts size to a config, it's required when creating new database pool.
Definition: libpmemkv.hpp:1488
config() noexcept
Default constructor with uninitialized config.
Definition: libpmemkv.hpp:1258
status get_object(const std::string &key, T *&value) const noexcept
Gets binary data from a config item with key name and assigns pointer to T object value.
Definition: libpmemkv.hpp:1604
status put_create_if_missing(bool value) noexcept
Puts create_if_missing parameter to a config.
Definition: libpmemkv.hpp:1543
status put_string(const std::string &key, const std::string &value) noexcept
Puts string value to a config.
Definition: libpmemkv.hpp:1471
int init() noexcept
Initialization function for config.
Definition: libpmemkv.hpp:1276
status get_int64(const std::string &key, std::int64_t &value) const noexcept
Gets std::int64_t value from a config item with key name.
Definition: libpmemkv.hpp:1641
status get_string(const std::string &key, std::string &value) const noexcept
Gets string value from a config item with key name.
Definition: libpmemkv.hpp:1659
status put_comparator(Comparator &&comparator)
Puts comparator object to a config.
Definition: libpmemkv.hpp:1380
pmemkv_config * release() noexcept
Similarly to std::unique_ptr::release it passes the ownership of underlying pmemkv_config variable an...
Definition: libpmemkv.hpp:1684
status put_oid(PMEMoid *oid) noexcept
Puts PMEMoid object to a config.
Definition: libpmemkv.hpp:1557
status put_object(const std::string &key, T *value, void(*deleter)(void *)) noexcept
Puts object pointed by value, of type T, with given destructor to a config.
Definition: libpmemkv.hpp:1320
status get_data(const std::string &key, T *&value, std::size_t &number) const noexcept
Gets object from a config item with key name and copies it into T object value.
Definition: libpmemkv.hpp:1576
status put_path(const std::string &path) noexcept
Puts path (of a database pool) to a config, to open or create.
Definition: libpmemkv.hpp:1501
status put_int64(const std::string &key, std::int64_t value) noexcept
Puts std::int64_t value to a config.
Definition: libpmemkv.hpp:1454
status get_uint64(const std::string &key, std::uint64_t &value) const noexcept
Gets std::uint64_t value from a config item with key name.
Definition: libpmemkv.hpp:1623
status put_data(const std::string &key, const T *value, const std::size_t number=1) noexcept
Puts binary data pointed by value, of type T, with count of elements to a config.
Definition: libpmemkv.hpp:1299
OutputIterator provides iteration through elements without a possibility of reading them....
Definition: libpmemkv.hpp:686
std::output_iterator_tag iterator_category
Definition: libpmemkv.hpp:694
assign_only ao
Definition: libpmemkv.hpp:724
void pointer
Definition: libpmemkv.hpp:691
void value_type
Definition: libpmemkv.hpp:693
std::ptrdiff_t difference_type
Definition: libpmemkv.hpp:692
Iterator provides methods to iterate over records in db.
Definition: libpmemkv.hpp:631
pmemkv_iterator * get_raw_it()
typename std::conditional< IsConst, pmemkv_iterator, pmemkv_write_iterator >::type iterator_type
Definition: libpmemkv.hpp:633
result< string_view > key() noexcept
Returns record's key (pmem::kv::string_view), in pmem::kv::result<pmem::kv::string_view>.
Definition: libpmemkv.hpp:1027
status prev() noexcept
Changes iterator position to the previous record.
Definition: libpmemkv.hpp:1012
std::enable_if<!IC, result< pmem::obj::slice< OutputIterator< char > > > >::type write_range(size_t pos=0, size_t n=std::numeric_limits< size_t >::max()) noexcept
status is_next() noexcept
Checks if there is a next record available.
Definition: libpmemkv.hpp:974
iterator(iterator_type *it)
status seek_higher_eq(string_view key) noexcept
Changes iterator position to the record with key equal or higher than given key.
Definition: libpmemkv.hpp:923
std::enable_if<!IC, status >::type commit() noexcept
status next() noexcept
Changes iterator position to the next record.
Definition: libpmemkv.hpp:993
status seek_to_last() noexcept
Changes iterator position to the last record.
Definition: libpmemkv.hpp:958
status seek_lower(string_view key) noexcept
Changes iterator position to the record with key lower than given key.
Definition: libpmemkv.hpp:863
std::unique_ptr< iterator_type, typename std::conditional< IsConst, decltype(&pmemkv_iterator_delete), decltype(&pmemkv_write_iterator_delete)>::type > it_
Definition: libpmemkv.hpp:675
result< string_view > read_range(size_t pos=0, size_t n=std::numeric_limits< size_t >::max()) noexcept
Returns value's range (pmem::kv::string_view) to read, in pmem::kv::result.
Definition: libpmemkv.hpp:1056
status seek_to_first() noexcept
Changes iterator position to the first record.
Definition: libpmemkv.hpp:941
status seek_lower_eq(string_view key) noexcept
Changes iterator position to the record with key equal or lower than given key.
Definition: libpmemkv.hpp:883
status seek_higher(string_view key) noexcept
Changes iterator position to the record with key higher than given key.
Definition: libpmemkv.hpp:903
std::enable_if<!IC >::type abort() noexcept
status seek(string_view key) noexcept
Changes iterator position to the record with given key.
Definition: libpmemkv.hpp:843
Main pmemkv class, it provides functions to operate on data in database.
Definition: libpmemkv.hpp:542
result< read_iterator > new_read_iterator()
Returns new read iterator in pmem::kv::result.
Definition: libpmemkv.hpp:2291
status count_all(std::size_t &cnt) noexcept
It returns number of currently stored elements in pmem::kv::db.
Definition: libpmemkv.hpp:1812
status exists(string_view key) noexcept
Checks existence of record with given key.
Definition: libpmemkv.hpp:2167
status defrag(double start_percent=0, double amount_percent=100)
Defragments approximately 'amount_percent' percent of elements in the database starting from 'start_p...
Definition: libpmemkv.hpp:2265
status open(const std::string &engine_name, config &&cfg=config{}) noexcept
Opens the pmemkv database with specified config.
Definition: libpmemkv.hpp:1787
status remove(string_view key) noexcept
Removes from database record with given key.
Definition: libpmemkv.hpp:2250
status put(string_view key, string_view value) noexcept
Inserts a key-value pair into pmemkv database.
Definition: libpmemkv.hpp:2236
status count_above(string_view key, std::size_t &cnt) noexcept
It returns number of currently stored elements in pmem::kv::db, whose keys are greater than the given...
Definition: libpmemkv.hpp:1827
status get_equal_above(string_view key, get_kv_callback *callback, void *arg) noexcept
Executes (C-like) callback function for every record stored in pmem::kv::db, whose keys are greater t...
Definition: libpmemkv.hpp:1993
db() noexcept
Default constructor with uninitialized database.
Definition: libpmemkv.hpp:1775
status get_all(get_kv_callback *callback, void *arg) noexcept
Executes (C-like) callback function for every record stored in pmem::kv::db.
Definition: libpmemkv.hpp:1912
result< tx > tx_begin() noexcept
Starts a pmemkv transaction.
Definition: libpmemkv.hpp:2328
status count_between(string_view key1, string_view key2, std::size_t &cnt) noexcept
It returns number of currently stored elements in pmem::kv::db, whose keys are greater than the key1 ...
Definition: libpmemkv.hpp:1892
std::string errormsg()
Returns a human readable string describing the last error.
Definition: libpmemkv.hpp:2308
status count_below(string_view key, std::size_t &cnt) noexcept
It returns number of currently stored elements in pmem::kv::db, whose keys are less than the given ke...
Definition: libpmemkv.hpp:1875
status get_equal_below(string_view key, get_kv_callback *callback, void *arg) noexcept
Executes (C-like) callback function for every record stored in pmem::kv::db, whose keys are lower tha...
Definition: libpmemkv.hpp:2039
status get_between(string_view key1, string_view key2, get_kv_callback *callback, void *arg) noexcept
Executes (C-like) callback function for every record stored in pmem::kv::db, whose keys are greater t...
Definition: libpmemkv.hpp:2128
void close() noexcept
Closes pmemkv database.
Definition: libpmemkv.hpp:1800
result< write_iterator > new_write_iterator()
Returns new write iterator in pmem::kv::result.
Definition: libpmemkv.hpp:2276
status get_above(string_view key, get_kv_callback *callback, void *arg) noexcept
Executes (C-like) callback function for every record stored in pmem::kv::db, whose keys are greater t...
Definition: libpmemkv.hpp:1949
std::unique_ptr< pmemkv_db, decltype(&pmemkv_close)> db_
Definition: libpmemkv.hpp:606
status get_below(string_view key, get_kv_callback *callback, void *arg) noexcept
Executes (C-like) callback function for every record stored in pmem::kv::db, whose keys are lower tha...
Definition: libpmemkv.hpp:2084
status count_equal_above(string_view key, std::size_t &cnt) noexcept
It returns number of currently stored elements in pmem::kv::db, whose keys are greater than or equal ...
Definition: libpmemkv.hpp:1843
status count_equal_below(string_view key, std::size_t &cnt) noexcept
It returns number of currently stored elements in pmem::kv::db, whose keys are lower than or equal to...
Definition: libpmemkv.hpp:1859
status get(string_view key, get_v_callback *callback, void *arg) noexcept
Executes (C-like) callback function for record with given key.
Definition: libpmemkv.hpp:2188
Definition: libpmemkv.hpp:1184
virtual ~comparator_base()
Definition: libpmemkv.hpp:1186
virtual int compare(string_view key1, string_view key2)=0
Stores result of an operation. It always contains status and optionally can contain value.
Definition: libpmemkv.hpp:175
bool is_ok() const noexcept
Checks if the result contains value (status == status::OK).
Definition: libpmemkv.hpp:328
result(const T &val) noexcept(noexcept(T(std::declval< T >())))
Creates result with value (status is automatically initialized to status::OK).
Definition: libpmemkv.hpp:213
const T & get_value() const &
Returns const reference to value from the result.
Definition: libpmemkv.hpp:343
status s
Definition: libpmemkv.hpp:180
T value
Definition: libpmemkv.hpp:177
status get_status() const noexcept
Returns status from the result.
Definition: libpmemkv.hpp:397
result & operator=(const result &other) noexcept(noexcept(std::declval< T >().~T()) &&noexcept(T(std::declval< T >())))
Default copy assignment operator.
Definition: libpmemkv.hpp:273
~result()
Explicit destructor.
Definition: libpmemkv.hpp:260
Pmemkv transaction handle.
Definition: libpmemkv.hpp:508
void abort() noexcept
Aborts the transaction.
Definition: libpmemkv.hpp:1741
tx(pmemkv_tx *tx_) noexcept
Constructs C++ tx object from a C pmemkv_tx pointer.
Definition: libpmemkv.hpp:1692
status put(string_view key, string_view value) noexcept
Inserts a key-value pair into pmemkv database.
Definition: libpmemkv.hpp:1719
status commit() noexcept
Commits the transaction.
Definition: libpmemkv.hpp:1732
status remove(string_view key) noexcept
Removes from database record with given key.
Definition: libpmemkv.hpp:1705
std::unique_ptr< pmemkv_tx, decltype(&pmemkv_tx_end)> tx_
Definition: libpmemkv.hpp:518
#define force_create_deprecated
Definition: libpmemkv.hpp:446
pmemkv_get_v_callback get_v_callback
Value-only callback, C-style.
Definition: libpmemkv.hpp:71
void get_v_function(string_view value)
The C++ idiomatic function type to use for callback using only the value.
Definition: libpmemkv.hpp:62
bool operator==(const result< T > &lhs, const status &rhs)
Definition: libpmemkv.hpp:403
status
Status returned by most of pmemkv functions.
Definition: libpmemkv.hpp:84
@ DEFRAG_ERROR
the defragmentation process failed (possibly in the middle of a run)
@ STOPPED_BY_CB
iteration was stopped by user's callback
@ CONFIG_TYPE_ERROR
config item has different type than expected
@ WRONG_ENGINE_NAME
engine name does not match any available engine
@ NOT_SUPPORTED
function is not implemented by current engine
@ TRANSACTION_SCOPE_ERROR
an error with the scope of the libpmemobj transaction
@ COMPARATOR_MISMATCH
db was created with a different comparator
@ NOT_FOUND
record (or config item) not found
@ UNKNOWN_ERROR
unknown error
@ CONFIG_PARSING_ERROR
parsing data to config failed
@ OUT_OF_MEMORY
operation failed because there is not enough memory (or space on the device)
@ INVALID_ARGUMENT
argument to function has wrong value
pmemkv_get_kv_callback get_kv_callback
Key-value pair callback, C-style.
Definition: libpmemkv.hpp:67
obj::string_view string_view
Partial string_view implementation, defined in pmem::obj namespace in libpmemobj-cpp library (see: ht...
Definition: libpmemkv.hpp:47
bool operator!=(const result< T > &lhs, const status &rhs)
Definition: libpmemkv.hpp:415
std::ostream & operator<<(std::ostream &os, const status &s)
Provides string representation of a status, along with its number as specified by enum.
Definition: libpmemkv.hpp:124
int get_kv_function(string_view key, string_view value)
The C++ idiomatic function type to use for callback using key-value pair.
Definition: libpmemkv.hpp:55
bool operator!=(const status &lhs, const result< T > &rhs)
Definition: libpmemkv.hpp:421
Persistent memory namespace.
Definition: libpmemkv.hpp:1210
std::unique_ptr< comparator_base > ptr
Definition: libpmemkv.hpp:1224
void * get() override
Definition: libpmemkv.hpp:1219
comparator_config_entry(std::unique_ptr< comparator_base > ptr, std::unique_ptr< pmemkv_comparator, decltype(pmemkv_comparator_delete) * > c_cmp)
Definition: libpmemkv.hpp:1211
std::unique_ptr< pmemkv_comparator, decltype(pmemkv_comparator_delete) * > c_cmp
Definition: libpmemkv.hpp:1225
Definition: libpmemkv.hpp:1193
int compare(string_view key1, string_view key2) override
Definition: libpmemkv.hpp:1202
comparator_wrapper(Comparator &&cmp)
Definition: libpmemkv.hpp:1198
comparator_wrapper(const Comparator &cmp)
Definition: libpmemkv.hpp:1194
Comparator cmp
Definition: libpmemkv.hpp:1207
Definition: libpmemkv.hpp:1162
virtual ~unique_ptr_wrapper_base()
Definition: libpmemkv.hpp:1163
Definition: libpmemkv.hpp:1171
unique_ptr_wrapper(std::unique_ptr< T, D > ptr)
Definition: libpmemkv.hpp:1172
void * get() override
Definition: libpmemkv.hpp:1176
std::unique_ptr< T, D > ptr
Definition: libpmemkv.hpp:1181