9 #include <libpmemobj++/string_view.hpp>
15 #include "libpmemkv.h"
16 #include <libpmemobj/pool_base.h>
77 OK = PMEMKV_STATUS_OK,
78 UNKNOWN_ERROR = PMEMKV_STATUS_UNKNOWN_ERROR,
79 NOT_FOUND = PMEMKV_STATUS_NOT_FOUND,
80 NOT_SUPPORTED = PMEMKV_STATUS_NOT_SUPPORTED,
82 INVALID_ARGUMENT = PMEMKV_STATUS_INVALID_ARGUMENT,
84 CONFIG_PARSING_ERROR =
85 PMEMKV_STATUS_CONFIG_PARSING_ERROR,
87 PMEMKV_STATUS_CONFIG_TYPE_ERROR,
89 STOPPED_BY_CB = PMEMKV_STATUS_STOPPED_BY_CB,
92 PMEMKV_STATUS_OUT_OF_MEMORY,
95 PMEMKV_STATUS_WRONG_ENGINE_NAME,
97 TRANSACTION_SCOPE_ERROR =
98 PMEMKV_STATUS_TRANSACTION_SCOPE_ERROR,
100 DEFRAG_ERROR = PMEMKV_STATUS_DEFRAG_ERROR,
103 PMEMKV_STATUS_COMPARATOR_MISMATCH,
109 static const std::string statuses[] = {
"OK",
114 "CONFIG_PARSING_ERROR",
119 "TRANSACTION_SCOPE_ERROR",
121 "COMPARATOR_MISMATCH"};
123 int status_no =
static_cast<int>(s);
124 os << statuses[status_no] <<
" (" << status_no <<
")";
151 explicit config(pmemkv_config *cfg) noexcept;
161 template <
typename T>
163 const std::size_t number = 1) noexcept;
165 template <typename T>
167 void (*deleter)(
void *)) noexcept;
168 template <typename T, typename D>
169 status put_object(const std::
string &key, std::unique_ptr<T, D>
object) noexcept;
172 status put_string(const std::
string &key, const std::
string &value) noexcept;
178 template <typename Comparator>
181 template <typename T>
182 status get_data(const std::
string &key, T *&value, std::
size_t &number) const
184 template <typename T>
187 status get_uint64(const std::
string &key, std::uint64_t &value) const noexcept;
188 status get_int64(const std::
string &key, std::int64_t &value) const noexcept;
189 status get_string(const std::
string &key, std::
string &value) const noexcept;
191 pmemkv_config *
release() noexcept;
217 db(
db &&other) noexcept;
222 status open(
const std::string &engine_name) noexcept;
223 status open(
const std::string &engine_name,
config &&cfg) noexcept;
225 void close() noexcept;
227 status count_all(std::
size_t &cnt) noexcept;
233 std::
size_t &cnt) noexcept;
267 status defrag(
double start_percent = 0,
double amount_percent = 100);
269 std::
string errormsg();
298 template <
typename T,
typename D>
309 std::unique_ptr<T, D>
ptr;
320 template <
typename Comparator>
332 return cmp.compare(key1, key2);
340 std::unique_ptr<comparator_base> ptr,
341 std::unique_ptr<pmemkv_comparator, decltype(pmemkv_comparator_delete) *>
343 : ptr(std::move(ptr)), c_cmp(std::move(c_cmp))
352 std::unique_ptr<comparator_base>
ptr;
353 std::unique_ptr<pmemkv_comparator, decltype(pmemkv_comparator_delete) *>
c_cmp;
362 static inline void call_up_destructor(
void *
object)
368 static inline void *call_up_get(
void *
object)
370 auto *ptr =
static_cast<unique_ptr_wrapper_base *
>(object);
374 static inline int call_comparator_function(
const char *k1,
size_t kb1,
const char *k2,
375 size_t kb2,
void *arg)
377 auto *cmp =
static_cast<comparator_base *
>(arg);
388 this->_config =
nullptr;
397 this->_config = other._config;
398 other._config =
nullptr;
411 pmemkv_config_delete(this->_config);
413 this->_config = other._config;
414 other._config =
nullptr;
434 pmemkv_config_delete(this->_config);
445 if (this->_config ==
nullptr) {
446 this->_config = pmemkv_config_new();
448 if (this->_config ==
nullptr)
465 template <
typename T>
467 const std::size_t count) noexcept
470 return status::UNKNOWN_ERROR;
472 return static_cast<status>(pmemkv_config_put_data(
473 this->_config, key.data(), (
void *)value, count *
sizeof(T)));
486 template <
typename T>
488 void (*deleter)(
void *)) noexcept
491 return status::UNKNOWN_ERROR;
493 return static_cast<status>(pmemkv_config_put_object(this->_config, key.data(),
494 (
void *)value, deleter));
505 template <
typename T,
typename D>
507 std::unique_ptr<T, D>
object) noexcept
510 return status::UNKNOWN_ERROR;
516 }
catch (std::bad_alloc &e) {
517 return status::OUT_OF_MEMORY;
519 return status::UNKNOWN_ERROR;
522 return static_cast<status>(pmemkv_config_put_object_cb(
523 this->_config, key.data(), (
void *)wrapper, internal::call_up_get,
524 internal::call_up_destructor));
543 template <
typename Comparator>
547 std::is_same<decltype(std::declval<Comparator>().compare(
548 std::declval<string_view>(),
549 std::declval<string_view>())),
551 "Comparator should implement `int compare(pmem::kv::string_view, pmem::kv::string_view)` method");
552 static_assert(std::is_convertible<decltype(std::declval<Comparator>().name()),
554 "Comparator should implement `std::string name()` method");
556 std::unique_ptr<internal::comparator_base> wrapper;
559 wrapper = std::unique_ptr<internal::comparator_base>(
561 std::forward<Comparator>(comparator)));
562 }
catch (std::bad_alloc &e) {
563 return status::OUT_OF_MEMORY;
565 return status::UNKNOWN_ERROR;
569 std::unique_ptr<pmemkv_comparator, decltype(pmemkv_comparator_delete) *>(
570 pmemkv_comparator_new(&internal::call_comparator_function,
571 std::string(comparator.name()).c_str(),
573 &pmemkv_comparator_delete);
575 return status::UNKNOWN_ERROR;
582 }
catch (std::bad_alloc &e) {
583 return status::OUT_OF_MEMORY;
585 return status::UNKNOWN_ERROR;
588 return static_cast<status>(pmemkv_config_put_object_cb(
589 this->_config,
"comparator", (
void *)entry, internal::call_up_get,
590 internal::call_up_destructor));
604 return status::UNKNOWN_ERROR;
606 return static_cast<status>(
607 pmemkv_config_put_uint64(this->_config, key.data(), value));
621 return status::UNKNOWN_ERROR;
623 return static_cast<status>(
624 pmemkv_config_put_int64(this->_config, key.data(), value));
636 const std::string &value) noexcept
639 return status::UNKNOWN_ERROR;
641 return static_cast<status>(
642 pmemkv_config_put_string(this->_config, key.data(), value.data()));
679 return put_uint64(
"force_create", value ? 1 : 0);
694 return status::UNKNOWN_ERROR;
696 return static_cast<status>(pmemkv_config_put_oid(this->_config, oid));
709 template <
typename T>
711 std::size_t &count)
const noexcept
713 if (this->_config ==
nullptr)
714 return status::NOT_FOUND;
717 auto s =
static_cast<status>(pmemkv_config_get_data(
718 this->_config, key.data(), (
const void **)&value, &size));
723 count = size /
sizeof(T);
737 template <
typename T>
740 if (this->_config ==
nullptr)
741 return status::NOT_FOUND;
743 auto s =
static_cast<status>(
744 pmemkv_config_get_object(this->_config, key.data(), (
void **)&value));
760 if (this->_config ==
nullptr)
761 return status::NOT_FOUND;
763 return static_cast<status>(
764 pmemkv_config_get_uint64(this->_config, key.data(), &value));
778 if (this->_config ==
nullptr)
779 return status::NOT_FOUND;
781 return static_cast<status>(
782 pmemkv_config_get_int64(this->_config, key.data(), &value));
796 if (this->_config ==
nullptr)
797 return status::NOT_FOUND;
801 auto s =
static_cast<status>(
802 pmemkv_config_get_string(this->_config, key.data(), &data));
821 this->_config =
nullptr;
831 static inline int call_get_kv_function(
const char *key,
size_t keybytes,
832 const char *value,
size_t valuebytes,
void *arg)
834 return (*
reinterpret_cast<std::function<get_kv_function> *
>(arg))(
838 static inline void call_get_v_function(
const char *value,
size_t valuebytes,
void *arg)
840 (*
reinterpret_cast<std::function<get_v_function> *
>(arg))(
844 static inline void call_get_copy(
const char *v,
size_t vb,
void *arg)
846 auto c =
reinterpret_cast<std::string *
>(arg);
867 this->_db = other._db;
885 std::swap(this->_db, other._db);
899 return static_cast<status>(
900 pmemkv_open(engine_name.c_str(),
nullptr, &(this->_db)));
913 return static_cast<status>(
914 pmemkv_open(engine_name.c_str(), cfg.release(), &(this->_db)));
922 if (this->_db !=
nullptr)
923 pmemkv_close(this->_db);
945 return static_cast<status>(pmemkv_count_all(this->_db, &cnt));
960 return static_cast<status>(
961 pmemkv_count_above(this->_db, key.data(), key.size(), &cnt));
976 return static_cast<status>(
977 pmemkv_count_equal_above(this->_db, key.data(), key.size(), &cnt));
992 return static_cast<status>(
993 pmemkv_count_equal_below(this->_db, key.data(), key.size(), &cnt));
1008 return static_cast<status>(
1009 pmemkv_count_below(this->_db, key.data(), key.size(), &cnt));
1024 std::size_t &cnt) noexcept
1026 return static_cast<status>(pmemkv_count_between(
1027 this->_db, key1.data(), key1.size(), key2.data(), key2.size(), &cnt));
1044 return static_cast<status>(pmemkv_get_all(this->_db, callback, arg));
1059 return static_cast<status>(pmemkv_get_all(this->_db, call_get_kv_function, &f));
1081 return static_cast<status>(
1082 pmemkv_get_above(this->_db, key.data(), key.size(), callback, arg));
1101 return static_cast<status>(pmemkv_get_above(this->_db, key.data(), key.size(),
1102 call_get_kv_function, &f));
1125 return static_cast<status>(
1126 pmemkv_get_equal_above(this->_db, key.data(), key.size(), callback, arg));
1145 std::function<get_kv_function> f) noexcept
1147 return static_cast<status>(pmemkv_get_equal_above(
1148 this->_db, key.data(), key.size(), call_get_kv_function, &f));
1171 return static_cast<status>(
1172 pmemkv_get_equal_below(this->_db, key.data(), key.size(), callback, arg));
1191 std::function<get_kv_function> f) noexcept
1193 return static_cast<status>(pmemkv_get_equal_below(
1194 this->_db, key.data(), key.size(), call_get_kv_function, &f));
1216 return static_cast<status>(
1217 pmemkv_get_below(this->_db, key.data(), key.size(), callback, arg));
1236 return static_cast<status>(pmemkv_get_below(this->_db, key.data(), key.size(),
1237 call_get_kv_function, &f));
1260 return static_cast<status>(pmemkv_get_between(this->_db, key1.data(), key1.size(),
1261 key2.data(), key2.size(), callback,
1280 std::function<get_kv_function> f) noexcept
1282 return static_cast<status>(pmemkv_get_between(this->_db, key1.data(), key1.size(),
1283 key2.data(), key2.size(),
1284 call_get_kv_function, &f));
1298 return static_cast<status>(pmemkv_exists(this->_db, key.data(), key.size()));
1318 return static_cast<status>(
1319 pmemkv_get(this->_db, key.data(), key.size(), callback, arg));
1335 return static_cast<status>(
1336 pmemkv_get(this->_db, key.data(), key.size(), call_get_v_function, &f));
1351 return static_cast<status>(
1352 pmemkv_get(this->_db, key.data(), key.size(), call_get_copy, value));
1366 return static_cast<status>(pmemkv_put(this->_db, key.data(), key.size(),
1367 value.data(), value.size()));
1380 return static_cast<status>(pmemkv_remove(this->_db, key.data(), key.size()));
1395 return static_cast<status>(
1396 pmemkv_defrag(this->_db, start_percent, amount_percent));
1408 return std::string(pmemkv_errormsg());
1416 static inline std::string errormsg()
1418 return std::string(pmemkv_errormsg());