40 #ifndef LIBPMEMOBJ_CPP_VOLATILE_STATE_HPP
41 #define LIBPMEMOBJ_CPP_VOLATILE_STATE_HPP
47 #include <shared_mutex>
49 #include <unordered_map>
71 get_if_exists(
const PMEMoid &oid)
73 auto &map = get_map();
76 std::shared_lock<rwlock_type> lock(get_rwlock());
77 auto it = map.find(oid);
79 return static_cast<T *
>(it->second.get());
87 get(
const PMEMoid &oid)
89 auto &map = get_map();
91 auto element = get_if_exists<T>(oid);
95 if (pmemobj_tx_stage() != TX_STAGE_NONE)
97 "volatile_state::get() cannot be called in a transaction");
100 std::unique_lock<rwlock_type> lock(get_rwlock());
102 auto deleter = [](
void const *data) {
103 T
const *p =
static_cast<T
const *
>(data);
107 auto it = map.find(oid);
108 if (it == map.end()) {
109 auto ret = map.emplace(
110 std::piecewise_construct,
111 std::forward_as_tuple(oid),
112 std::forward_as_tuple(
new T, deleter));
121 auto pop = pmemobj_pool_by_oid(oid);
123 static_cast<detail::pool_data *
>(
124 pmemobj_get_user_data(pop));
126 user_data->set_cleanup([oid] {
127 clear_from_pool(oid.pool_uuid_lo);
131 return static_cast<T *
>(it->second.get());
136 destroy(
const PMEMoid &oid)
138 if (pmemobj_tx_stage() == TX_STAGE_WORK) {
140 obj::transaction::stage::oncommit, [oid] {
141 std::unique_lock<rwlock_type> lock(
143 get_map().erase(oid);
146 std::unique_lock<rwlock_type> lock(get_rwlock());
147 get_map().erase(oid);
152 struct pmemoid_hash {
154 operator()(
const PMEMoid &oid)
const
156 return oid.pool_uuid_lo + oid.off;
160 struct pmemoid_equal_to {
162 operator()(
const PMEMoid &lhs,
const PMEMoid &rhs)
const
164 return lhs.pool_uuid_lo == rhs.pool_uuid_lo &&
169 using key_type = PMEMoid;
171 std::unique_ptr<void,
172 std::add_pointer<void(
const void *)>::type>;
174 using map_type = std::unordered_map<key_type, value_type, pmemoid_hash,
177 using rwlock_type = std::shared_timed_mutex;
180 clear_from_pool(uint64_t pool_id)
182 std::unique_lock<rwlock_type> lock(get_rwlock());
183 auto &map = get_map();
185 for (
auto it = map.begin(); it != map.end();) {
186 if (it->first.pool_uuid_lo == pool_id)
203 static rwlock_type rwlock;