11 #ifndef LIBPMEMOBJ_CPP_VOLATILE_STATE_HPP
12 #define LIBPMEMOBJ_CPP_VOLATILE_STATE_HPP
18 #include <shared_mutex>
20 #include <unordered_map>
42 get_if_exists(
const PMEMoid &oid)
44 auto &map = get_map();
47 std::shared_lock<rwlock_type> lock(get_rwlock());
48 auto it = map.find(oid);
50 return static_cast<T *
>(it->second.get());
58 get(
const PMEMoid &oid)
60 auto &map = get_map();
62 auto element = get_if_exists<T>(oid);
66 if (pmemobj_tx_stage() != TX_STAGE_NONE)
68 "volatile_state::get() cannot be called in a transaction");
71 std::unique_lock<rwlock_type> lock(get_rwlock());
73 auto deleter = [](
void const *data) {
74 T
const *p =
static_cast<T
const *
>(data);
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));
92 auto pop = pmemobj_pool_by_oid(oid);
94 static_cast<detail::pool_data *
>(
95 pmemobj_get_user_data(pop));
97 user_data->set_cleanup([oid] {
98 clear_from_pool(oid.pool_uuid_lo);
102 return static_cast<T *
>(it->second.get());
107 destroy(
const PMEMoid &oid)
109 if (pmemobj_tx_stage() == TX_STAGE_WORK) {
111 obj::flat_transaction::stage::oncommit, [oid] {
112 std::unique_lock<rwlock_type> lock(
114 get_map().erase(oid);
117 std::unique_lock<rwlock_type> lock(get_rwlock());
118 get_map().erase(oid);
123 struct pmemoid_hash {
125 operator()(
const PMEMoid &oid)
const
127 return oid.pool_uuid_lo + oid.off;
131 struct pmemoid_equal_to {
133 operator()(
const PMEMoid &lhs,
const PMEMoid &rhs)
const
135 return lhs.pool_uuid_lo == rhs.pool_uuid_lo &&
140 using key_type = PMEMoid;
142 std::unique_ptr<void,
143 std::add_pointer<void(
const void *)>::type>;
145 using map_type = std::unordered_map<key_type, value_type, pmemoid_hash,
148 using rwlock_type = std::shared_timed_mutex;
151 clear_from_pool(uint64_t pool_id)
153 std::unique_lock<rwlock_type> lock(get_rwlock());
154 auto &map = get_map();
156 for (
auto it = map.begin(); it != map.end();) {
157 if (it->first.pool_uuid_lo == pool_id)
174 static rwlock_type rwlock;