Commit ecbcddc0 authored by Michael Widenius's avatar Michael Widenius

Improved speed of thr_alarm from O(N) to O(1). thr_alarm is used to handle...

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()
parent ceb5468f
......@@ -1940,3 +1940,4 @@ sql/client_plugin.c
*.dgcov
libmysqld/create_options.cc
storage/pbxt/bin/xtstat
libmysqld/sql_expression_cache.cc
/* Copyright (C) 2000 MySQL AB
/* Copyright (C) 2010 Monty Program Ab
All Rights reserved
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the following disclaimer
in the documentation and/or other materials provided with the
distribution.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
<COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
/*
Code for generell handling of priority Queues.
Implemention of queues from "Algoritms in C" by Robert Sedgewick.
Copyright Monty Program KB.
By monty.
*/
#ifndef _queues_h
......@@ -31,30 +39,34 @@ typedef struct st_queue {
void *first_cmp_arg;
uint elements;
uint max_elements;
uint offset_to_key; /* compare is done on element+offset */
uint offset_to_key; /* compare is done on element+offset */
uint offset_to_queue_pos; /* If we want to store position in element */
uint auto_extent;
int max_at_top; /* Normally 1, set to -1 if queue_top gives max */
int (*compare)(void *, uchar *,uchar *);
uint auto_extent;
} QUEUE;
#define queue_first_element(queue) 1
#define queue_last_element(queue) (queue)->elements
#define queue_top(queue) ((queue)->root[1])
#define queue_element(queue,index) ((queue)->root[index+1])
#define queue_element(queue,index) ((queue)->root[index])
#define queue_end(queue) ((queue)->root[(queue)->elements])
#define queue_replaced(queue) _downheap(queue,1)
#define queue_replace(queue, idx) _downheap(queue, idx, (queue)->root[idx])
#define queue_replace_top(queue) _downheap(queue, 1, (queue)->root[1])
#define queue_set_cmp_arg(queue, set_arg) (queue)->first_cmp_arg= set_arg
#define queue_set_max_at_top(queue, set_arg) \
(queue)->max_at_top= set_arg ? -1 : 1
#define queue_remove_top(queue_arg) queue_remove((queue_arg), queue_first_element(queue_arg))
typedef int (*queue_compare)(void *,uchar *, uchar *);
int init_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
pbool max_at_top, queue_compare compare,
void *first_cmp_arg);
int init_queue_ex(QUEUE *queue,uint max_elements,uint offset_to_key,
pbool max_at_top, queue_compare compare,
void *first_cmp_arg, uint auto_extent);
void *first_cmp_arg, uint offset_to_queue_pos,
uint auto_extent);
int reinit_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
pbool max_at_top, queue_compare compare,
void *first_cmp_arg);
void *first_cmp_arg, uint offset_to_queue_pos,
uint auto_extent);
int resize_queue(QUEUE *queue, uint max_elements);
void delete_queue(QUEUE *queue);
void queue_insert(QUEUE *queue,uchar *element);
......@@ -62,7 +74,7 @@ int queue_insert_safe(QUEUE *queue, uchar *element);
uchar *queue_remove(QUEUE *queue,uint idx);
#define queue_remove_all(queue) { (queue)->elements= 0; }
#define queue_is_full(queue) (queue->elements == queue->max_elements)
void _downheap(QUEUE *queue,uint idx);
void _downheap(QUEUE *queue, uint idx, uchar *element);
void queue_fix(QUEUE *queue);
#define is_queue_inited(queue) ((queue)->root != 0)
......
......@@ -34,7 +34,7 @@ extern "C" {
typedef struct st_alarm_info
{
ulong next_alarm_time;
time_t next_alarm_time;
uint active_alarms;
uint max_used_alarms;
} ALARM_INFO;
......@@ -78,10 +78,11 @@ typedef int thr_alarm_entry;
typedef thr_alarm_entry* thr_alarm_t;
typedef struct st_alarm {
ulong expire_time;
time_t expire_time;
thr_alarm_entry alarmed; /* set when alarm is due */
pthread_t thread;
my_thread_id thread_id;
uint index_in_queue;
my_bool malloced;
} ALARM;
......
This diff is collapsed.
......@@ -41,6 +41,19 @@ volatile my_bool alarm_thread_running= 0;
time_t next_alarm_expire_time= ~ (time_t) 0;
static sig_handler process_alarm_part2(int sig);
#ifdef DBUG_OFF
#define reset_index_in_queue(alarm_data)
#else
#define reset_index_in_queue(alarm_data) alarm_data->index_in_queue= 0;
#endif /* DBUG_OFF */
#ifndef USE_ONE_SIGNAL_HAND
#define one_signal_hand_sigmask(A,B,C) pthread_sigmask((A), (B), (C))
#else
#define one_signal_hand_sigmask(A,B,C)
#endif
#if !defined(__WIN__)
static pthread_mutex_t LOCK_alarm;
......@@ -72,8 +85,8 @@ void init_thr_alarm(uint max_alarms)
DBUG_ENTER("init_thr_alarm");
alarm_aborted=0;
next_alarm_expire_time= ~ (time_t) 0;
init_queue(&alarm_queue,max_alarms+1,offsetof(ALARM,expire_time),0,
compare_ulong,NullS);
init_queue(&alarm_queue, max_alarms+1, offsetof(ALARM,expire_time), 0,
compare_ulong, NullS, offsetof(ALARM, index_in_queue)+1, 0);
sigfillset(&full_signal_set); /* Neaded to block signals */
pthread_mutex_init(&LOCK_alarm,MY_MUTEX_INIT_FAST);
pthread_cond_init(&COND_alarm,NULL);
......@@ -151,7 +164,7 @@ void resize_thr_alarm(uint max_alarms)
my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
{
time_t now;
time_t now, next;
#ifndef USE_ONE_SIGNAL_HAND
sigset_t old_mask;
#endif
......@@ -161,79 +174,68 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
DBUG_PRINT("enter",("thread: %s sec: %d",my_thread_name(),sec));
now= my_time(0);
#ifndef USE_ONE_SIGNAL_HAND
pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
#endif
if (!alarm_data)
{
if (!(alarm_data=(ALARM*) my_malloc(sizeof(ALARM),MYF(MY_WME))))
goto abort_no_unlock;
alarm_data->malloced= 1;
}
else
alarm_data->malloced= 0;
next= now + sec;
alarm_data->expire_time= next;
alarm_data->alarmed= 0;
alarm_data->thread= current_my_thread_var->pthread_self;
alarm_data->thread_id= current_my_thread_var->id;
one_signal_hand_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
pthread_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */
if (alarm_aborted > 0)
if (unlikely(alarm_aborted))
{ /* No signal thread */
DBUG_PRINT("info", ("alarm aborted"));
*alrm= 0; /* No alarm */
pthread_mutex_unlock(&LOCK_alarm);
#ifndef USE_ONE_SIGNAL_HAND
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
#endif
DBUG_RETURN(1);
}
if (alarm_aborted < 0)
if (alarm_aborted > 0)
goto abort;
sec= 1; /* Abort mode */
}
if (alarm_queue.elements >= max_used_alarms)
{
if (alarm_queue.elements == alarm_queue.max_elements)
{
DBUG_PRINT("info", ("alarm queue full"));
fprintf(stderr,"Warning: thr_alarm queue is full\n");
*alrm= 0; /* No alarm */
pthread_mutex_unlock(&LOCK_alarm);
#ifndef USE_ONE_SIGNAL_HAND
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
#endif
DBUG_RETURN(1);
goto abort;
}
max_used_alarms=alarm_queue.elements+1;
}
reschedule= (ulong) next_alarm_expire_time > (ulong) now + sec;
if (!alarm_data)
{
if (!(alarm_data=(ALARM*) my_malloc(sizeof(ALARM),MYF(MY_WME))))
{
DBUG_PRINT("info", ("failed my_malloc()"));
*alrm= 0; /* No alarm */
pthread_mutex_unlock(&LOCK_alarm);
#ifndef USE_ONE_SIGNAL_HAND
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
#endif
DBUG_RETURN(1);
}
alarm_data->malloced=1;
}
else
alarm_data->malloced=0;
alarm_data->expire_time=now+sec;
alarm_data->alarmed=0;
alarm_data->thread= current_my_thread_var->pthread_self;
alarm_data->thread_id= current_my_thread_var->id;
reschedule= (ulong) next_alarm_expire_time > (ulong) next;
queue_insert(&alarm_queue,(uchar*) alarm_data);
assert(alarm_data->index_in_queue > 0);
/* Reschedule alarm if the current one has more than sec left */
if (reschedule)
if (unlikely(reschedule))
{
DBUG_PRINT("info", ("reschedule"));
if (pthread_equal(pthread_self(),alarm_thread))
{
alarm(sec); /* purecov: inspected */
next_alarm_expire_time= now + sec;
next_alarm_expire_time= next;
}
else
reschedule_alarms(); /* Reschedule alarms */
}
pthread_mutex_unlock(&LOCK_alarm);
#ifndef USE_ONE_SIGNAL_HAND
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
#endif
one_signal_hand_sigmask(SIG_SETMASK,&old_mask,NULL);
(*alrm)= &alarm_data->alarmed;
DBUG_RETURN(0);
abort:
if (alarm_data->malloced)
my_free(alarm_data, MYF(0));
pthread_mutex_unlock(&LOCK_alarm);
one_signal_hand_sigmask(SIG_SETMASK,&old_mask,NULL);
abort_no_unlock:
*alrm= 0; /* No alarm */
DBUG_RETURN(1);
}
......@@ -247,41 +249,18 @@ void thr_end_alarm(thr_alarm_t *alarmed)
#ifndef USE_ONE_SIGNAL_HAND
sigset_t old_mask;
#endif
uint i, found=0;
DBUG_ENTER("thr_end_alarm");
#ifndef USE_ONE_SIGNAL_HAND
pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
#endif
pthread_mutex_lock(&LOCK_alarm);
one_signal_hand_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
alarm_data= (ALARM*) ((uchar*) *alarmed - offsetof(ALARM,alarmed));
for (i=0 ; i < alarm_queue.elements ; i++)
{
if ((ALARM*) queue_element(&alarm_queue,i) == alarm_data)
{
queue_remove(&alarm_queue,i),MYF(0);
if (alarm_data->malloced)
my_free((uchar*) alarm_data,MYF(0));
found++;
#ifdef DBUG_OFF
break;
#endif
}
}
DBUG_ASSERT(!*alarmed || found == 1);
if (!found)
{
if (*alarmed)
fprintf(stderr,"Warning: Didn't find alarm 0x%lx in queue of %d alarms\n",
(long) *alarmed, alarm_queue.elements);
DBUG_PRINT("warning",("Didn't find alarm 0x%lx in queue\n",
(long) *alarmed));
}
pthread_mutex_lock(&LOCK_alarm);
DBUG_ASSERT(alarm_data->index_in_queue != 0);
DBUG_ASSERT(queue_element(&alarm_queue, alarm_data->index_in_queue) ==
alarm_data);
queue_remove(&alarm_queue, alarm_data->index_in_queue);
pthread_mutex_unlock(&LOCK_alarm);
#ifndef USE_ONE_SIGNAL_HAND
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
#endif
one_signal_hand_sigmask(SIG_SETMASK,&old_mask,NULL);
reset_index_in_queue(alarm_data);
DBUG_VOID_RETURN;
}
......@@ -344,12 +323,13 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused)))
#if defined(MAIN) && !defined(__bsdi__)
printf("process_alarm\n"); fflush(stdout);
#endif
if (alarm_queue.elements)
if (likely(alarm_queue.elements))
{
if (alarm_aborted)
if (unlikely(alarm_aborted))
{
uint i;
for (i=0 ; i < alarm_queue.elements ;)
for (i= queue_first_element(&alarm_queue) ;
i <= queue_last_element(&alarm_queue) ;)
{
alarm_data=(ALARM*) queue_element(&alarm_queue,i);
alarm_data->alarmed=1; /* Info to thread */
......@@ -360,6 +340,7 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused)))
printf("Warning: pthread_kill couldn't find thread!!!\n");
#endif
queue_remove(&alarm_queue,i); /* No thread. Remove alarm */
reset_index_in_queue(alarm_data);
}
else
i++; /* Signal next thread */
......@@ -371,8 +352,8 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused)))
}
else
{
ulong now=(ulong) my_time(0);
ulong next=now+10-(now%10);
time_t now= my_time(0);
time_t next= now+10-(now%10);
while ((alarm_data=(ALARM*) queue_top(&alarm_queue))->expire_time <= now)
{
alarm_data->alarmed=1; /* Info to thread */
......@@ -382,15 +363,16 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused)))
{
#ifdef MAIN
printf("Warning: pthread_kill couldn't find thread!!!\n");
#endif
queue_remove(&alarm_queue,0); /* No thread. Remove alarm */
#endif /* MAIN */
queue_remove_top(&alarm_queue); /* No thread. Remove alarm */
reset_index_in_queue(alarm_data);
if (!alarm_queue.elements)
break;
}
else
{
alarm_data->expire_time=next;
queue_replaced(&alarm_queue);
queue_replace_top(&alarm_queue);
}
}
#ifndef USE_ALARM_THREAD
......@@ -486,13 +468,15 @@ void thr_alarm_kill(my_thread_id thread_id)
if (alarm_aborted)
return;
pthread_mutex_lock(&LOCK_alarm);
for (i=0 ; i < alarm_queue.elements ; i++)
for (i= queue_first_element(&alarm_queue) ;
i <= queue_last_element(&alarm_queue);
i++)
{
if (((ALARM*) queue_element(&alarm_queue,i))->thread_id == thread_id)
ALARM *element= (ALARM*) queue_element(&alarm_queue,i);
if (element->thread_id == thread_id)
{
ALARM *tmp=(ALARM*) queue_remove(&alarm_queue,i);
tmp->expire_time=0;
queue_insert(&alarm_queue,(uchar*) tmp);
element->expire_time= 0;
queue_replace(&alarm_queue, i);
reschedule_alarms();
break;
}
......@@ -508,7 +492,7 @@ void thr_alarm_info(ALARM_INFO *info)
info->max_used_alarms= max_used_alarms;
if ((info->active_alarms= alarm_queue.elements))
{
ulong now=(ulong) my_time(0);
time_t now= my_time(0);
long time_diff;
ALARM *alarm_data= (ALARM*) queue_top(&alarm_queue);
time_diff= (long) (alarm_data->expire_time - now);
......@@ -556,7 +540,7 @@ static void *alarm_handler(void *arg __attribute__((unused)))
{
if (alarm_queue.elements)
{
ulong sleep_time,now= my_time(0);
time_t sleep_time,now= my_time(0);
if (alarm_aborted)
sleep_time=now+1;
else
......@@ -792,20 +776,6 @@ static void *test_thread(void *arg)
return 0;
}
#ifdef USE_ONE_SIGNAL_HAND
static sig_handler print_signal_warning(int sig)
{
printf("Warning: Got signal %d from thread %s\n",sig,my_thread_name());
fflush(stdout);
#ifdef DONT_REMEMBER_SIGNAL
my_sigset(sig,print_signal_warning); /* int. thread system calls */
#endif
if (sig == SIGALRM)
alarm(2); /* reschedule alarm */
}
#endif /* USE_ONE_SIGNAL_HAND */
static void *signal_hand(void *arg __attribute__((unused)))
{
sigset_t set;
......
......@@ -583,9 +583,9 @@ my_bool engine_table_options_frm_read(const uchar *buff, uint length,
}
if (buff < buff_end)
sql_print_warning("Table %`s was created in a later MariaDB version - "
sql_print_warning("Table '%s' was created in a later MariaDB version - "
"unknown table attributes were ignored",
share->table_name);
share->table_name.str);
DBUG_RETURN(buff > buff_end);
}
......
......@@ -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;
......
......@@ -1151,7 +1151,9 @@ uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
{
uchar *reuse_end= reuse->base + reuse->max_keys * key_length;
for (uint i= 0; i < queue->elements; ++i)
for (uint i= queue_first_element(queue);
i <= queue_last_element(queue);
i++)
{
BUFFPEK *bp= (BUFFPEK *) queue_element(queue, i);
if (bp->base + bp->max_keys * key_length == reuse->base)
......@@ -1240,7 +1242,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
first_cmp_arg= (void*) &sort_length;
}
if (init_queue(&queue, (uint) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0,
(queue_compare) cmp, first_cmp_arg))
(queue_compare) cmp, first_cmp_arg, 0, 0))
DBUG_RETURN(1); /* purecov: inspected */
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
{
......@@ -1277,7 +1279,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
error= 0; /* purecov: inspected */
goto end; /* purecov: inspected */
}
queue_replaced(&queue); // Top element has been used
queue_replace_top(&queue); // Top element has been used
}
else
cmp= 0; // Not unique
......@@ -1325,14 +1327,14 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
if (!(error= (int) read_to_buffer(from_file,buffpek,
rec_length)))
{
VOID(queue_remove(&queue,0));
VOID(queue_remove_top(&queue));
reuse_freed_buff(&queue, buffpek, rec_length);
break; /* One buffer have been removed */
}
else if (error == -1)
goto err; /* purecov: inspected */
}
queue_replaced(&queue); /* Top element has been replaced */
queue_replace_top(&queue); /* Top element has been replaced */
}
}
buffpek= (BUFFPEK*) queue_top(&queue);
......
......@@ -2567,7 +2567,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
Initialize priority queue, initialized to reading forward.
*/
if ((error= init_queue(&m_queue, m_tot_parts, (uint) PARTITION_BYTES_IN_POS,
0, key_rec_cmp, (void*)this)))
0, key_rec_cmp, (void*)this, 0, 0)))
goto err_handler;
/*
......@@ -4622,7 +4622,7 @@ int ha_partition::handle_unordered_scan_next_partition(uchar * buf)
int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
{
uint i;
uint j= 0;
uint j= queue_first_element(&m_queue);
bool found= FALSE;
DBUG_ENTER("ha_partition::handle_ordered_index_scan");
......@@ -4716,7 +4716,7 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
*/
queue_set_max_at_top(&m_queue, reverse_order);
queue_set_cmp_arg(&m_queue, (void*)m_curr_key_info);
m_queue.elements= j;
m_queue.elements= j - queue_first_element(&m_queue);
queue_fix(&m_queue);
return_top_record(buf);
table->status= 0;
......@@ -4787,7 +4787,7 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same)
if (error == HA_ERR_END_OF_FILE)
{
/* Return next buffered row */
queue_remove(&m_queue, (uint) 0);
queue_remove_top(&m_queue);
if (m_queue.elements)
{
DBUG_PRINT("info", ("Record returned from partition %u (2)",
......@@ -4799,7 +4799,7 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same)
}
DBUG_RETURN(error);
}
queue_replaced(&m_queue);
queue_replace_top(&m_queue);
return_top_record(buf);
DBUG_PRINT("info", ("Record returned from partition %u", m_top_entry));
DBUG_RETURN(0);
......@@ -4830,7 +4830,7 @@ int ha_partition::handle_ordered_prev(uchar *buf)
{
if (error == HA_ERR_END_OF_FILE)
{
queue_remove(&m_queue, (uint) 0);
queue_remove_top(&m_queue);
if (m_queue.elements)
{
return_top_record(buf);
......@@ -4842,7 +4842,7 @@ int ha_partition::handle_ordered_prev(uchar *buf)
}
DBUG_RETURN(error);
}
queue_replaced(&m_queue);
queue_replace_top(&m_queue);
return_top_record(buf);
DBUG_PRINT("info", ("Record returned from partition %d", m_top_entry));
DBUG_RETURN(0);
......
......@@ -1129,7 +1129,7 @@ class ha_partition :public handler
virtual handlerton *partition_ht() const
{
handlerton *h= m_file[0]->ht;
for (int i=1; i < m_tot_parts; i++)
for (uint i=1; i < m_tot_parts; i++)
DBUG_ASSERT(h == m_file[i]->ht);
return h;
}
......
......@@ -1778,10 +1778,12 @@ Item *Item_in_optimizer::expr_cache_insert_transformer(uchar *thd_arg)
if (args[0]->cols() == 1)
depends_on.push_front((Item**)args);
else
for (int i= 0; i < args[0]->cols(); i++)
{
for (uint i= 0; i < args[0]->cols(); i++)
{
depends_on.push_front(args[0]->addr(i));
}
}
if (args[1]->expr_cache_is_needed(thd))
DBUG_RETURN(set_expr_cache(thd, depends_on));
......
......@@ -3957,8 +3957,6 @@ subselect_hash_sj_engine::make_unique_engine()
Item_iterator_row it(item_in->left_expr);
/* The only index on the temporary table. */
KEY *tmp_key= tmp_table->key_info;
/* Number of keyparts in tmp_key. */
uint tmp_key_parts= tmp_key->key_parts;
JOIN_TAB *tab;
DBUG_ENTER("subselect_hash_sj_engine::make_unique_engine");
......@@ -4879,7 +4877,8 @@ subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts,
merge_keys[i]->sort_keys();
if (init_queue(&pq, keys_count, 0, FALSE,
subselect_rowid_merge_engine::cmp_keys_by_cur_rownum, NULL))
subselect_rowid_merge_engine::cmp_keys_by_cur_rownum, NULL,
0, 0))
return TRUE;
return FALSE;
......
......@@ -262,18 +262,20 @@ static int net_data_is_ready(my_socket sd)
#endif /* EMBEDDED_LIBRARY */
/**
Remove unwanted characters from connection
and check if disconnected.
Intialize NET handler for new reads:
Read from socket until there is nothing more to read. Discard
what is read.
- Read from socket until there is nothing more to read. Discard
what is read.
- Initialize net for new net_read/net_write calls.
If there is anything when to read 'net_clear' is called this
normally indicates an error in the protocol.
If there is anything when to read 'net_clear' is called this
normally indicates an error in the protocol. Normally one should not
need to do clear the communication buffer. If one compiles without
-DUSE_NET_CLEAR then one wins one read call / query.
When connection is properly closed (for TCP it means with
a FIN packet), then select() considers a socket "ready to read",
in the sense that there's EOF to read, but read() returns 0.
When connection is properly closed (for TCP it means with
a FIN packet), then select() considers a socket "ready to read",
in the sense that there's EOF to read, but read() returns 0.
@param net NET handler
@param clear_buffer if <> 0, then clear all data from comm buff
......@@ -281,20 +283,18 @@ static int net_data_is_ready(my_socket sd)
void net_clear(NET *net, my_bool clear_buffer __attribute__((unused)))
{
#if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)
size_t count;
int ready;
#endif
DBUG_ENTER("net_clear");
/*
We don't do a clear in case of DBUG_OFF to catch bugs
in the protocol handling
We don't do a clear in case of not DBUG_OFF to catch bugs in the
protocol handling.
*/
#if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)
#if (!defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)) || defined(USE_NET_CLEAR)
if (clear_buffer)
{
size_t count;
int ready;
while ((ready= net_data_is_ready(net->vio->sd)) > 0)
{
/* The socket is ready */
......
......@@ -1155,10 +1155,7 @@ QUICK_SELECT_I::QUICK_SELECT_I()
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr,
bool no_alloc, MEM_ROOT *parent_alloc,
bool *create_error)
:dont_free(0),doing_key_read(0),/*error(0),*/free_file(0),/*in_range(0),*/cur_range(NULL),last_range(0)
//psergey3-merge: check whether we need doing_key_read and last_range
// was:
// :free_file(0),cur_range(NULL),last_range(0),dont_free(0)
:doing_key_read(0),/*error(0),*/free_file(0),/*in_range(0),*/cur_range(NULL),last_range(0),dont_free(0)
{
my_bitmap_map *bitmap;
DBUG_ENTER("QUICK_RANGE_SELECT::QUICK_RANGE_SELECT");
......@@ -1594,7 +1591,7 @@ int QUICK_ROR_UNION_SELECT::init()
DBUG_ENTER("QUICK_ROR_UNION_SELECT::init");
if (init_queue(&queue, quick_selects.elements, 0,
FALSE , QUICK_ROR_UNION_SELECT::queue_cmp,
(void*) this))
(void*) this, 0, 0))
{
bzero(&queue, sizeof(QUEUE));
DBUG_RETURN(1);
......@@ -8293,12 +8290,12 @@ int QUICK_ROR_UNION_SELECT::get_next()
{
if (error != HA_ERR_END_OF_FILE)
DBUG_RETURN(error);
queue_remove(&queue, 0);
queue_remove_top(&queue);
}
else
{
quick->save_last_pos();
queue_replaced(&queue);
queue_replace_top(&queue);
}
if (!have_prev_rowid)
......
......@@ -423,7 +423,7 @@ static bool merge_walk(uchar *merge_buffer, ulong merge_buffer_size,
if (end <= begin ||
merge_buffer_size < (ulong) (key_length * (end - begin + 1)) ||
init_queue(&queue, (uint) (end - begin), offsetof(BUFFPEK, key), 0,
buffpek_compare, &compare_context))
buffpek_compare, &compare_context, 0, 0))
return 1;
/* we need space for one key when a piece of merge buffer is re-read */
merge_buffer_size-= key_length;
......@@ -468,7 +468,7 @@ static bool merge_walk(uchar *merge_buffer, ulong merge_buffer_size,
*/
top->key+= key_length;
if (--top->mem_count)
queue_replaced(&queue);
queue_replace_top(&queue);
else /* next piece should be read */
{
/* save old_key not to overwrite it in read_to_buffer */
......@@ -478,14 +478,14 @@ static bool merge_walk(uchar *merge_buffer, ulong merge_buffer_size,
if (bytes_read == (uint) (-1))
goto end;
else if (bytes_read > 0) /* top->key, top->mem_count are reset */
queue_replaced(&queue); /* in read_to_buffer */
queue_replace_top(&queue); /* in read_to_buffer */
else
{
/*
Tree for old 'top' element is empty: remove it from the queue and
give all its memory to the nearest tree.
*/
queue_remove(&queue, 0);
queue_remove_top(&queue);
reuse_freed_buff(&queue, top, key_length);
}
}
......
......@@ -473,14 +473,15 @@ static void _ftb_init_index_search(FT_INFO *ftb)
int i;
FTB_WORD *ftbw;
if ((ftb->state != READY && ftb->state !=INDEX_DONE) ||
ftb->keynr == NO_SUCH_KEY)
if (ftb->state == UNINITIALIZED || ftb->keynr == NO_SUCH_KEY)
return;
ftb->state=INDEX_SEARCH;
for (i=ftb->queue.elements; i; i--)
for (i= queue_last_element(&ftb->queue);
(int) i >= (int) queue_first_element(&ftb->queue);
i--)
{
ftbw=(FTB_WORD *)(ftb->queue.root[i]);
ftbw=(FTB_WORD *)(queue_element(&ftb->queue, i));
if (ftbw->flags & FTB_FLAG_TRUNC)
{
......@@ -585,7 +586,7 @@ FT_INFO * maria_ft_init_boolean_search(MARIA_HA *info, uint keynr,
sizeof(void *))))
goto err;
reinit_queue(&ftb->queue, ftb->queue.max_elements, 0, 0,
(int (*)(void*, uchar*, uchar*))FTB_WORD_cmp, 0);
(int (*)(void*, uchar*, uchar*))FTB_WORD_cmp, 0, 0, 0);
for (ftbw= ftb->last_word; ftbw; ftbw= ftbw->prev)
queue_insert(&ftb->queue, (uchar *)ftbw);
ftb->list=(FTB_WORD **)alloc_root(&ftb->mem_root,
......@@ -828,7 +829,7 @@ int maria_ft_boolean_read_next(FT_INFO *ftb, char *record)
/* update queue */
_ft2_search(ftb, ftbw, 0);
queue_replaced(& ftb->queue);
queue_replace_top(&ftb->queue);
}
ftbe=ftb->root;
......
......@@ -253,12 +253,12 @@ FT_INFO *maria_ft_init_nlq_search(MARIA_HA *info, uint keynr, uchar *query,
{
QUEUE best;
init_queue(&best,ft_query_expansion_limit,0,0, (queue_compare) &FT_DOC_cmp,
0);
0, 0, 0);
tree_walk(&aio.dtree, (tree_walk_action) &walk_and_push,
&best, left_root_right);
while (best.elements)
{
my_off_t docid=((FT_DOC *)queue_remove(& best, 0))->dpos;
my_off_t docid= ((FT_DOC *)queue_remove_top(&best))->dpos;
if (!(*info->read_record)(info, record, docid))
{
info->update|= HA_STATE_AKTIV;
......
......@@ -933,7 +933,7 @@ merge_buffers(MARIA_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
if (init_queue(&queue,(uint) (Tb-Fb)+1,offsetof(BUFFPEK,key),0,
(int (*)(void*, uchar *,uchar*)) info->key_cmp,
(void*) info))
(void*) info, 0, 0))
DBUG_RETURN(1); /* purecov: inspected */
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
......@@ -982,7 +982,7 @@ merge_buffers(MARIA_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
uchar *base= buffpek->base;
uint max_keys=buffpek->max_keys;
VOID(queue_remove(&queue,0));
VOID(queue_remove_top(&queue));
/* Put room used by buffer to use in other buffer */
for (refpek= (BUFFPEK**) &queue_top(&queue);
......@@ -1007,7 +1007,7 @@ merge_buffers(MARIA_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
}
else if (error == -1)
goto err; /* purecov: inspected */
queue_replaced(&queue); /* Top element has been replaced */
queue_replace_top(&queue); /* Top element has been replaced */
}
}
buffpek=(BUFFPEK*) queue_top(&queue);
......
......@@ -590,7 +590,7 @@ static int compress(PACK_MRG_INFO *mrg,char *result_table)
Create a global priority queue in preparation for making
temporary Huffman trees.
*/
if (init_queue(&queue,256,0,0,compare_huff_elements,0))
if (init_queue(&queue, 256, 0, 0, compare_huff_elements, 0, 0, 0))
goto err;
/*
......@@ -1521,7 +1521,7 @@ static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts)
if (queue.max_elements < found)
{
delete_queue(&queue);
if (init_queue(&queue,found,0,0,compare_huff_elements,0))
if (init_queue(&queue,found, 0, 0, compare_huff_elements, 0, 0, 0))
return -1;
}
......@@ -1625,8 +1625,7 @@ static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts)
Make a priority queue from the queue. Construct its index so that we
have a partially ordered tree.
*/
for (i=found/2 ; i > 0 ; i--)
_downheap(&queue,i);
queue_fix(&queue);
/* The Huffman algorithm. */
bytes_packed=0; bits_packed=0;
......@@ -1637,12 +1636,9 @@ static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts)
Popping from a priority queue includes a re-ordering of the queue,
to get the next least incidence element to the top.
*/
a=(HUFF_ELEMENT*) queue_remove(&queue,0);
/*
Copy the next least incidence element. The queue implementation
reserves root[0] for temporary purposes. root[1] is the top.
*/
b=(HUFF_ELEMENT*) queue.root[1];
a=(HUFF_ELEMENT*) queue_remove_top(&queue);
/* Copy the next least incidence element */
b=(HUFF_ELEMENT*) queue_top(&queue);
/* Get a new element from the element buffer. */
new_huff_el=huff_tree->element_buffer+found+i;
/* The new element gets the sum of the two least incidence elements. */
......@@ -1664,8 +1660,8 @@ static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts)
Replace the copied top element by the new element and re-order the
queue.
*/
queue.root[1]=(uchar*) new_huff_el;
queue_replaced(&queue);
queue_top(&queue)= (uchar*) new_huff_el;
queue_replace_top(&queue);
}
huff_tree->root=(HUFF_ELEMENT*) queue.root[1];
huff_tree->bytes_packed=bytes_packed+(bits_packed+7)/8;
......@@ -1796,8 +1792,7 @@ static my_off_t calc_packed_length(HUFF_COUNTS *huff_counts,
Make a priority queue from the queue. Construct its index so that we
have a partially ordered tree.
*/
for (i=(found+1)/2 ; i > 0 ; i--)
_downheap(&queue,i);
queue_fix(&queue);
/* The Huffman algorithm. */
for (i=0 ; i < found-1 ; i++)
......@@ -1811,12 +1806,9 @@ static my_off_t calc_packed_length(HUFF_COUNTS *huff_counts,
incidence). Popping from a priority queue includes a re-ordering
of the queue, to get the next least incidence element to the top.
*/
a= (my_off_t*) queue_remove(&queue, 0);
/*
Copy the next least incidence element. The queue implementation
reserves root[0] for temporary purposes. root[1] is the top.
*/
b= (my_off_t*) queue.root[1];
a= (my_off_t*) queue_remove_top(&queue);
/* Copy the next least incidence element. */
b= (my_off_t*) queue_top(&queue);
/* Create a new element in a local (automatic) buffer. */
new_huff_el= element_buffer + i;
/* The new element gets the sum of the two least incidence elements. */
......@@ -1836,8 +1828,8 @@ static my_off_t calc_packed_length(HUFF_COUNTS *huff_counts,
queue. This successively replaces the references to counts by
references to HUFF_ELEMENTs.
*/
queue.root[1]=(uchar*) new_huff_el;
queue_replaced(&queue);
queue_top(&queue)= (uchar*) new_huff_el;
queue_replace_top(&queue);
}
DBUG_RETURN(bytes_packed+(bits_packed+7)/8);
}
......
......@@ -482,16 +482,18 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
static void _ftb_init_index_search(FT_INFO *ftb)
{
int i;
uint i;
FTB_WORD *ftbw;
if (ftb->state == UNINITIALIZED || ftb->keynr == NO_SUCH_KEY)
return;
ftb->state=INDEX_SEARCH;
for (i=ftb->queue.elements; i; i--)
for (i= queue_last_element(&ftb->queue);
(int) i >= (int) queue_first_element(&ftb->queue);
i--)
{
ftbw=(FTB_WORD *)(ftb->queue.root[i]);
ftbw=(FTB_WORD *)(queue_element(&ftb->queue, i));
if (ftbw->flags & FTB_FLAG_TRUNC)
{
......@@ -595,12 +597,12 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, uchar *query,
sizeof(void *))))
goto err;
reinit_queue(&ftb->queue, ftb->queue.max_elements, 0, 0,
(int (*)(void*, uchar*, uchar*))FTB_WORD_cmp, 0);
(int (*)(void*, uchar*, uchar*))FTB_WORD_cmp, 0, 0, 0);
for (ftbw= ftb->last_word; ftbw; ftbw= ftbw->prev)
queue_insert(&ftb->queue, (uchar *)ftbw);
ftb->list=(FTB_WORD **)alloc_root(&ftb->mem_root,
sizeof(FTB_WORD *)*ftb->queue.elements);
memcpy(ftb->list, ftb->queue.root+1, sizeof(FTB_WORD *)*ftb->queue.elements);
memcpy(ftb->list, &queue_top(&ftb->queue), sizeof(FTB_WORD *)*ftb->queue.elements);
my_qsort2(ftb->list, ftb->queue.elements, sizeof(FTB_WORD *),
(qsort2_cmp)FTB_WORD_cmp_list, (void*) ftb->charset);
if (ftb->queue.elements<2) ftb->with_scan &= ~FTB_FLAG_TRUNC;
......@@ -839,7 +841,7 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record)
/* update queue */
_ft2_search(ftb, ftbw, 0);
queue_replaced(& ftb->queue);
queue_replace_top(&ftb->queue);
}
ftbe=ftb->root;
......
......@@ -250,12 +250,12 @@ FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, uchar *query,
{
QUEUE best;
init_queue(&best,ft_query_expansion_limit,0,0, (queue_compare) &FT_DOC_cmp,
0);
0, 0, 0);
tree_walk(&aio.dtree, (tree_walk_action) &walk_and_push,
&best, left_root_right);
while (best.elements)
{
my_off_t docid=((FT_DOC *)queue_remove(& best, 0))->dpos;
my_off_t docid= ((FT_DOC *)queue_remove_top(&best))->dpos;
if (!(*info->read_record)(info,docid,record))
{
info->update|= HA_STATE_AKTIV;
......
......@@ -5,6 +5,7 @@
valgrind="valgrind --alignment=8 --leak-check=yes"
silent="-s"
rm -f test1.TMD
if test -f mi_test1$MACH ; then suffix=$MACH ; else suffix=""; fi
./mi_test1$suffix $silent
......
......@@ -576,7 +576,7 @@ static int compress(PACK_MRG_INFO *mrg,char *result_table)
Create a global priority queue in preparation for making
temporary Huffman trees.
*/
if (init_queue(&queue,256,0,0,compare_huff_elements,0))
if (init_queue(&queue, 256, 0, 0, compare_huff_elements, 0, 0, 0))
goto err;
/*
......@@ -1511,7 +1511,7 @@ static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts)
if (queue.max_elements < found)
{
delete_queue(&queue);
if (init_queue(&queue,found,0,0,compare_huff_elements,0))
if (init_queue(&queue,found, 0, 0, compare_huff_elements, 0, 0, 0))
return -1;
}
......@@ -1615,8 +1615,7 @@ static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts)
Make a priority queue from the queue. Construct its index so that we
have a partially ordered tree.
*/
for (i=found/2 ; i > 0 ; i--)
_downheap(&queue,i);
queue_fix(&queue);
/* The Huffman algorithm. */
bytes_packed=0; bits_packed=0;
......@@ -1627,12 +1626,9 @@ static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts)
Popping from a priority queue includes a re-ordering of the queue,
to get the next least incidence element to the top.
*/
a=(HUFF_ELEMENT*) queue_remove(&queue,0);
/*
Copy the next least incidence element. The queue implementation
reserves root[0] for temporary purposes. root[1] is the top.
*/
b=(HUFF_ELEMENT*) queue.root[1];
a=(HUFF_ELEMENT*) queue_remove_top(&queue);
/* Copy the next least incidence element */
b=(HUFF_ELEMENT*) queue_top(&queue);
/* Get a new element from the element buffer. */
new_huff_el=huff_tree->element_buffer+found+i;
/* The new element gets the sum of the two least incidence elements. */
......@@ -1654,8 +1650,8 @@ static int make_huff_tree(HUFF_TREE *huff_tree, HUFF_COUNTS *huff_counts)
Replace the copied top element by the new element and re-order the
queue.
*/
queue.root[1]=(uchar*) new_huff_el;
queue_replaced(&queue);
queue_top(&queue)= (uchar*) new_huff_el;
queue_replace_top(&queue);
}
huff_tree->root=(HUFF_ELEMENT*) queue.root[1];
huff_tree->bytes_packed=bytes_packed+(bits_packed+7)/8;
......@@ -1786,8 +1782,7 @@ static my_off_t calc_packed_length(HUFF_COUNTS *huff_counts,
Make a priority queue from the queue. Construct its index so that we
have a partially ordered tree.
*/
for (i=(found+1)/2 ; i > 0 ; i--)
_downheap(&queue,i);
queue_fix(&queue);
/* The Huffman algorithm. */
for (i=0 ; i < found-1 ; i++)
......@@ -1801,12 +1796,9 @@ static my_off_t calc_packed_length(HUFF_COUNTS *huff_counts,
incidence). Popping from a priority queue includes a re-ordering
of the queue, to get the next least incidence element to the top.
*/
a= (my_off_t*) queue_remove(&queue, 0);
/*
Copy the next least incidence element. The queue implementation
reserves root[0] for temporary purposes. root[1] is the top.
*/
b= (my_off_t*) queue.root[1];
a= (my_off_t*) queue_remove_top(&queue);
/* Copy the next least incidence element. */
b= (my_off_t*) queue_top(&queue);
/* Create a new element in a local (automatic) buffer. */
new_huff_el= element_buffer + i;
/* The new element gets the sum of the two least incidence elements. */
......@@ -1826,8 +1818,8 @@ static my_off_t calc_packed_length(HUFF_COUNTS *huff_counts,
queue. This successively replaces the references to counts by
references to HUFF_ELEMENTs.
*/
queue.root[1]=(uchar*) new_huff_el;
queue_replaced(&queue);
queue_top(&queue)= (uchar*) new_huff_el;
queue_replace_top(&queue);
}
DBUG_RETURN(bytes_packed+(bits_packed+7)/8);
}
......
......@@ -920,7 +920,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
if (init_queue(&queue,(uint) (Tb-Fb)+1,offsetof(BUFFPEK,key),0,
(int (*)(void*, uchar *,uchar*)) info->key_cmp,
(void*) info))
(void*) info, 0, 0))
DBUG_RETURN(1); /* purecov: inspected */
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
......@@ -969,7 +969,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
uchar *base= buffpek->base;
uint max_keys=buffpek->max_keys;
VOID(queue_remove(&queue,0));
VOID(queue_remove_top(&queue));
/* Put room used by buffer to use in other buffer */
for (refpek= (BUFFPEK**) &queue_top(&queue);
......@@ -994,7 +994,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
}
else if (error == -1)
goto err; /* purecov: inspected */
queue_replaced(&queue); /* Top element has been replaced */
queue_replace_top(&queue); /* Top element has been replaced */
}
}
buffpek=(BUFFPEK*) queue_top(&queue);
......
......@@ -52,7 +52,7 @@ int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag)
if (init_queue(q,info->tables, 0,
(myisam_readnext_vec[search_flag] == SEARCH_SMALLER),
queue_key_cmp,
info->open_tables->table->s->keyinfo[inx].seg))
info->open_tables->table->s->keyinfo[inx].seg, 0, 0))
error=my_errno;
}
else
......@@ -60,7 +60,7 @@ int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag)
if (reinit_queue(q,info->tables, 0,
(myisam_readnext_vec[search_flag] == SEARCH_SMALLER),
queue_key_cmp,
info->open_tables->table->s->keyinfo[inx].seg))
info->open_tables->table->s->keyinfo[inx].seg, 0, 0))
error=my_errno;
}
}
......
......@@ -32,7 +32,7 @@ int myrg_rnext(MYRG_INFO *info, uchar *buf, int inx)
{
if (err == HA_ERR_END_OF_FILE)
{
queue_remove(&(info->by_key),0);
queue_remove_top(&(info->by_key));
if (!info->by_key.elements)
return HA_ERR_END_OF_FILE;
}
......@@ -43,7 +43,7 @@ int myrg_rnext(MYRG_INFO *info, uchar *buf, int inx)
{
/* Found here, adding to queue */
queue_top(&(info->by_key))=(uchar *)(info->current_table);
queue_replaced(&(info->by_key));
queue_replace_top(&(info->by_key));
}
/* now, mymerge's read_next is as simple as one queue_top */
......
......@@ -29,7 +29,7 @@ int myrg_rnext_same(MYRG_INFO *info, uchar *buf)
{
if (err == HA_ERR_END_OF_FILE)
{
queue_remove(&(info->by_key),0);
queue_remove_top(&(info->by_key));
if (!info->by_key.elements)
return HA_ERR_END_OF_FILE;
}
......@@ -40,7 +40,7 @@ int myrg_rnext_same(MYRG_INFO *info, uchar *buf)
{
/* Found here, adding to queue */
queue_top(&(info->by_key))=(uchar *)(info->current_table);
queue_replaced(&(info->by_key));
queue_replace_top(&(info->by_key));
}
/* now, mymerge's read_next is as simple as one queue_top */
......
......@@ -32,7 +32,7 @@ int myrg_rprev(MYRG_INFO *info, uchar *buf, int inx)
{
if (err == HA_ERR_END_OF_FILE)
{
queue_remove(&(info->by_key),0);
queue_remove_top(&(info->by_key));
if (!info->by_key.elements)
return HA_ERR_END_OF_FILE;
}
......@@ -43,7 +43,7 @@ int myrg_rprev(MYRG_INFO *info, uchar *buf, int inx)
{
/* Found here, adding to queue */
queue_top(&(info->by_key))=(uchar *)(info->current_table);
queue_replaced(&(info->by_key));
queue_replace_top(&(info->by_key));
}
/* now, mymerge's read_prev is as simple as one queue_top */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment