From ecbcddc03dc298ea1e6c0aa1a120bd0b4b04b3fd Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Fri, 16 Jul 2010 10:33:01 +0300 Subject: Improved speed of thr_alarm from O(N) to O(1). thr_alarm is used to handle timeouts and kill of connections. Fixed compiler warnings. queues.h and queues.c are now based on the UNIREG code and thus made BSD. Fix code to use new queue() interface. This mostly affects how you access elements in the queue. If USE_NET_CLEAR is not set, don't clear connection from unexpected characters. This should give a speed up when doing a lot of fast queries. Fixed some code in ma_ft_boolean_search.c that had not made it from myisam/ft_boolean_search.c include/queues.h: Use UNIREG code base (BSD) Changed init_queue() to take all initialization arguments. New interface to access elements in queue include/thr_alarm.h: Changed to use time_t instead of ulong (portability) Added index_in_queue, to be able to remove random element from queue in O(1) mysys/queues.c: Use UNIREG code base (BSD) init_queue() and reinit_queue() now takes more initialization arguments. (No need for init_queue_ex() anymore) Now one can tell queue_insert() to store in the element a pointer to where element is in queue. This allows one to remove elements from queue in O(1) instead of O(N) mysys/thr_alarm.c: Use new option in queue() to allow fast removal of elements. Do less inside LOCK_alarm mutex. This should give a major speed up of thr_alarm usage when there is many threads sql/create_options.cc: Fixed wrong printf sql/event_queue.cc: Use new queue interface() sql/filesort.cc: Use new queue interface() sql/ha_partition.cc: Use new queue interface() sql/ha_partition.h: Fixed compiler warning sql/item_cmpfunc.cc: Fixed compiler warning sql/item_subselect.cc: Use new queue interface() Removed not used variable sql/net_serv.cc: If USE_NET_CLEAR is not set, don't clear connection from unexpected characters. This should give a speed up when doing a lot of fast queries at the disadvantage that if there is a bug in the client protocol the connection will be dropped instead of being unnoticed. sql/opt_range.cc: Use new queue interface() Fixed compiler warnings sql/uniques.cc: Use new queue interface() storage/maria/ma_ft_boolean_search.c: Copy code from myisam/ft_boolean_search.c Use new queue interface() storage/maria/ma_ft_nlq_search.c: Use new queue interface() storage/maria/ma_sort.c: Use new queue interface() storage/maria/maria_pack.c: Use new queue interface() Use queue_fix() instead of own loop to fix queue. storage/myisam/ft_boolean_search.c: Use new queue interface() storage/myisam/ft_nlq_search.c: Use new queue interface() storage/myisam/mi_test_all.sh: Remove temporary file from last run storage/myisam/myisampack.c: Use new queue interface() Use queue_fix() instead of own loop to fix queue. storage/myisam/sort.c: Use new queue interface() storage/myisammrg/myrg_queue.c: Use new queue interface() storage/myisammrg/myrg_rnext.c: Use new queue interface() storage/myisammrg/myrg_rnext_same.c: Use new queue interface() storage/myisammrg/myrg_rprev.c: Use new queue interface() --- sql/event_queue.cc | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) (limited to 'sql/event_queue.cc') diff --git a/sql/event_queue.cc b/sql/event_queue.cc index d68dc8ef479..2a354fe6cfd 100644 --- a/sql/event_queue.cc +++ b/sql/event_queue.cc @@ -136,9 +136,9 @@ Event_queue::init_queue(THD *thd) LOCK_QUEUE_DATA(); - if (init_queue_ex(&queue, EVENT_QUEUE_INITIAL_SIZE , 0 /*offset*/, - 0 /*max_on_top*/, event_queue_element_compare_q, - NULL, EVENT_QUEUE_EXTENT)) + if (::init_queue(&queue, EVENT_QUEUE_INITIAL_SIZE , 0 /*offset*/, + 0 /*max_on_top*/, event_queue_element_compare_q, + NullS, 0, EVENT_QUEUE_EXTENT)) { sql_print_error("Event Scheduler: Can't initialize the execution queue"); goto err; @@ -325,11 +325,13 @@ void Event_queue::drop_matching_events(THD *thd, LEX_STRING pattern, bool (*comparator)(LEX_STRING, Event_basic *)) { - uint i= 0; + uint i; DBUG_ENTER("Event_queue::drop_matching_events"); DBUG_PRINT("enter", ("pattern=%s", pattern.str)); - while (i < queue.elements) + for (i= queue_first_element(&queue) ; + i <= queue_last_element(&queue) ; + ) { Event_queue_element *et= (Event_queue_element *) queue_element(&queue, i); DBUG_PRINT("info", ("[%s.%s]?", et->dbname.str, et->name.str)); @@ -339,7 +341,8 @@ Event_queue::drop_matching_events(THD *thd, LEX_STRING pattern, The queue is ordered. If we remove an element, then all elements after it will shift one position to the left, if we imagine it as an array from left to the right. In this case we should not - increment the counter and the (i < queue.elements) condition is ok. + increment the counter and the (i <= queue_last_element() condition + is ok. */ queue_remove(&queue, i); delete et; @@ -403,7 +406,9 @@ Event_queue::find_n_remove_event(LEX_STRING db, LEX_STRING name) uint i; DBUG_ENTER("Event_queue::find_n_remove_event"); - for (i= 0; i < queue.elements; ++i) + for (i= queue_first_element(&queue); + i <= queue_last_element(&queue); + i++) { Event_queue_element *et= (Event_queue_element *) queue_element(&queue, i); DBUG_PRINT("info", ("[%s.%s]==[%s.%s]?", db.str, name.str, @@ -441,7 +446,9 @@ Event_queue::recalculate_activation_times(THD *thd) LOCK_QUEUE_DATA(); DBUG_PRINT("info", ("%u loaded events to be recalculated", queue.elements)); - for (i= 0; i < queue.elements; i++) + for (i= queue_first_element(&queue); + i <= queue_last_element(&queue); + i++) { ((Event_queue_element*)queue_element(&queue, i))->compute_next_execution_time(); ((Event_queue_element*)queue_element(&queue, i))->update_timing_fields(thd); @@ -454,16 +461,19 @@ Event_queue::recalculate_activation_times(THD *thd) have removed all. The queue has been ordered in a way the disabled events are at the end. */ - for (i= queue.elements; i > 0; i--) + for (i= queue_last_element(&queue); + (int) i >= (int) queue_first_element(&queue); + i--) { - Event_queue_element *element = (Event_queue_element*)queue_element(&queue, i - 1); + Event_queue_element *element= + (Event_queue_element*)queue_element(&queue, i); if (element->status != Event_parse_data::DISABLED) break; /* This won't cause queue re-order, because we remove always the last element. */ - queue_remove(&queue, i - 1); + queue_remove(&queue, i); delete element; } UNLOCK_QUEUE_DATA(); @@ -499,7 +509,9 @@ Event_queue::empty_queue() sql_print_information("Event Scheduler: Purging the queue. %u events", queue.elements); /* empty the queue */ - for (i= 0; i < queue.elements; ++i) + for (i= queue_first_element(&queue); + i <= queue_last_element(&queue); + i++) { Event_queue_element *et= (Event_queue_element *) queue_element(&queue, i); delete et; @@ -525,7 +537,9 @@ Event_queue::dbug_dump_queue(time_t now) uint i; DBUG_ENTER("Event_queue::dbug_dump_queue"); DBUG_PRINT("info", ("Dumping queue . Elements=%u", queue.elements)); - for (i = 0; i < queue.elements; i++) + for (i= queue_first_element(&queue); + i <= queue_last_element(&queue); + i++) { et= ((Event_queue_element*)queue_element(&queue, i)); DBUG_PRINT("info", ("et: 0x%lx name: %s.%s", (long) et, @@ -592,7 +606,7 @@ Event_queue::get_top_for_execution_if_time(THD *thd, continue; } - top= ((Event_queue_element*) queue_element(&queue, 0)); + top= (Event_queue_element*) queue_top(&queue); thd->set_current_time(); /* Get current time */ @@ -634,10 +648,10 @@ Event_queue::get_top_for_execution_if_time(THD *thd, top->dbname.str, top->name.str, top->dropped? "Dropping.":""); delete top; - queue_remove(&queue, 0); + queue_remove_top(&queue); } else - queue_replaced(&queue); + queue_replace_top(&queue); dbug_dump_queue(thd->query_start()); break; -- cgit v1.2.1