11
11
#include "ha0ha.ic"
16
#endif /* UNIV_DEBUG */
17
#ifdef UNIV_SYNC_DEBUG
19
#endif /* UNIV_SYNC_DEBUG */
20
#include "page0page.h"
22
16
/*****************************************************************
23
17
Creates a hash table with >= n array cells. The actual number of cells is
24
18
chosen to be a prime number slightly bigger than n. */
29
23
/* out, own: created table */
24
ibool in_btr_search, /* in: TRUE if the hash table is used in
25
the btr_search module */
30
26
ulint n, /* in: number of array cells */
31
27
#ifdef UNIV_SYNC_DEBUG
32
28
ulint mutex_level, /* in: level of the mutexes in the latching
41
37
table = hash_create(n);
44
table->adaptive = TRUE;
45
#endif /* UNIV_DEBUG */
40
table->adaptive = TRUE;
42
table->adaptive = FALSE;
46
45
/* Creating MEM_HEAP_BTR_SEARCH type heaps can potentially fail,
47
46
but in practise it never should in this case, hence the asserts. */
49
48
if (n_mutexes == 0) {
50
table->heap = mem_heap_create_in_btr_search(
51
ut_min(4096, MEM_MAX_ALLOC_IN_BUF));
50
table->heap = mem_heap_create_in_btr_search(4096);
53
table->heap = mem_heap_create_in_buffer(4096);
59
61
table->heaps = mem_alloc(n_mutexes * sizeof(void*));
61
63
for (i = 0; i < n_mutexes; i++) {
62
table->heaps[i] = mem_heap_create_in_btr_search(4096);
63
ut_a(table->heaps[i]);
65
table->heaps[i] = mem_heap_create_in_btr_search(4096);
66
ut_a(table->heaps[i]);
68
table->heaps[i] = mem_heap_create_in_buffer(4096);
69
75
/*****************************************************************
70
Empties a hash table and frees the memory heaps. */
75
hash_table_t* table) /* in, own: hash table */
80
#ifdef UNIV_SYNC_DEBUG
81
ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EXCLUSIVE));
82
#endif /* UNIV_SYNC_DEBUG */
84
/* Free the memory heaps. */
87
for (i = 0; i < n; i++) {
88
mem_heap_free(table->heaps[i]);
91
/* Clear the hash table. */
92
n = hash_get_n_cells(table);
94
for (i = 0; i < n; i++) {
95
hash_get_nth_cell(table, i)->node = NULL;
99
/*****************************************************************
100
76
Inserts an entry into a hash table. If an entry with the same fold number
101
77
is found, its node is updated to point to the new data, and no new node
105
ha_insert_for_fold_func(
106
/*====================*/
107
83
/* out: TRUE if succeed, FALSE if no more
108
84
memory could be allocated */
109
85
hash_table_t* table, /* in: hash table */
111
87
the same fold value already exists, it is
112
88
updated to point to the same data, and no new
113
89
node is created! */
115
buf_block_t* block, /* in: buffer block containing the data */
116
#endif /* UNIV_DEBUG */
117
90
void* data) /* in: data, must not be NULL */
119
92
hash_cell_t* cell;
121
94
ha_node_t* prev_node;
95
buf_block_t* prev_block;
124
98
ut_ad(table && data);
125
ut_ad(block->frame == page_align(data));
126
99
ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
128
101
hash = hash_calc_hash(fold, table);
134
107
while (prev_node != NULL) {
135
108
if (prev_node->fold == fold) {
137
109
if (table->adaptive) {
138
buf_block_t* prev_block = prev_node->block;
139
ut_a(prev_block->frame
140
== page_align(prev_node->data));
110
prev_block = buf_block_align(prev_node->data);
141
111
ut_a(prev_block->n_pointers > 0);
142
112
prev_block->n_pointers--;
113
buf_block_align(data)->n_pointers++;
146
prev_node->block = block;
147
#endif /* UNIV_DEBUG */
148
116
prev_node->data = data;
169
ha_node_set_data(node, block, data);
137
ha_node_set_data(node, data);
172
139
if (table->adaptive) {
140
buf_block_align(data)->n_pointers++;
175
#endif /* UNIV_DEBUG */
176
143
node->fold = fold;
178
145
node->next = NULL;
199
166
/***************************************************************
200
167
Deletes a hash node. */
203
170
ha_delete_hash_node(
204
171
/*================*/
205
172
hash_table_t* table, /* in: hash table */
206
173
ha_node_t* del_node) /* in: node to be deleted */
209
175
if (table->adaptive) {
210
ut_a(del_node->block->frame = page_align(del_node->data));
211
ut_a(del_node->block->n_pointers > 0);
212
del_node->block->n_pointers--;
176
ut_a(buf_block_align(del_node->data)->n_pointers > 0);
177
buf_block_align(del_node->data)->n_pointers--;
214
#endif /* UNIV_DEBUG */
215
180
HASH_DELETE_AND_COMPACT(ha_node_t, next, table, del_node);
218
183
/*****************************************************************
219
184
Deletes an entry from a hash table. */
240
205
/*************************************************************
241
206
Looks for an element when we know the pointer to the data, and updates
242
207
the pointer to data, if found. */
245
ha_search_and_update_if_found_func(
246
/*===============================*/
210
ha_search_and_update_if_found(
211
/*==========================*/
247
212
hash_table_t* table, /* in: hash table */
248
213
ulint fold, /* in: folded value of the searched data */
249
214
void* data, /* in: pointer to the data */
251
buf_block_t* new_block,/* in: block containing new_data */
253
215
void* new_data)/* in: new pointer to the data */
257
219
ut_ad(!table->mutexes || mutex_own(hash_get_mutex(table, fold)));
258
ut_ad(new_block->frame == page_align(new_data));
260
221
node = ha_search_with_data(table, fold, data);
264
224
if (table->adaptive) {
265
ut_a(node->block->n_pointers > 0);
266
node->block->n_pointers--;
267
new_block->n_pointers++;
225
ut_a(buf_block_align(node->data)->n_pointers > 0);
226
buf_block_align(node->data)->n_pointers--;
227
buf_block_align(new_data)->n_pointers++;
270
node->block = new_block;
271
#endif /* UNIV_DEBUG */
272
230
node->data = new_data;
276
234
/*********************************************************************
277
235
Removes from the chain determined by fold all nodes whose data pointer
278
236
points to the page given. */
281
239
ha_remove_all_nodes_to_page(
282
240
/*========================*/
283
241
hash_table_t* table, /* in: hash table */
284
242
ulint fold, /* in: fold value */
285
const page_t* page) /* in: buffer page */
243
page_t* page) /* in: buffer page */
291
249
node = ha_chain_get_first(table, fold);
294
if (page_align(ha_node_get_data(node)) == page) {
252
if (buf_frame_align(ha_node_get_data(node)) == page) {
296
254
/* Remove the hash node */
312
270
node = ha_chain_get_first(table, fold);
315
ut_a(page_align(ha_node_get_data(node)) != page);
273
ut_a(buf_frame_align(ha_node_get_data(node)) != page);
317
275
node = ha_chain_get_next(node);