PMDK C++ bindings  1.9
This is the C++ bindings documentation for PMDK's libpmemobj.
pool.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2016-2020, Intel Corporation
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  *
16  * * Neither the name of the copyright holder nor the names of its
17  * contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
38 #ifndef LIBPMEMOBJ_CPP_POOL_HPP
39 #define LIBPMEMOBJ_CPP_POOL_HPP
40 
41 #include <cstddef>
42 #include <functional>
43 #include <mutex>
44 #include <string>
45 #include <sys/stat.h>
46 #include <typeindex>
47 #include <unordered_map>
48 #include <vector>
49 
53 #include <libpmemobj++/p.hpp>
56 #include <libpmemobj/atomic_base.h>
57 #include <libpmemobj/pool_base.h>
58 
59 namespace pmem
60 {
61 
62 namespace obj
63 {
64 template <typename T>
65 class persistent_ptr;
66 
75 class pool_base {
76 public:
80  pool_base() noexcept : pop(nullptr)
81  {
82  }
83 
91  explicit pool_base(pmemobjpool *cpop) noexcept : pop(cpop)
92  {
93  }
94 
98  pool_base(const pool_base &) noexcept = default;
99 
103  pool_base(pool_base &&) noexcept = default;
104 
108  pool_base &operator=(const pool_base &) noexcept = default;
109 
113  pool_base &operator=(pool_base &&) noexcept = default;
114 
118  virtual ~pool_base() noexcept = default;
119 
132  static pool_base
133  open(const std::string &path, const std::string &layout)
134  {
135 #ifdef _WIN32
136  pmemobjpool *pop = pmemobj_openU(path.c_str(), layout.c_str());
137 #else
138  pmemobjpool *pop = pmemobj_open(path.c_str(), layout.c_str());
139 #endif
140  if (pop == nullptr)
141  throw pmem::pool_error("Failed opening pool")
142  .with_pmemobj_errormsg();
143 
144  pmemobj_set_user_data(pop, new detail::pool_data);
145 
146  return pool_base(pop);
147  }
148 
165  static pool_base
166  create(const std::string &path, const std::string &layout,
167  std::size_t size = PMEMOBJ_MIN_POOL, mode_t mode = DEFAULT_MODE)
168  {
169 #ifdef _WIN32
170  pmemobjpool *pop = pmemobj_createU(path.c_str(), layout.c_str(),
171  size, mode);
172 #else
173  pmemobjpool *pop = pmemobj_create(path.c_str(), layout.c_str(),
174  size, mode);
175 #endif
176  if (pop == nullptr)
177  throw pmem::pool_error("Failed creating pool")
178  .with_pmemobj_errormsg();
179 
180  pmemobj_set_user_data(pop, new detail::pool_data);
181 
182  return pool_base(pop);
183  }
184 
195  static int
196  check(const std::string &path, const std::string &layout) noexcept
197  {
198 #ifdef _WIN32
199  return pmemobj_checkU(path.c_str(), layout.c_str());
200 #else
201  return pmemobj_check(path.c_str(), layout.c_str());
202 #endif
203  }
204 
205 #ifdef _WIN32
206 
219  static pool_base
220  open(const std::wstring &path, const std::wstring &layout)
221  {
222  pmemobjpool *pop = pmemobj_openW(path.c_str(), layout.c_str());
223  if (pop == nullptr)
224  throw pmem::pool_error("Failed opening pool")
225  .with_pmemobj_errormsg();
226 
227  pmemobj_set_user_data(pop, new detail::pool_data);
228 
229  return pool_base(pop);
230  }
231 
249  static pool_base
250  create(const std::wstring &path, const std::wstring &layout,
251  std::size_t size = PMEMOBJ_MIN_POOL, mode_t mode = DEFAULT_MODE)
252  {
253  pmemobjpool *pop = pmemobj_createW(path.c_str(), layout.c_str(),
254  size, mode);
255  if (pop == nullptr)
256  throw pmem::pool_error("Failed creating pool")
257  .with_pmemobj_errormsg();
258 
259  pmemobj_set_user_data(pop, new detail::pool_data);
260 
261  return pool_base(pop);
262  }
263 
275  static int
276  check(const std::wstring &path, const std::wstring &layout) noexcept
277  {
278  return pmemobj_checkW(path.c_str(), layout.c_str());
279  }
280 #endif
281 
287  void
289  {
290  if (this->pop == nullptr)
291  throw std::logic_error("Pool already closed");
292 
293  auto *user_data = static_cast<detail::pool_data *>(
294  pmemobj_get_user_data(this->pop));
295 
296  if (user_data->initialized.load())
297  user_data->cleanup();
298 
299  delete user_data;
300 
301  pmemobj_close(this->pop);
302  this->pop = nullptr;
303  }
304 
311  void
312  persist(const void *addr, size_t len) noexcept
313  {
314  pmemobj_persist(this->pop, addr, len);
315  }
316 
322  template <typename Y>
323  void
324  persist(const p<Y> &prop) noexcept
325  {
326  pmemobj_persist(this->pop, &prop, sizeof(Y));
327  }
328 
335  template <typename Y>
336  void
337  persist(const persistent_ptr<Y> &ptr) noexcept
338  {
339  pmemobj_persist(this->pop, &ptr, sizeof(ptr));
340  }
341 
348  void
349  flush(const void *addr, size_t len) noexcept
350  {
351  pmemobj_flush(this->pop, addr, len);
352  }
353 
359  template <typename Y>
360  void
361  flush(const p<Y> &prop) noexcept
362  {
363  pmemobj_flush(this->pop, &prop, sizeof(Y));
364  }
365 
371  template <typename Y>
372  void
373  flush(const persistent_ptr<Y> &ptr) noexcept
374  {
375  pmemobj_flush(this->pop, &ptr, sizeof(ptr));
376  }
377 
381  void
382  drain(void) noexcept
383  {
384  pmemobj_drain(this->pop);
385  }
386 
397  void *
398  memcpy_persist(void *dest, const void *src, size_t len) noexcept
399  {
400  return pmemobj_memcpy_persist(this->pop, dest, src, len);
401  }
402 
413  void *
414  memset_persist(void *dest, int c, size_t len) noexcept
415  {
416  return pmemobj_memset_persist(this->pop, dest, c, len);
417  }
418 
426  PMEMobjpool *
427  handle() noexcept
428  {
429  return this->pop;
430  }
431 
432  POBJ_CPP_DEPRECATED PMEMobjpool *
433  get_handle() noexcept
434  {
435  return pool_base::handle();
436  }
437 
451  pobj_defrag_result
452  defrag(persistent_ptr_base **ptrv, size_t oidcnt)
453  {
454  pobj_defrag_result result;
455  int ret = pmemobj_defrag(this->pop, (PMEMoid **)ptrv, oidcnt,
456  &result);
457 
458  if (ret != 0)
459  throw defrag_error(result, "Defragmentation failed")
460  .with_pmemobj_errormsg();
461 
462  return result;
463  }
464 
465 protected:
466  /* The pool opaque handle */
467  PMEMobjpool *pop;
468 
469 #ifndef _WIN32
470  /* Default create mode */
471  static const int DEFAULT_MODE = S_IWUSR | S_IRUSR;
472 #else
473  /* Default create mode */
474  static const int DEFAULT_MODE = S_IWRITE | S_IREAD;
475 #endif
476 };
477 
490 template <typename T>
491 class pool : public pool_base {
492 public:
496  pool() noexcept = default;
497 
501  pool(const pool &) noexcept = default;
502 
506  pool(pool &&) noexcept = default;
507 
511  pool &operator=(const pool &) noexcept = default;
512 
516  pool &operator=(pool &&) noexcept = default;
517 
521  ~pool() noexcept = default;
522 
526  explicit pool(const pool_base &pb) noexcept : pool_base(pb)
527  {
528  }
529 
533  explicit pool(pool_base &&pb) noexcept : pool_base(pb)
534  {
535  }
536 
547  template <typename M>
548  M
549  ctl_get(const std::string &name)
550  {
551  return ctl_get_detail<M>(pop, name);
552  }
553 
565  template <typename M>
566  M
567  ctl_set(const std::string &name, M arg)
568  {
569  return ctl_set_detail(pop, name, arg);
570  }
571 
583  template <typename M>
584  M
585  ctl_exec(const std::string &name, M arg)
586  {
587  return ctl_exec_detail(pop, name, arg);
588  }
589 
590 #ifdef _WIN32
591 
601  template <typename M>
602  M
603  ctl_get(const std::wstring &name)
604  {
605  return ctl_get_detail<M>(pop, name);
606  }
607 
619  template <typename M>
620  M
621  ctl_set(const std::wstring &name, M arg)
622  {
623  return ctl_set_detail(pop, name, arg);
624  }
625 
637  template <typename M>
638  M
639  ctl_exec(const std::wstring &name, M arg)
640  {
641  return ctl_exec_detail(pop, name, arg);
642  }
643 #endif
644 
652  {
653  if (pop == nullptr)
654  throw pmem::pool_error("Invalid pool handle");
655 
656  persistent_ptr<T> root = pmemobj_root(this->pop, sizeof(T));
657  return root;
658  }
659 
660  POBJ_CPP_DEPRECATED persistent_ptr<T>
661  get_root()
662  {
663  return pool::root();
664  }
665 
678  static pool<T>
679  open(const std::string &path, const std::string &layout)
680  {
681  return pool<T>(pool_base::open(path, layout));
682  }
683 
700  static pool<T>
701  create(const std::string &path, const std::string &layout,
702  std::size_t size = PMEMOBJ_MIN_POOL, mode_t mode = DEFAULT_MODE)
703  {
704  return pool<T>(pool_base::create(path, layout, size, mode));
705  }
706 
717  static int
718  check(const std::string &path, const std::string &layout)
719  {
720  return pool_base::check(path, layout);
721  }
722 
723 #ifdef _WIN32
724 
737  static pool<T>
738  open(const std::wstring &path, const std::wstring &layout)
739  {
740  return pool<T>(pool_base::open(path, layout));
741  }
742 
760  static pool<T>
761  create(const std::wstring &path, const std::wstring &layout,
762  std::size_t size = PMEMOBJ_MIN_POOL, mode_t mode = DEFAULT_MODE)
763  {
764  return pool<T>(pool_base::create(path, layout, size, mode));
765  }
766 
778  static int
779  check(const std::wstring &path, const std::wstring &layout)
780  {
781  return pool_base::check(path, layout);
782  }
783 #endif
784 };
785 
796 template <typename T>
797 T
798 ctl_get(const std::string &name)
799 {
800  return ctl_get_detail<T>(nullptr, name);
801 }
802 
814 template <typename T>
815 T
816 ctl_set(const std::string &name, T arg)
817 {
818  return ctl_set_detail(nullptr, name, arg);
819 }
820 
832 template <typename T>
833 T
834 ctl_exec(const std::string &name, T arg)
835 {
836  return ctl_exec_detail(nullptr, name, arg);
837 }
838 
839 #ifdef _WIN32
840 
850 template <typename T>
851 T
852 ctl_get(const std::wstring &name)
853 {
854  return ctl_get_detail<T>(nullptr, name);
855 }
856 
868 template <typename T>
869 T
870 ctl_set(const std::wstring &name, T arg)
871 {
872  return ctl_set_detail(nullptr, name, arg);
873 }
874 
886 template <typename T>
887 T
888 ctl_exec(const std::wstring &name, T arg)
889 {
890  return ctl_exec_detail(nullptr, name, arg);
891 }
892 #endif
893 
894 } /* namespace obj */
895 
896 } /* namespace pmem */
897 
898 #endif /* LIBPMEMOBJ_CPP_POOL_HPP */
pmem::obj::pool_base::memcpy_persist
void * memcpy_persist(void *dest, const void *src, size_t len) noexcept
Performs memcpy and persist operation on a given chunk of memory.
Definition: pool.hpp:398
pmem::obj::ctl_exec
T ctl_exec(const std::string &name, T arg)
Execute function at global scope.
Definition: pool.hpp:834
pmem::obj::pool_base::persist
void persist(const persistent_ptr< Y > &ptr) noexcept
Performs persist operation on a given persistent pointer.
Definition: pool.hpp:337
pmem::obj::pool_base::create
static pool_base create(const std::wstring &path, const std::wstring &layout, std::size_t size=PMEMOBJ_MIN_POOL, mode_t mode=DEFAULT_MODE)
Creates a new transactional object store pool.
Definition: pool.hpp:250
pmem::obj::pool::ctl_exec
M ctl_exec(const std::string &name, M arg)
Execute function at pool scope.
Definition: pool.hpp:585
pmem::pool_error
Custom pool error class.
Definition: pexceptions.hpp:74
pmem::obj::pool_base::pool_base
pool_base(const pool_base &) noexcept=default
Defaulted copy constructor.
pmem::obj::pool::check
static int check(const std::wstring &path, const std::wstring &layout)
Checks if a given pool is consistent.
Definition: pool.hpp:779
pmem::obj::pool::create
static pool< T > create(const std::string &path, const std::string &layout, std::size_t size=PMEMOBJ_MIN_POOL, mode_t mode=DEFAULT_MODE)
Creates a new transactional object store pool.
Definition: pool.hpp:701
pmem::obj::pool_base::persist
void persist(const void *addr, size_t len) noexcept
Performs persist operation on a given chunk of memory.
Definition: pool.hpp:312
pmem
Persistent memory namespace.
Definition: allocation_flag.hpp:44
pmem::obj::pool::ctl_get
M ctl_get(const std::string &name)
Query libpmemobj state at pool scope.
Definition: pool.hpp:549
pmem::obj::pool_base::memset_persist
void * memset_persist(void *dest, int c, size_t len) noexcept
Performs memset and persist operation on a given chunk of memory.
Definition: pool.hpp:414
ctl.hpp
C++ ctl api.
common.hpp
Commonly used functionality.
pmem::obj::pool::pool
pool(pool_base &&pb) noexcept
Defaulted move constructor.
Definition: pool.hpp:533
pmem::obj::pool::ctl_get
M ctl_get(const std::wstring &name)
Query libpmemobj state at pool scope.
Definition: pool.hpp:603
pmem::obj::pool::ctl_set
M ctl_set(const std::wstring &name, M arg)
Modify libpmemobj state at pool scope.
Definition: pool.hpp:621
pmem::obj::pool_base::check
static int check(const std::string &path, const std::string &layout) noexcept
Checks if a given pool is consistent.
Definition: pool.hpp:196
pmem::obj::pool_base::defrag
pobj_defrag_result defrag(persistent_ptr_base **ptrv, size_t oidcnt)
Starts defragmentation using selected pointers within this pool.
Definition: pool.hpp:452
pmem::obj::pool_base::pool_base
pool_base(pool_base &&) noexcept=default
Defaulted move constructor.
pexceptions.hpp
Custom exceptions.
pmem::obj::pool_base::check
static int check(const std::wstring &path, const std::wstring &layout) noexcept
Checks if a given pool is consistent.
Definition: pool.hpp:276
pmem::obj::pool_base::drain
void drain(void) noexcept
Performs drain operation.
Definition: pool.hpp:382
pmem::obj::pool_base::persist
void persist(const p< Y > &prop) noexcept
Performs persist operation on a given pmem property.
Definition: pool.hpp:324
pmem::obj::p
Resides on pmem class.
Definition: p.hpp:64
pmem::obj::pool_base::open
static pool_base open(const std::string &path, const std::string &layout)
Opens an existing object store memory pool.
Definition: pool.hpp:133
pmem::obj::pool_base::close
void close()
Closes the pool.
Definition: pool.hpp:288
pmem::obj::pool::root
persistent_ptr< T > root()
Retrieves pool's root object.
Definition: pool.hpp:651
pmem::obj::pool_base::pool_base
pool_base() noexcept
Defaulted constructor.
Definition: pool.hpp:80
pmem::obj::pool_base::flush
void flush(const persistent_ptr< Y > &ptr) noexcept
Performs flush operation on a given persistent object.
Definition: pool.hpp:373
pmem::obj::pool::pool
pool() noexcept=default
Defaulted constructor.
pmem::obj::ctl_set
T ctl_set(const std::string &name, T arg)
Modify libpmemobj state at global scope.
Definition: pool.hpp:816
pmem::obj::pool_base::flush
void flush(const void *addr, size_t len) noexcept
Performs flush operation on a given chunk of memory.
Definition: pool.hpp:349
pmem::obj::pool_base::handle
PMEMobjpool * handle() noexcept
Gets the C style handle to the pool.
Definition: pool.hpp:427
pmem::obj::pool_base::pool_base
pool_base(pmemobjpool *cpop) noexcept
Explicit constructor.
Definition: pool.hpp:91
pmem::obj::pool_base::create
static pool_base create(const std::string &path, const std::string &layout, std::size_t size=PMEMOBJ_MIN_POOL, mode_t mode=DEFAULT_MODE)
Creates a new transactional object store pool.
Definition: pool.hpp:166
pmem::obj::pool::ctl_set
M ctl_set(const std::string &name, M arg)
Modify libpmemobj state at pool scope.
Definition: pool.hpp:567
pmem::defrag_error
Custom defrag error class.
Definition: pexceptions.hpp:236
pmem::obj::persistent_ptr
Persistent pointer class.
Definition: persistent_ptr.hpp:212
pmem::obj::pool_base::open
static pool_base open(const std::wstring &path, const std::wstring &layout)
Opens an existing object store memory pool.
Definition: pool.hpp:220
pmem::obj::pool
PMEMobj pool class.
Definition: pool.hpp:491
p.hpp
Resides on pmem property template.
pmem::obj::ctl_get
T ctl_get(const std::string &name)
Query libpmemobj state at global scope.
Definition: pool.hpp:798
pmem::obj::pool::open
static pool< T > open(const std::string &path, const std::string &layout)
Opens an existing object store memory pool.
Definition: pool.hpp:679
pmem::obj::pool::ctl_exec
M ctl_exec(const std::wstring &name, M arg)
Execute function at pool scope.
Definition: pool.hpp:639
pmem::obj::pool_base::flush
void flush(const p< Y > &prop) noexcept
Performs flush operation on a given pmem property.
Definition: pool.hpp:361
pool_data.hpp
A volatile data stored along with pmemobjpool.
pmem::obj::persistent_ptr_base
Persistent_ptr base (non-template) class.
Definition: persistent_ptr_base.hpp:71
persistent_ptr_base.hpp
Base class for persistent_ptr.
pmem::obj::pool::open
static pool< T > open(const std::wstring &path, const std::wstring &layout)
Opens an existing object store memory pool.
Definition: pool.hpp:738
pmem::obj::pool::create
static pool< T > create(const std::wstring &path, const std::wstring &layout, std::size_t size=PMEMOBJ_MIN_POOL, mode_t mode=DEFAULT_MODE)
Creates a new transactional object store pool.
Definition: pool.hpp:761
pmem::obj::pool_base
The non-template pool base class.
Definition: pool.hpp:75
pmem::obj::pool::check
static int check(const std::string &path, const std::string &layout)
Checks if a given pool is consistent.
Definition: pool.hpp:718