PMDK C++ bindings 1.13.0
This is the C++ bindings documentation for PMDK's libpmemobj.
Loading...
Searching...
No Matches
volatile_state.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-3-Clause
2/* Copyright 2019-2020, Intel Corporation */
3
11#ifndef LIBPMEMOBJ_CPP_VOLATILE_STATE_HPP
12#define LIBPMEMOBJ_CPP_VOLATILE_STATE_HPP
13
14#include <cassert>
15#include <functional>
16#include <memory>
17#include <mutex>
18#include <shared_mutex>
19#include <tuple>
20#include <unordered_map>
21
24#include <libpmemobj++/pool.hpp>
26
27namespace pmem
28{
29
30namespace detail
31{
32
39public:
40 template <typename T>
41 static T *
42 get_if_exists(const PMEMoid &oid)
43 {
44 auto &map = get_map();
45
46 {
47 std::shared_lock<rwlock_type> lock(get_rwlock());
48 auto it = map.find(oid);
49 if (it != map.end())
50 return static_cast<T *>(it->second.get());
51 else
52 return nullptr;
53 }
54 }
55
56 template <typename T>
57 static T *
58 get(const PMEMoid &oid)
59 {
60 auto &map = get_map();
61
62 auto element = get_if_exists<T>(oid);
63 if (element)
64 return element;
65
66 if (pmemobj_tx_stage() != TX_STAGE_NONE)
68 "volatile_state::get() cannot be called in a transaction");
69
70 {
71 std::unique_lock<rwlock_type> lock(get_rwlock());
72
73 auto deleter = [](void const *data) {
74 T const *p = static_cast<T const *>(data);
75 delete p;
76 };
77
78 auto it = map.find(oid);
79 if (it == map.end()) {
80 auto ret = map.emplace(
81 std::piecewise_construct,
82 std::forward_as_tuple(oid),
83 std::forward_as_tuple(new T, deleter));
84
85 /* emplace could fail only if there is already
86 * an element with the same key which is not
87 * possible */
88 assert(ret.second);
89
90 it = ret.first;
91
92 auto pop = pmemobj_pool_by_oid(oid);
93 auto *user_data =
94 static_cast<detail::pool_data *>(
95 pmemobj_get_user_data(pop));
96
97 user_data->set_cleanup([oid] {
98 clear_from_pool(oid.pool_uuid_lo);
99 });
100 }
101
102 return static_cast<T *>(it->second.get());
103 }
104 }
105
106 static void
107 destroy(const PMEMoid &oid)
108 {
109 if (pmemobj_tx_stage() == TX_STAGE_WORK) {
111 obj::flat_transaction::stage::oncommit, [oid] {
112 std::unique_lock<rwlock_type> lock(
113 get_rwlock());
114 get_map().erase(oid);
115 });
116 } else {
117 std::unique_lock<rwlock_type> lock(get_rwlock());
118 get_map().erase(oid);
119 }
120 }
121
122private:
123 struct pmemoid_hash {
124 std::size_t
125 operator()(const PMEMoid &oid) const
126 {
127 return oid.pool_uuid_lo + oid.off;
128 }
129 };
130
131 struct pmemoid_equal_to {
132 bool
133 operator()(const PMEMoid &lhs, const PMEMoid &rhs) const
134 {
135 return lhs.pool_uuid_lo == rhs.pool_uuid_lo &&
136 lhs.off == rhs.off;
137 }
138 };
139
140 using key_type = PMEMoid;
141 using value_type =
142 std::unique_ptr<void,
143 std::add_pointer<void(const void *)>::type>;
144
145 using map_type = std::unordered_map<key_type, value_type, pmemoid_hash,
146 pmemoid_equal_to>;
147
148 using rwlock_type = std::shared_timed_mutex;
149
150 static void
151 clear_from_pool(uint64_t pool_id)
152 {
153 std::unique_lock<rwlock_type> lock(get_rwlock());
154 auto &map = get_map();
155
156 for (auto it = map.begin(); it != map.end();) {
157 if (it->first.pool_uuid_lo == pool_id)
158 it = map.erase(it);
159 else
160 ++it;
161 }
162 }
163
164 static map_type &
165 get_map()
166 {
167 static map_type map;
168 return map;
169 }
170
171 static rwlock_type &
172 get_rwlock()
173 {
174 static rwlock_type rwlock;
175 return rwlock;
176 }
177};
178
179} /* namespace detail */
180
181} /* namespace pmem */
182
183#endif /* LIBPMEMOBJ_CPP_VOLATILE_STATE_HPP */
static void register_callback(stage stg, std::function< void()> cb)
Registers callback to be called on specified stage for the transaction.
Definition: transaction.hpp:478
Global key value store which allows persistent objects to use volatile memory.
Definition: volatile_state.hpp:38
Custom transaction error class.
Definition: pexceptions.hpp:176
Commonly used functionality.
Functions for destroying arrays.
Persistent memory namespace.
Definition: allocation_flag.hpp:15
C++ pmemobj pool.
C++ pmemobj transactions.