13 #if __cpp_lib_string_view
14 #include <string_view>
17 #include "libpmemkv.h"
43 #if __cpp_lib_string_view
44 using string_view = std::string_view;
62 const char *
data() const noexcept;
63 std::
size_t size() const noexcept;
106 OK = PMEMKV_STATUS_OK,
107 UNKNOWN_ERROR = PMEMKV_STATUS_UNKNOWN_ERROR,
108 NOT_FOUND = PMEMKV_STATUS_NOT_FOUND,
109 NOT_SUPPORTED = PMEMKV_STATUS_NOT_SUPPORTED,
111 INVALID_ARGUMENT = PMEMKV_STATUS_INVALID_ARGUMENT,
113 CONFIG_PARSING_ERROR =
114 PMEMKV_STATUS_CONFIG_PARSING_ERROR,
116 PMEMKV_STATUS_CONFIG_TYPE_ERROR,
118 STOPPED_BY_CB = PMEMKV_STATUS_STOPPED_BY_CB,
121 PMEMKV_STATUS_OUT_OF_MEMORY,
124 PMEMKV_STATUS_WRONG_ENGINE_NAME,
126 TRANSACTION_SCOPE_ERROR =
127 PMEMKV_STATUS_TRANSACTION_SCOPE_ERROR,
129 DEFRAG_ERROR = PMEMKV_STATUS_DEFRAG_ERROR,
132 PMEMKV_STATUS_COMPARATOR_MISMATCH,
158 explicit config(pmemkv_config *cfg) noexcept;
168 template <
typename Comparator>
169 status put_comparator(Comparator &&comparator);
171 template <
typename T>
172 status put_data(
const std::string &key,
const T *value,
173 const std::size_t number = 1) noexcept;
175 template <typename T>
176 status put_object(const std::
string &key, T *value,
177 void (*deleter)(
void *)) noexcept;
178 template <typename T, typename D>
179 status put_object(const std::
string &key, std::unique_ptr<T, D>
object) noexcept;
180 status put_uint64(const std::
string &key, std::uint64_t value) noexcept;
181 status put_int64(const std::
string &key, std::int64_t value) noexcept;
182 status put_string(const std::
string &key, const std::
string &value) noexcept;
184 template <typename T>
185 status get_data(const std::
string &key, T *&value, std::
size_t &number) const
187 template <typename T>
188 status get_object(const std::
string &key, T *&value) const noexcept;
190 status get_uint64(const std::
string &key, std::uint64_t &value) const noexcept;
191 status get_int64(const std::
string &key, std::int64_t &value) const noexcept;
192 status get_string(const std::
string &key, std::
string &value) const noexcept;
194 pmemkv_config *release() noexcept;
199 pmemkv_config *_config;
220 db(
db &&other) noexcept;
225 status open(
const std::string &engine_name) noexcept;
226 status open(
const std::string &engine_name,
config &&cfg) noexcept;
228 void close() noexcept;
230 status count_all(std::
size_t &cnt) noexcept;
236 std::
size_t &cnt) noexcept;
270 status defrag(
double start_percent = 0,
double amount_percent = 100);
272 std::
string errormsg();
301 template <
typename T,
typename D>
312 std::unique_ptr<T, D>
ptr;
323 template <
typename Comparator>
335 return cmp.compare(key1, key2);
343 std::unique_ptr<comparator_base> ptr,
344 std::unique_ptr<pmemkv_comparator, decltype(pmemkv_comparator_delete) *>
346 : ptr(std::move(ptr)), c_cmp(std::move(c_cmp))
355 std::unique_ptr<comparator_base>
ptr;
356 std::unique_ptr<pmemkv_comparator, decltype(pmemkv_comparator_delete) *>
c_cmp;
365 static inline void call_up_destructor(
void *
object)
371 static inline void *call_up_get(
void *
object)
373 auto *ptr =
static_cast<unique_ptr_wrapper_base *
>(object);
377 static inline int call_comparator_function(
const char *k1,
size_t kb1,
const char *k2,
378 size_t kb2,
void *arg)
380 auto *cmp =
static_cast<comparator_base *
>(arg);
391 this->_config =
nullptr;
400 this->_config = other._config;
401 other._config =
nullptr;
414 pmemkv_config_delete(this->_config);
416 this->_config = other._config;
417 other._config =
nullptr;
437 pmemkv_config_delete(this->_config);
448 if (this->_config ==
nullptr) {
449 this->_config = pmemkv_config_new();
451 if (this->_config ==
nullptr)
468 template <
typename T>
470 const std::size_t count) noexcept
473 return status::UNKNOWN_ERROR;
475 return static_cast<status>(pmemkv_config_put_data(
476 this->_config, key.data(), (
void *)value, count *
sizeof(T)));
489 template <
typename T>
491 void (*deleter)(
void *)) noexcept
494 return status::UNKNOWN_ERROR;
496 return static_cast<status>(pmemkv_config_put_object(this->_config, key.data(),
497 (
void *)value, deleter));
508 template <
typename T,
typename D>
510 std::unique_ptr<T, D>
object) noexcept
513 return status::UNKNOWN_ERROR;
519 }
catch (std::bad_alloc &e) {
520 return status::OUT_OF_MEMORY;
522 return status::UNKNOWN_ERROR;
525 return static_cast<status>(pmemkv_config_put_object_cb(
526 this->_config, key.data(), (
void *)wrapper, internal::call_up_get,
527 internal::call_up_destructor));
546 template <
typename Comparator>
550 std::is_same<decltype(std::declval<Comparator>().
compare(
551 std::declval<string_view>(),
552 std::declval<string_view>())),
554 "Comparator should implement `int compare(pmem::kv::string_view, pmem::kv::string_view)` method");
555 static_assert(std::is_convertible<decltype(std::declval<Comparator>().name()),
557 "Comparator should implement `std::string name()` method");
559 std::unique_ptr<internal::comparator_base> wrapper;
562 wrapper = std::unique_ptr<internal::comparator_base>(
564 std::forward<Comparator>(comparator)));
565 }
catch (std::bad_alloc &e) {
566 return status::OUT_OF_MEMORY;
568 return status::UNKNOWN_ERROR;
572 std::unique_ptr<pmemkv_comparator, decltype(pmemkv_comparator_delete) *>(
573 pmemkv_comparator_new(&internal::call_comparator_function,
574 std::string(comparator.name()).c_str(),
576 &pmemkv_comparator_delete);
578 return status::UNKNOWN_ERROR;
585 }
catch (std::bad_alloc &e) {
586 return status::OUT_OF_MEMORY;
588 return status::UNKNOWN_ERROR;
591 return static_cast<status>(pmemkv_config_put_object_cb(
592 this->_config,
"comparator", (
void *)entry, internal::call_up_get,
593 internal::call_up_destructor));
607 return status::UNKNOWN_ERROR;
609 return static_cast<status>(
610 pmemkv_config_put_uint64(this->_config, key.data(), value));
624 return status::UNKNOWN_ERROR;
626 return static_cast<status>(
627 pmemkv_config_put_int64(this->_config, key.data(), value));
639 const std::string &value) noexcept
642 return status::UNKNOWN_ERROR;
644 return static_cast<status>(
645 pmemkv_config_put_string(this->_config, key.data(), value.data()));
658 template <
typename T>
660 std::size_t &count)
const noexcept
662 if (this->_config ==
nullptr)
663 return status::NOT_FOUND;
666 auto s =
static_cast<status>(pmemkv_config_get_data(
667 this->_config, key.data(), (
const void **)&value, &
size));
672 count =
size /
sizeof(T);
686 template <
typename T>
689 if (this->_config ==
nullptr)
690 return status::NOT_FOUND;
692 auto s =
static_cast<status>(
693 pmemkv_config_get_object(this->_config, key.data(), (
void **)&value));
709 if (this->_config ==
nullptr)
710 return status::NOT_FOUND;
712 return static_cast<status>(
713 pmemkv_config_get_uint64(this->_config, key.data(), &value));
727 if (this->_config ==
nullptr)
728 return status::NOT_FOUND;
730 return static_cast<status>(
731 pmemkv_config_get_int64(this->_config, key.data(), &value));
745 if (this->_config ==
nullptr)
746 return status::NOT_FOUND;
750 auto s =
static_cast<status>(
751 pmemkv_config_get_string(this->_config, key.data(), &
data));
769 auto c = this->_config;
770 this->_config =
nullptr;
774 #if !__cpp_lib_string_view
810 : _data(data), _size(std::char_traits<char>::length(data))
845 int ret = std::char_traits<char>::compare(data(), other.data(),
846 std::min(size(), other.size()));
849 if (size() < other.size())
851 if (size() > other.size())
863 static inline int call_get_kv_function(
const char *key,
size_t keybytes,
864 const char *value,
size_t valuebytes,
void *arg)
866 return (*
reinterpret_cast<std::function<get_kv_function> *
>(arg))(
870 static inline void call_get_v_function(
const char *value,
size_t valuebytes,
void *arg)
872 (*
reinterpret_cast<std::function<get_v_function> *
>(arg))(
873 string_view(value, valuebytes));
876 static inline void call_get_copy(
const char *v,
size_t vb,
void *arg)
878 auto c =
reinterpret_cast<std::string *
>(arg);
899 this->_db = other._db;
917 std::swap(this->_db, other._db);
931 return static_cast<status>(
932 pmemkv_open(engine_name.c_str(),
nullptr, &(this->_db)));
945 return static_cast<status>(
946 pmemkv_open(engine_name.c_str(), cfg.release(), &(this->_db)));
954 if (this->_db !=
nullptr)
955 pmemkv_close(this->_db);
977 return static_cast<status>(pmemkv_count_all(this->_db, &cnt));
992 return static_cast<status>(
993 pmemkv_count_above(this->_db, key.data(), key.size(), &cnt));
1008 return static_cast<status>(
1009 pmemkv_count_equal_above(this->_db, key.data(), key.size(), &cnt));
1024 return static_cast<status>(
1025 pmemkv_count_equal_below(this->_db, key.data(), key.size(), &cnt));
1040 return static_cast<status>(
1041 pmemkv_count_below(this->_db, key.data(), key.size(), &cnt));
1056 std::size_t &cnt) noexcept
1058 return static_cast<status>(pmemkv_count_between(
1059 this->_db, key1.data(), key1.size(), key2.data(), key2.size(), &cnt));
1076 return static_cast<status>(pmemkv_get_all(this->_db, callback, arg));
1091 return static_cast<status>(pmemkv_get_all(this->_db, call_get_kv_function, &f));
1113 return static_cast<status>(
1114 pmemkv_get_above(this->_db, key.data(), key.size(), callback, arg));
1133 return static_cast<status>(pmemkv_get_above(this->_db, key.data(), key.size(),
1134 call_get_kv_function, &f));
1157 return static_cast<status>(
1158 pmemkv_get_equal_above(this->_db, key.data(), key.size(), callback, arg));
1177 std::function<get_kv_function> f) noexcept
1179 return static_cast<status>(pmemkv_get_equal_above(
1180 this->_db, key.data(), key.size(), call_get_kv_function, &f));
1203 return static_cast<status>(
1204 pmemkv_get_equal_below(this->_db, key.data(), key.size(), callback, arg));
1223 std::function<get_kv_function> f) noexcept
1225 return static_cast<status>(pmemkv_get_equal_below(
1226 this->_db, key.data(), key.size(), call_get_kv_function, &f));
1248 return static_cast<status>(
1249 pmemkv_get_below(this->_db, key.data(), key.size(), callback, arg));
1268 return static_cast<status>(pmemkv_get_below(this->_db, key.data(), key.size(),
1269 call_get_kv_function, &f));
1292 return static_cast<status>(pmemkv_get_between(this->_db, key1.data(), key1.size(),
1293 key2.data(), key2.size(), callback,
1312 std::function<get_kv_function> f) noexcept
1314 return static_cast<status>(pmemkv_get_between(this->_db, key1.data(), key1.size(),
1315 key2.data(), key2.size(),
1316 call_get_kv_function, &f));
1330 return static_cast<status>(pmemkv_exists(this->_db, key.data(), key.size()));
1350 return static_cast<status>(
1351 pmemkv_get(this->_db, key.data(), key.size(), callback, arg));
1367 return static_cast<status>(
1368 pmemkv_get(this->_db, key.data(), key.size(), call_get_v_function, &f));
1383 return static_cast<status>(
1384 pmemkv_get(this->_db, key.data(), key.size(), call_get_copy, value));
1398 return static_cast<status>(pmemkv_put(this->_db, key.data(), key.size(),
1399 value.data(), value.size()));
1412 return static_cast<status>(pmemkv_remove(this->_db, key.data(), key.size()));
1427 return static_cast<status>(
1428 pmemkv_defrag(this->_db, start_percent, amount_percent));
1440 return std::string(pmemkv_errormsg());
1448 static inline std::string errormsg()
1450 return std::string(pmemkv_errormsg());