PMDK C++ bindings  1.2.0
This is the C++ bindings documentation for PMDK's libpmemobj.
persistent_ptr.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2015-2018, 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_PERSISTENT_PTR_HPP
39 #define LIBPMEMOBJ_CPP_PERSISTENT_PTR_HPP
40 
41 #include <cassert>
42 #include <limits>
43 #include <memory>
44 #include <ostream>
45 
49 #include <libpmemobj++/pool.hpp>
50 #include <libpmemobj.h>
51 
52 namespace pmem
53 {
54 
55 namespace obj
56 {
57 
58 template <typename T>
59 class pool;
60 
61 template <typename T>
62 class persistent_ptr;
63 
64 /*
65  * persistent_ptr void specialization.
66  */
67 template <>
68 class persistent_ptr<void> : public detail::persistent_ptr_base<void> {
69 public:
70  persistent_ptr() = default;
73 };
74 
75 /*
76  * persistent_ptr const void specialization.
77  */
78 template <>
79 class persistent_ptr<const void>
80  : public detail::persistent_ptr_base<const void> {
81 public:
82  persistent_ptr() = default;
85 };
86 
131 template <typename T>
132 class persistent_ptr : public detail::persistent_ptr_base<T> {
133 public:
134  persistent_ptr() = default;
136 
140  explicit persistent_ptr(persistent_ptr<void> const &rhs) noexcept
141  : detail::persistent_ptr_base<T>(rhs.raw())
142  {
143  }
144 
148  explicit persistent_ptr(persistent_ptr<const void> const &rhs) noexcept
149  : detail::persistent_ptr_base<T>(rhs.raw())
150  {
151  }
152 
156  operator persistent_ptr<void>() const noexcept
157  {
158  return this->get();
159  }
160 
164  typename pmem::detail::sp_dereference<T>::type operator*() const
165  noexcept
166  {
167  return *this->get();
168  }
169 
173  typename pmem::detail::sp_member_access<T>::type operator->() const
174  noexcept
175  {
176  return this->get();
177  }
178 
186  template <typename I,
187  typename std::enable_if<std::is_integral<I>::value,
188  int>::type = 0>
189  typename pmem::detail::sp_array_access<T>::type operator[](I i) const
190  noexcept
191  {
192  assert(i >= 0 &&
193  (i < pmem::detail::sp_extent<T>::value ||
194  pmem::detail::sp_extent<T>::value == 0) &&
195  "persistent array index out of bounds");
196 
197  return this->get()[i];
198  }
199 
203  inline persistent_ptr<T> &
205  {
206  detail::conditional_add_to_tx(this);
207  this->oid.off += sizeof(T);
208 
209  return *this;
210  }
211 
215  inline persistent_ptr<T>
217  {
218  PMEMoid noid = this->oid;
219  ++(*this);
220 
221  return persistent_ptr<T>(noid);
222  }
223 
227  inline persistent_ptr<T> &
229  {
230  detail::conditional_add_to_tx(this);
231  this->oid.off -= sizeof(T);
232 
233  return *this;
234  }
235 
239  inline persistent_ptr<T>
241  {
242  PMEMoid noid = this->oid;
243  --(*this);
244 
245  return persistent_ptr<T>(noid);
246  }
247 
251  inline persistent_ptr<T> &
252  operator+=(std::ptrdiff_t s)
253  {
254  detail::conditional_add_to_tx(this);
255  this->oid.off += static_cast<std::uint64_t>(s) * sizeof(T);
256 
257  return *this;
258  }
259 
263  inline persistent_ptr<T> &
264  operator-=(std::ptrdiff_t s)
265  {
266  detail::conditional_add_to_tx(this);
267  this->oid.off -= static_cast<std::uint64_t>(s) * sizeof(T);
268 
269  return *this;
270  }
271 
277  void
279  {
280  pop.persist(this->get(), sizeof(T));
281  }
282 
289  void
290  persist(void)
291  {
292  pmemobjpool *pop = pmemobj_pool_by_oid(this->raw());
293 
294  if (pop == nullptr)
295  throw pool_error(
296  "Cannot get pool from persistent pointer");
297 
298  pmemobj_persist(pop, this->get(), sizeof(T));
299  }
300 
306  void
308  {
309  pop.flush(this->get(), sizeof(T));
310  }
311 
318  void
319  flush(void)
320  {
321  pmemobjpool *pop = pmemobj_pool_by_oid(this->raw());
322 
323  if (pop == nullptr)
324  throw pool_error(
325  "Cannot get pool from persistent pointer");
326 
327  pmemobj_flush(pop, this->get(), sizeof(T));
328  }
329 
330  /*
331  * Pointer traits related.
332  */
333 
342  static persistent_ptr<T>
343  pointer_to(T &ref)
344  {
345  return persistent_ptr<T>(std::addressof(ref), 0);
346  }
347 
351  template <class U>
353 
358 
362  using bool_type = bool;
363 
364  /*
365  * Random access iterator requirements (members)
366  */
367 
371  using iterator_category = std::random_access_iterator_tag;
372 
376  using difference_type = std::ptrdiff_t;
377 
381  using value_type = T;
382 
386  using reference = T &;
387 
392 };
393 
400 template <class T>
401 inline void
403 {
404  a.swap(b);
405 }
406 
412 template <typename T, typename Y>
413 inline bool
414 operator==(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
415 {
416  return OID_EQUALS(lhs.raw(), rhs.raw());
417 }
418 
422 template <typename T, typename Y>
423 inline bool
424 operator!=(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
425 {
426  return !(lhs == rhs);
427 }
428 
432 template <typename T>
433 inline bool
434 operator==(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
435 {
436  return lhs.get() == nullptr;
437 }
438 
442 template <typename T>
443 inline bool
444 operator==(std::nullptr_t, persistent_ptr<T> const &lhs) noexcept
445 {
446  return lhs.get() == nullptr;
447 }
448 
452 template <typename T>
453 inline bool
454 operator!=(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
455 {
456  return lhs.get() != nullptr;
457 }
458 
462 template <typename T>
463 inline bool
464 operator!=(std::nullptr_t, persistent_ptr<T> const &lhs) noexcept
465 {
466  return lhs.get() != nullptr;
467 }
468 
476 template <typename T, typename Y>
477 inline bool
478 operator<(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
479 {
480  if (lhs.raw().pool_uuid_lo == rhs.raw().pool_uuid_lo)
481  return lhs.raw().off < rhs.raw().off;
482  else
483  return lhs.raw().pool_uuid_lo < rhs.raw().pool_uuid_lo;
484 }
485 
491 template <typename T, typename Y>
492 inline bool
493 operator<=(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
494 {
495  return !(rhs < lhs);
496 }
497 
503 template <typename T, typename Y>
504 inline bool
505 operator>(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
506 {
507  return (rhs < lhs);
508 }
509 
515 template <typename T, typename Y>
516 inline bool
517 operator>=(persistent_ptr<T> const &lhs, persistent_ptr<Y> const &rhs) noexcept
518 {
519  return !(lhs < rhs);
520 }
521 
522 /* nullptr comparisons */
523 
527 template <typename T>
528 inline bool
529 operator<(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
530 {
531  return std::less<typename persistent_ptr<T>::element_type *>()(
532  lhs.get(), nullptr);
533 }
534 
538 template <typename T>
539 inline bool
540 operator<(std::nullptr_t, persistent_ptr<T> const &rhs) noexcept
541 {
542  return std::less<typename persistent_ptr<T>::element_type *>()(
543  nullptr, rhs.get());
544 }
545 
549 template <typename T>
550 inline bool
551 operator<=(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
552 {
553  return !(nullptr < lhs);
554 }
555 
559 template <typename T>
560 inline bool
561 operator<=(std::nullptr_t, persistent_ptr<T> const &rhs) noexcept
562 {
563  return !(rhs < nullptr);
564 }
565 
569 template <typename T>
570 inline bool
571 operator>(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
572 {
573  return nullptr < lhs;
574 }
575 
579 template <typename T>
580 inline bool
581 operator>(std::nullptr_t, persistent_ptr<T> const &rhs) noexcept
582 {
583  return rhs < nullptr;
584 }
585 
589 template <typename T>
590 inline bool
591 operator>=(persistent_ptr<T> const &lhs, std::nullptr_t) noexcept
592 {
593  return !(lhs < nullptr);
594 }
595 
599 template <typename T>
600 inline bool
601 operator>=(std::nullptr_t, persistent_ptr<T> const &rhs) noexcept
602 {
603  return !(nullptr < rhs);
604 }
605 
609 template <typename T>
610 inline persistent_ptr<T>
611 operator+(persistent_ptr<T> const &lhs, std::ptrdiff_t s)
612 {
613  PMEMoid noid;
614  noid.pool_uuid_lo = lhs.raw().pool_uuid_lo;
615  noid.off = lhs.raw().off + static_cast<std::uint64_t>(s) * sizeof(T);
616 
617  return persistent_ptr<T>(noid);
618 }
619 
623 template <typename T>
624 inline persistent_ptr<T>
625 operator-(persistent_ptr<T> const &lhs, std::ptrdiff_t s)
626 {
627  PMEMoid noid;
628  noid.pool_uuid_lo = lhs.raw().pool_uuid_lo;
629  noid.off = lhs.raw().off - static_cast<std::uint64_t>(s) * sizeof(T);
630 
631  return persistent_ptr<T>(noid);
632 }
633 
641 template <typename T, typename Y,
642  typename = typename std::enable_if<
643  std::is_same<typename std::remove_cv<T>::type,
644  typename std::remove_cv<Y>::type>::value>>
645 inline ptrdiff_t
647 {
648  assert(lhs.raw().pool_uuid_lo == rhs.raw().pool_uuid_lo);
649  auto d = static_cast<std::ptrdiff_t>(lhs.raw().off - rhs.raw().off);
650 
651  return d / static_cast<std::ptrdiff_t>(sizeof(T));
652 }
653 
657 template <typename T>
658 std::ostream &
659 operator<<(std::ostream &os, persistent_ptr<T> const &pptr)
660 {
661  PMEMoid raw_oid = pptr.raw();
662  os << std::hex << "0x" << raw_oid.pool_uuid_lo << ", 0x" << raw_oid.off
663  << std::dec;
664  return os;
665 }
666 
667 } /* namespace obj */
668 
669 } /* namespace pmem */
670 
671 #endif /* LIBPMEMOBJ_CPP_PERSISTENT_PTR_HPP */
bool operator==(standard_alloc_policy< T > const &, standard_alloc_policy< T2 > const &)
Determines if memory from another allocator can be deallocated from this one.
Definition: allocator.hpp:400
persistent_ptr< T > & operator++()
Prefix increment operator.
Definition: persistent_ptr.hpp:204
Persistent_ptr base class.
Definition: persistent_ptr_base.hpp:68
void persist(void)
Persists what the persistent pointer points to.
Definition: persistent_ptr.hpp:290
Helper template for persistent ptr specialization.
Persistent pointer class.
Definition: common.hpp:72
pmem::detail::sp_array_access< T >::type operator[](I i) const noexcept
Array access operator.
Definition: persistent_ptr.hpp:189
pmem::detail::sp_member_access< T >::type operator->() const noexcept
Member access operator.
Definition: persistent_ptr.hpp:173
The non-template pool base class.
Definition: pool.hpp:67
Custom pool error class.
Definition: pexceptions.hpp:53
persistent_ptr< T > & operator-=(std::ptrdiff_t s)
Subtraction assignment operator.
Definition: persistent_ptr.hpp:264
persistent_ptr(persistent_ptr< const void > const &rhs) noexcept
Explicit const void specialization of the converting constructor.
Definition: persistent_ptr.hpp:148
persistent_ptr< T > operator++(int)
Postfix increment operator.
Definition: persistent_ptr.hpp:216
void persist(pool_base &pop)
Persists the content of the underlying object.
Definition: persistent_ptr.hpp:278
bool bool_type
The used bool_type.
Definition: persistent_ptr.hpp:362
void flush(pool_base &pop)
Flushes what the persistent pointer points to.
Definition: persistent_ptr.hpp:307
PMEMobj pool class.
Definition: persistent_ptr.hpp:59
persistent_ptr< T > operator--(int)
Postfix decrement operator.
Definition: persistent_ptr.hpp:240
persistent_ptr< T > operator+(persistent_ptr< T > const &lhs, std::ptrdiff_t s)
Addition operator for persistent pointers.
Definition: persistent_ptr.hpp:611
Commonly used functionality.
std::random_access_iterator_tag iterator_category
The persistent_ptr iterator category.
Definition: persistent_ptr.hpp:371
persistent_ptr< T > & operator--()
Prefix decrement operator.
Definition: persistent_ptr.hpp:228
persistent_ptr< T > & operator+=(std::ptrdiff_t s)
Addition assignment operator.
Definition: persistent_ptr.hpp:252
void flush(void)
Flushes what the persistent pointer points to.
Definition: persistent_ptr.hpp:319
void persist(const void *addr, size_t len) noexcept
Performs persist operation on a given chunk of memory.
Definition: pool.hpp:284
static persistent_ptr< T > pointer_to(T &ref)
Create a persistent pointer from a given reference.
Definition: persistent_ptr.hpp:343
persistent_ptr< T > operator-(persistent_ptr< T > const &lhs, std::ptrdiff_t s)
Subtraction operator for persistent pointers.
Definition: persistent_ptr.hpp:625
const PMEMoid & raw() const noexcept
Get PMEMoid encapsulated by this object.
Definition: persistent_ptr_base.hpp:304
pmem::detail::sp_dereference< T >::type operator*() const noexcept
Dereference operator.
Definition: persistent_ptr.hpp:164
Resides on pmem class.
Definition: p.hpp:64
bool operator!=(const allocator< T, P, Tr > &lhs, const OtherAllocator &rhs)
Determines if memory from another allocator can be deallocated from this one.
Definition: allocator.hpp:516
T value_type
The type of the value pointed to by the persistent_ptr.
Definition: persistent_ptr.hpp:381
Definition: allocator.hpp:48
void flush(const void *addr, size_t len) noexcept
Performs flush operation on a given chunk of memory.
Definition: pool.hpp:320
Base class for persistent_ptr.
std::ptrdiff_t difference_type
The persistent_ptr difference type.
Definition: persistent_ptr.hpp:376
persistent_ptr(persistent_ptr< void > const &rhs) noexcept
Explicit void specialization of the converting constructor.
Definition: persistent_ptr.hpp:140
C++ pmemobj pool.
T & reference
The reference type of the value pointed to by the persistent_ptr.
Definition: persistent_ptr.hpp:386