forked from zhangnaifan/BzTree
-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.h
156 lines (143 loc) · 3.96 KB
/
utils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#ifndef UTILS_H
#define UTILS_H
#include <assert.h>
#include <libpmem.h>
#include <libpmemobj.h>
#include <stdint.h>
#define MAX_PATH_DEPTH 16
struct bz_path_stack
{
uint64_t nodes[MAX_PATH_DEPTH];
int child_ids[MAX_PATH_DEPTH];
int count = 0;
void push(uint64_t node, int child_id) {
assert(count < MAX_PATH_DEPTH);
nodes[count] = node;
child_ids[count] = child_id;
++count;
}
void push() {
++count;
}
void pop() {
assert(count > 0);
--count;
}
void reset() {
count = 0;
}
bool empty() {
return count <= 0;
}
uint64_t get_node() {
assert(count > 0);
return nodes[count - 1];
}
int get_child_id() {
assert(count > 0);
return child_ids[count - 1];
}
};
POBJ_LAYOUT_BEGIN(layout_name);
POBJ_LAYOUT_TOID(layout_name, struct bz_node_block);
POBJ_LAYOUT_END(layout_name);
struct bz_node_block {
POBJ_LIST_ENTRY(struct bz_node_block) entry;
};
struct bz_memory_pool {
PMEMmutex mem_lock;
PMEMobjpool * pop_;
void init(PMEMobjpool *pop, PMEMoid base_oid) {
pop_ = pop;
rel_ptr<uint64_t>::set_base(base_oid);
rel_ptr<rel_ptr<uint64_t>>::set_base(base_oid);
}
#ifndef IS_PMEM
POBJ_LIST_HEAD(bz_node_list, struct bz_node_block) head_;
void prev_alloc() {
uint32_t node_sz = NODE_ALLOC_SIZE;
for (size_t i = 0; i < PRE_ALLOC_NUM; ++i) {
POBJ_LIST_INSERT_NEW_TAIL(pop_, &head_, entry,
sizeof(bz_node_block) + NODE_ALLOC_SIZE,
NULL, NULL);
}
}
void acquire(rel_ptr<rel_ptr<uint64_t>> ptr) {
pmemobj_mutex_lock(pop_, &mem_lock);
TOID(struct bz_node_block) front = POBJ_LIST_FIRST(&head_);
if (!TOID_IS_NULL(front)) {
TX_BEGIN(pop_) {
pmemobj_tx_add_range_direct(ptr.abs(), sizeof(uint64_t));
*ptr = (uint64_t*)((char*)pmemobj_direct(front.oid) + sizeof(bz_node_block));
POBJ_LIST_REMOVE(pop_, &head_, front, entry);
} TX_END;
}
else {
TX_BEGIN(pop_) {
pmemobj_tx_add_range_direct(ptr.abs(), sizeof(uint64_t));
PMEMoid oid = pmemobj_tx_alloc(sizeof(bz_node_block) + NODE_ALLOC_SIZE, TOID_TYPE_NUM(struct bz_node_block));
*ptr = (uint64_t*)((char*)pmemobj_direct(oid) + sizeof(bz_node_block));
} TX_END;
}
pmemobj_mutex_unlock(pop_, &mem_lock);
}
void release(rel_ptr<rel_ptr<uint64_t>> ptr) {
pmemobj_mutex_lock(pop_, &mem_lock);
PMEMoid oid = ptr->oid();
//right?
oid.off -= sizeof(bz_node_block);
TOID(struct bz_node_block) back = TOID(struct bz_node_block)(oid);
TX_BEGIN(pop_) {
pmemobj_tx_add_range_direct(ptr.abs(), sizeof(uint64_t));
POBJ_LIST_INSERT_TAIL(pop_, &head_, back, entry);
*ptr = rel_ptr<uint64_t>();
} TX_END;
pmemobj_mutex_unlock(pop_, &mem_lock);
}
#else
uint32_t front_, back_;
uint64_t nodes[MAX_ALLOC_NUM];
void prev_alloc() {
front_ = back_ = 0;
for (int i = 0; i < PRE_ALLOC_NUM; ++i) {
PMEMoid oid;
pmemobj_alloc(pop_, &oid, NODE_ALLOC_SIZE, TOID_TYPE_NUM(struct bz_node_block), NULL, NULL);
assert(!OID_IS_NULL(oid));
nodes[back_] = rel_ptr<uint64_t>(oid).rel();
pmem_persist(&nodes[back_], sizeof(uint64_t));
++back_;
}
pmem_persist(&front_, sizeof(uint32_t));
pmem_persist(&back_, sizeof(uint32_t));
}
void acquire(rel_ptr<rel_ptr<uint64_t>> ptr) {
pmemobj_mutex_lock(pop_, &mem_lock);
if (front_ == back_) {
PMEMoid oid;
pmemobj_alloc(pop_, &oid, NODE_ALLOC_SIZE, TOID_TYPE_NUM(struct bz_node_block), NULL, NULL);
assert(!OID_IS_NULL(oid));
*ptr = rel_ptr<uint64_t>(oid);
}
else {
*ptr = rel_ptr<uint64_t>(nodes[front_]);
front_ = (front_ + 1) % MAX_ALLOC_NUM;
pmem_persist(&front_, sizeof(uint32_t));
}
pmem_persist(ptr.abs(), sizeof(uint64_t));
pmemobj_mutex_unlock(pop_, &mem_lock);
}
void release(rel_ptr<rel_ptr<uint64_t>> ptr) {
if (ptr->is_null())
return;
pmemobj_mutex_lock(pop_, &mem_lock);
nodes[back_] = ptr->rel();
*ptr = rel_ptr<uint64_t>();
back_ = (back_ + 1) % MAX_ALLOC_NUM;
assert(back_ != front_);
pmem_persist(ptr.abs(), sizeof(uint64_t));
pmem_persist(&back_, sizeof(uint32_t));
pmemobj_mutex_unlock(pop_, &mem_lock);
}
#endif // !IS_PMEM
};
#endif // !UTILS_H