forked from yuanrongxi/innodb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhash0hash.h
235 lines (190 loc) · 6.55 KB
/
hash0hash.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
#ifndef __HASH_0_HASH_H_
#define __HASH_0_HASH_H_
#include "univ.h"
#include "mem0mem.h"
#ifndef UNIV_HOTBACKUP
#include "sync0sync.h"
#include "sync0rw.h"
#endif
#define hash_create hash0_create
typedef void* hash_node_t;
/*这个枚举会指定hash_table_t中的sync_obj*/
enum hash_table_sync_t
{
HASH_TABLE_SYNC_NONE = 0, /*无锁类型*/
HASH_TABLE_SYNC_MUTEX, /*用互斥锁访问HASH TABLE*/
HASH_TABLE_SYNC_RW_LOCK, /*用读写锁访问HASH TABLE*/
};
struct hash_cell_t
{
void* node;
};
#define HASH_TABLE_MAGIC_N 76561114
struct hash_table_t
{
enum hash_table_sync_t type; /*hash table的同步类型*/
ulint n_cells; /*hash桶个数*/
hash_cell_t* array; /*hash桶数组*/
#ifndef UNIV_HOTBACKUP
ulint n_sync_obj;
union{ /*同步锁*/
ib_mutex_t* mutexes;
rw_lock_t* rw_locks;
}sync_obj;
/*heaps的单元个数和n_sync_obj一样*/
mem_heap_t** heaps;
#endif
mem_heap_t* heap;
ulint magic_n; /*校验魔法字*/
#endif
};
UNIV_INTERN hash_table_t* hash_create(ulint n);
UNIV_INTERN void hash_create_sync_obj_func(hash_table_t* table, enum hash_table_sync_t type, ulint n_sync_obj);
/*创建hash table*/
#define hash_create_sync_obj(t, s, n, level) hash_create_sync_obj_func(t, s, n)
UNIV_INTERN void hash_table_free(hash_table_t* table);
UNIV_INTERN ulint hash_calc_hash(ulint fold, hash_table_t* table);
UNIV_INLINE hash_cell_t* hash_get_nth_cell(hash_table_t* table, ulint n);
UNIV_INLINE void hash_table_clear(hash_table_t* table);
UNIV_INLINE ulint hash_get_n_cells(hash_table_t* table);
UNIV_INLINE ulint hash_get_sync_obj_index(hash_table_t* table, ulint fold);
UNIV_INLINE mem_heap_t* hash_get_nth_heap(hash_table_t* table, ulint i);
UNIV_INLINE mem_heap_t* hash_get_heap(hash_table_t* table, ulint fold);
UNIV_INLINE ib_mutex_t* hash_get_nth_mutex(hash_table_t* table, ulint i);
UNIV_INLINE rw_lock_t* hash_get_nth_lock(hash_table_t* table, ulint i);
UNIV_INLINE ib_mutex_t* hash_get_mutex(hash_table_t* table, ulint fold);
UNIV_INLINE rw_lock_t* hash_get_lock(hash_table_t* table, ulint fold);
UNIV_INTERN void hash_mutex_enter(hash_table_t* table, ulint fold);
UNIV_INTERN void hash_mutex_exit(hash_table_t* table, ulint fold);
UNIV_INTERN void hash_mutex_enter_all(hash_table_t* table);
UNIV_INTERN void hash_mutex_exit_all(hash_table_t* table);
/*解除除keep_mutex以外的所有锁*/
UNIV_INTERN void hash_mutex_exit_all_but(hash_table_t* table, ib_mutex_t* keep_mutex);
UNIV_INTERN void hash_lock_s(hash_table_t* table, ulint fold);
UNIV_INTERN void hash_unlock_s(hash_table_t* table, ulint fold);
UNIV_INTERN void hash_lock_x(hash_table_t* table, ulint fold);
UNIV_INTERN void hash_unlock_x(hash_table_t* table, ulint fold);
UNIV_INTERN void hash_lock_x_all(hash_table_t* table);
UNIV_INTERN void hash_unlock_x_all(hash_table_t* table);
/*解除除keep_lock以外的所有锁*/
UNIV_INTERN void hash_unlock_x_all_put(hash_table_t* table, rw_lock_t* keep_lock);
#ifndef UNIV_HOTBACKUP
#define HASH_ASSERT_OWN(TABLE, FOLD) \
ut_ad((TABLE)->type != HASH_TABLE_SYNC_MUTEX || (mutex_own(hash_get_mutex((TABLE), FOLD))));
#else
#define HASH_ASSERT_OWN(TABLE, FOLD)
#endif
/*向hash table插入一个(fold, data)*/
#define HASH_INSERT(TYPE, NAME, TABLE, FOLD, DATA) \
do{ \
hash_cell_t* cell3333; \
TYPE* struct333; \
(DATA)->NAME = NULL; \
cell3333 = hash_get_nth_cell(TABLE, hash_calc_hash(FOLD, TABLE)); \
if(cell3333->node == NULL) \
cell3333->node = DATA; \
else{ \
struct333 = (TYPE*)cell3333->node; \
while(struct333->NAME != NULL) \
struct333 = (TYPE*)struct333->NAME; \
struct333->NAME = DATA; \
} \
}while(0)
# define HASH_ASSERT_VALID(DATA) do {} while (0)
# define HASH_INVALIDATE(DATA, NAME) do {} while (0)
#define HASH_DELETE(TYPE, NAME, TABLE, FOLD, DATA) \
do{ \
hash_cell_t* cell3333; \
TYPE* struct3333; \
HASH_ASSERT_OWN(TABLE, FOLD); \
cell3333 = hash_get_nth_cell(TABLE, hash_calc_hash(FOLD, TABLE)); \
if(cell3333->node == DATA){ \
HASH_ASSERT_VALID(DATA->NAME); \
cell3333->node = DATA->NAME; \
} \
else{ \
struct3333 = (TYPE*)cell3333->node; \
while(struct3333->NAME != DATA){ \
struct3333 = (TYPE*)struct3333->NAME; \
ut_a(struct3333); \
} \
struct3333->NAME = DATA->NAME; \
} \
HASH_INVALIDATE(DATA, NAME); \
}while(0)
/*获得cell的第一个单元*/
#define HASH_GET_FIRST(TABLE, HASH_VAL) (hash_get_nth_cell(TABLE, HASH_VAL)->node)
/*获得data的下一个单元*/
#define HASH_GET_NEXT(NAME, DATA) ((DATA)->NAME)
#define HASH_SEARCH(NAME, TABLE, FOLD, TYPE, DATA, ASSERTION, TEST) \
{ \
HASH_ASSERT_OWN(TABLE, FOLD); \
(DATA) = (TYPE)HASH_GET_FIRST(TABLE, hash_calc_hash(FOLD, TABLE)); \
HASH_ASSERT_VALID(DATA); \
while((DATA) != NULL){ \
ASSERTION; \
if(TEST) break; \
else{ \
HASH_ASSERT_VALID(HASH_GET_NEXT(NAME, DATA)); \
(DATA) = (TYPE) HASH_GET_NEXT(NAME, DATA); \
} \
} \
}
#define HASH_SEARCH_ALL(NAME, TABLE, TYPE, DATA, ASSERTION, TEST) \
do{ \
ulint i3333; \
for (i3333 = (TABLE)->n_cells; i3333--; ) { \
(DATA) = (TYPE) HASH_GET_FIRST(TABLE, i3333); \
while ((DATA) != NULL) { \
HASH_ASSERT_VALID(DATA); \
ASSERTION; \
if (TEST) break; \
(DATA) = (TYPE) HASH_GET_NEXT(NAME, DATA); \
} \
if ((DATA) != NULL) break; \
}while(0)
#define HASH_DELETE_AND_COMPACT(TYPE, NAME, TABLE, NODE) \
do{ \
TYPE* node111; \
TYPE* top_node111; \
hash_cell_t* cell111; \
ulint fold111; \
\
fold111 = (NODE)->fold; \
HASH_DELETE(TYPE, NAME, TABLE, fold111, NODE); \ /*删除掉需要删除的node*/
\
top_node111 = (TYPE*)mem_heap_get_top(hash_get_heap(TABLE, fold111), sizoef(TYPE)); \/*获得heap top的地址,如果这个地址存储的内容不是NODE的内容,将这个问题位置的内容和NODE置换,并释放掉top的空间,保持空间的连续性*/
\
if(top_node111 != (NODE)){ \
*(NODE) = *top_node111; \
cell111 = hash_get_nth_cell(TABLE, hash_calc_hash(fold111, TABLE)); \
if(cell111->node == top_node111){ \
cell111->node = NODE; \
} \
else{ \
node111 = cell111->node; \
while(top_node111 != HASH_GET_NEXT(NAME, node111)){ \
node111 = HASH_GET_NEXT(NAME, node111); \
} \
node111->NAME = NODE; \
} \
} \
mem_heap_free_top(hash_get_heap(TABLE, fold111), sizeof(TYPE)); \ /*释放掉heap top指向的空间(大小为TYPE结构的内存大小)*/
}while(0)
#define HASH_MIGRAGTE(OLD_TABLE, NEW_TABLE, NODE_TYPE, PTR_NAME, FOLD_FUNC) \
do{ \
ulint i2222; \
ulint cell_count2222; \
cell_count2222 = hash_get_n_cells(OLD_TABLE); \
\
for(i2222 = 0; i2222 < cell_count2222; i2222 ++){ \
NODE_TYPE* node2222 = HASH_GET_FIRST(TABLE, i2222); \
while(node2222 != NULL){ \
NODE_TYPE* next2222 = node2222->PTR_NAME; \
ulint fold2222 = FOLD_FUNC(node2222); \
HASH_INSERT(NODE_TYPE, PTR_NAME, NEW_TABLE, fold2222, node2222); \
node2222 = next2222; \
} \
} \
}while(0)
#endif