18 #include "NdbPoolImpl.hpp"
20 NdbMutex *NdbPool::pool_mutex = NULL;
27 Uint32 init_no_ndb_objects)
29 if (!initPoolMutex()) {
32 NdbMutex_Lock(pool_mutex);
34 if (the_pool != NULL) {
37 the_pool =
new NdbPool(cc, max_ndb_obj, no_conn_obj);
38 if (!the_pool->init(init_no_ndb_objects)) {
44 NdbMutex*
temp = pool_mutex;
48 NdbMutex_Unlock(pool_mutex);
50 NdbMutex_Destroy(temp);
56 NdbPool::drop_instance()
58 if (pool_mutex == NULL) {
61 NdbMutex_Lock(pool_mutex);
62 the_pool->release_all();
65 NdbMutex* temp = pool_mutex;
66 NdbMutex_Unlock(temp);
67 NdbMutex_Destroy(temp);
71 NdbPool::initPoolMutex()
73 bool ret_result =
false;
74 if (pool_mutex == NULL) {
75 pool_mutex = NdbMutex_Create();
76 ret_result = ((pool_mutex == NULL) ?
false :
true);
82 Uint32 max_no_objects,
83 Uint32 no_conn_objects)
85 if (no_conn_objects > 1024) {
86 no_conn_objects = 1024;
88 if (max_no_objects > MAX_NDB_OBJECTS) {
89 max_no_objects = MAX_NDB_OBJECTS;
90 }
else if (max_no_objects == 0) {
93 m_max_ndb_objects = max_no_objects;
94 m_no_of_conn_objects = no_conn_objects;
97 m_pool_reference = NULL;
99 m_first_free = NULL_POOL;
100 m_first_not_in_use = NULL_POOL;
101 m_last_free = NULL_POOL;
102 input_pool_cond = NULL;
103 output_pool_cond = NULL;
107 m_cluster_connection = cc;
112 NdbCondition_Destroy(input_pool_cond);
113 NdbCondition_Destroy(output_pool_cond);
117 NdbPool::release_all()
120 for (i = 0; i < m_max_ndb_objects + 1; i++) {
121 if (m_pool_reference[i].ndb_reference != NULL) {
122 assert(m_pool_reference[i].in_use);
123 assert(m_pool_reference[i].free_entry);
124 delete m_pool_reference[
i].ndb_reference;
127 delete [] m_pool_reference;
128 delete [] m_hash_entry;
129 m_pool_reference = NULL;
134 NdbPool::init(Uint32 init_no_objects)
136 bool ret_result =
false;
139 input_pool_cond = NdbCondition_Create();
140 output_pool_cond = NdbCondition_Create();
141 if (input_pool_cond == NULL || output_pool_cond == NULL) {
144 if (init_no_objects > m_max_ndb_objects) {
145 init_no_objects = m_max_ndb_objects;
147 if (init_no_objects == 0) {
150 m_pool_reference =
new NdbPool::POOL_STRUCT[m_max_ndb_objects + 1];
151 m_hash_entry =
new Uint8[POOL_HASH_TABLE_SIZE];
153 if ((m_pool_reference == NULL) || (m_hash_entry == NULL)) {
154 delete [] m_pool_reference;
155 delete [] m_hash_entry;
158 for (i = 0; i < m_max_ndb_objects + 1; i++) {
159 m_pool_reference[
i].ndb_reference = NULL;
160 m_pool_reference[
i].in_use =
false;
161 m_pool_reference[
i].next_free_object = i+1;
162 m_pool_reference[
i].prev_free_object = i-1;
163 m_pool_reference[
i].next_db_object = NULL_POOL;
164 m_pool_reference[
i].prev_db_object = NULL_POOL;
166 for (i = 0; i < POOL_HASH_TABLE_SIZE; i++) {
167 m_hash_entry[
i] = NULL_HASH;
169 m_pool_reference[m_max_ndb_objects].next_free_object = NULL_POOL;
170 m_pool_reference[1].prev_free_object = NULL_POOL;
171 m_first_not_in_use = 1;
172 m_no_of_objects = init_no_objects;
173 for (i = init_no_objects; i > 0 ; i--) {
175 if (!allocate_ndb(fake_id, (
const char*)NULL, (
const char*)NULL)) {
198 NdbPool::get_ndb_object(Uint32 &hint_id,
199 const char* a_catalog_name,
200 const char* a_schema_name)
203 Uint32 hash_entry = compute_hash(a_schema_name);
204 NdbMutex_Lock(pool_mutex);
209 if ((ret_ndb = get_hint_ndb(hint_id, hash_entry)) != NULL) {
216 if (a_schema_name && (ret_ndb = get_db_hash(hint_id,
226 if ((ret_ndb = get_free_list(hint_id, hash_entry)) != NULL) {
233 if (m_no_of_objects < m_max_ndb_objects) {
234 if (allocate_ndb(hint_id, a_catalog_name, a_schema_name)) {
235 assert((ret_ndb = get_hint_ndb(hint_id, hash_entry)) != NULL);
243 if ((ret_ndb = wait_free_ndb(hint_id)) != NULL) {
253 NdbMutex_Unlock(pool_mutex);
254 if (ret_ndb != NULL) {
266 NdbPool::return_ndb_object(
Ndb* returned_ndb, Uint32
id)
268 NdbMutex_Lock(pool_mutex);
269 assert(
id <= m_max_ndb_objects);
271 assert(returned_ndb == m_pool_reference[
id].ndb_reference);
272 bool wait_cond = m_waiting;
275 if (m_signal_count > 0) {
276 pool_cond = output_pool_cond;
279 pool_cond = input_pool_cond;
282 NdbMutex_Unlock(pool_mutex);
283 NdbCondition_Signal(pool_cond);
287 NdbMutex_Unlock(pool_mutex);
292 NdbPool::allocate_ndb(Uint32 &
id,
293 const char* a_catalog_name,
294 const char* a_schema_name)
297 if (m_first_not_in_use == NULL_POOL) {
301 a_ndb =
new Ndb(m_cluster_connection, a_schema_name, a_catalog_name);
303 a_ndb =
new Ndb(m_cluster_connection,
"");
308 a_ndb->
init(m_no_of_conn_objects);
311 id = m_first_not_in_use;
312 Uint32 allocated_id = m_first_not_in_use;
313 m_first_not_in_use = m_pool_reference[allocated_id].next_free_object;
315 m_pool_reference[allocated_id].ndb_reference = a_ndb;
316 m_pool_reference[allocated_id].in_use =
true;
317 m_pool_reference[allocated_id].free_entry =
false;
319 add_free_list(allocated_id);
320 add_db_hash(allocated_id);
325 NdbPool::add_free_list(Uint32
id)
327 assert(!m_pool_reference[
id].free_entry);
328 assert(m_pool_reference[
id].in_use);
329 m_pool_reference[
id].free_entry =
true;
330 m_pool_reference[
id].next_free_object = m_first_free;
331 m_pool_reference[
id].prev_free_object = (Uint8)NULL_POOL;
332 m_first_free = (Uint8)
id;
333 if (m_last_free == (Uint8)NULL_POOL) {
334 m_last_free = (Uint8)
id;
339 NdbPool::add_db_hash(Uint32
id)
341 Ndb* t_ndb = m_pool_reference[
id].ndb_reference;
343 Uint32 hash_entry = compute_hash(schema_name);
344 Uint8 next_db_entry = m_hash_entry[hash_entry];
345 m_pool_reference[
id].next_db_object = next_db_entry;
346 m_pool_reference[
id].prev_db_object = (Uint8)NULL_HASH;
347 m_hash_entry[hash_entry] = (Uint8)
id;
351 NdbPool::get_free_list(Uint32 &
id, Uint32 hash_entry)
353 if (m_first_free == NULL_POOL) {
357 Ndb* ret_ndb = get_hint_ndb(m_first_free, hash_entry);
358 assert(ret_ndb != NULL);
363 NdbPool::get_db_hash(Uint32 &
id,
365 const char *a_catalog_name,
366 const char *a_schema_name)
368 Uint32 entry_id = m_hash_entry[hash_entry];
370 while (entry_id != NULL_HASH) {
371 Ndb* t_ndb = m_pool_reference[entry_id].ndb_reference;
373 if (strcmp(a_catalog_name, a_ndb_catalog_name) == 0) {
375 if (strcmp(a_schema_name, a_ndb_schema_name) == 0) {
380 entry_id = m_pool_reference[entry_id].next_db_object;
384 Ndb* ret_ndb = get_hint_ndb(entry_id, hash_entry);
385 assert(ret_ndb != NULL);
392 NdbPool::get_hint_ndb(Uint32 hint_id, Uint32 hash_entry)
396 if ((hint_id != 0) &&
397 (hint_id <= m_max_ndb_objects) &&
398 (m_pool_reference[hint_id].in_use) &&
399 (m_pool_reference[hint_id].free_entry)) {
400 ret_ndb = m_pool_reference[hint_id].ndb_reference;
401 if (ret_ndb != NULL) {
413 remove_free_list(hint_id);
414 remove_db_hash(hint_id, hash_entry);
419 NdbPool::remove_free_list(Uint32
id)
421 Uint16 next_free_entry = m_pool_reference[
id].next_free_object;
422 Uint16 prev_free_entry = m_pool_reference[
id].prev_free_object;
423 if (prev_free_entry == (Uint8)NULL_POOL) {
424 m_first_free = next_free_entry;
426 m_pool_reference[prev_free_entry].next_free_object = next_free_entry;
428 if (next_free_entry == (Uint8)NULL_POOL) {
429 m_last_free = prev_free_entry;
431 m_pool_reference[next_free_entry].prev_free_object = prev_free_entry;
433 m_pool_reference[
id].next_free_object = NULL_POOL;
434 m_pool_reference[
id].prev_free_object = NULL_POOL;
435 m_pool_reference[
id].free_entry =
false;
439 NdbPool::remove_db_hash(Uint32
id, Uint32 hash_entry)
441 Uint16 next_free_entry = m_pool_reference[
id].next_db_object;
442 Uint16 prev_free_entry = m_pool_reference[
id].prev_db_object;
443 if (prev_free_entry == (Uint8)NULL_HASH) {
444 m_hash_entry[hash_entry] = (Uint8)next_free_entry;
446 m_pool_reference[prev_free_entry].next_db_object = next_free_entry;
448 if (next_free_entry == (Uint8)NULL_HASH) {
451 m_pool_reference[next_free_entry].prev_db_object = prev_free_entry;
453 m_pool_reference[
id].next_db_object = NULL_HASH;
454 m_pool_reference[
id].prev_db_object = NULL_HASH;
458 NdbPool::compute_hash(
const char *a_schema_name)
460 Uint32 len = Uint32(strlen(a_schema_name));
462 for (Uint32 i = 0; i < len; i++) {
463 Uint32 c = a_schema_name[
i];
464 h = (h << 5) + h + c;
466 h &= (POOL_HASH_TABLE_SIZE - 1);
471 NdbPool::wait_free_ndb(Uint32 &
id)
480 res = NdbCondition_WaitTimeout(input_pool_cond, pool_mutex, time_out);
481 if (tmp == input_pool_cond) {
485 if (m_output_queue == 0) {
486 switch_condition_queue();
490 }
while (res == 0 && m_first_wait == NULL_POOL);
491 if (res != 0 && m_first_wait == NULL_POOL) {
496 assert(m_waiting != 0 || m_first_wait == NULL_POOL);
497 return m_pool_reference[
id].ndb_reference;
501 NdbPool::remove_wait_list()
503 Uint32
id = m_first_wait;
504 m_first_wait = m_pool_reference[
id].next_free_object;
505 m_pool_reference[
id].next_free_object = NULL_POOL;
506 m_pool_reference[
id].prev_free_object = NULL_POOL;
507 m_pool_reference[
id].free_entry =
false;
511 NdbPool::add_wait_list(Uint32
id)
513 m_pool_reference[
id].next_free_object = m_first_wait;
518 NdbPool::switch_condition_queue()
520 m_signal_count = m_input_queue;
521 Uint16 move_queue = m_input_queue;
522 m_input_queue = m_output_queue;
523 m_output_queue = move_queue;
526 input_pool_cond = output_pool_cond;
527 output_pool_cond = move_cond;