25 #include "mysys_priv.h"
26 #include "mysys_err.h"
51 int init_queue(
QUEUE *queue, uint max_elements, uint offset_to_key,
52 pbool max_at_top,
int (*
compare) (
void *, uchar *, uchar *),
55 DBUG_ENTER(
"init_queue");
56 if ((queue->root= (uchar **) my_malloc((max_elements+1)*
sizeof(
void*),
61 queue->first_cmp_arg=first_cmp_arg;
62 queue->max_elements=max_elements;
63 queue->offset_to_key=offset_to_key;
64 queue_set_max_at_top(queue, max_at_top);
94 int init_queue_ex(
QUEUE *queue, uint max_elements, uint offset_to_key,
95 pbool max_at_top,
int (*
compare) (
void *, uchar *, uchar *),
96 void *first_cmp_arg, uint auto_extent)
99 DBUG_ENTER(
"init_queue_ex");
101 if ((ret= init_queue(queue, max_elements, offset_to_key, max_at_top,
compare,
105 queue->auto_extent= auto_extent;
131 int reinit_queue(
QUEUE *queue, uint max_elements, uint offset_to_key,
132 pbool max_at_top,
int (*
compare) (
void *, uchar *, uchar *),
135 DBUG_ENTER(
"reinit_queue");
138 queue->first_cmp_arg=first_cmp_arg;
139 queue->offset_to_key=offset_to_key;
140 queue_set_max_at_top(queue, max_at_top);
141 resize_queue(queue, max_elements);
163 int resize_queue(
QUEUE *queue, uint max_elements)
166 DBUG_ENTER(
"resize_queue");
167 if (queue->max_elements == max_elements)
169 if ((new_root= (uchar **) my_realloc((
void *)queue->root,
170 (max_elements+1)*
sizeof(
void*),
173 set_if_smaller(queue->elements, max_elements);
174 queue->max_elements= max_elements;
175 queue->root= new_root;
194 void delete_queue(
QUEUE *queue)
196 DBUG_ENTER(
"delete_queue");
197 my_free(queue->root);
205 void queue_insert(
register QUEUE *queue, uchar *element)
208 DBUG_ASSERT(queue->elements < queue->max_elements);
209 queue->root[0]= element;
210 idx= ++queue->elements;
212 while ((queue->compare(queue->first_cmp_arg,
213 element + queue->offset_to_key,
214 queue->root[(next= idx >> 1)] +
215 queue->offset_to_key) * queue->max_at_top) < 0)
217 queue->root[idx]= queue->root[next];
220 queue->root[idx]= element;
232 int queue_insert_safe(
register QUEUE *queue, uchar *element)
235 if (queue->elements == queue->max_elements)
237 if (!queue->auto_extent)
239 else if (resize_queue(queue, queue->max_elements + queue->auto_extent))
243 queue_insert(queue, element);
251 uchar *queue_remove(
register QUEUE *queue, uint idx)
254 DBUG_ASSERT(idx < queue->max_elements);
255 element= queue->root[++idx];
256 queue->root[idx]= queue->root[queue->elements--];
257 _downheap(queue, idx);
263 #ifndef queue_replaced
264 void queue_replaced(
QUEUE *queue)
272 void _downheap(
register QUEUE *queue, uint idx)
275 uint elements,half_queue,offset_to_key, next_index;
279 offset_to_key=queue->offset_to_key;
280 element=queue->root[idx];
281 half_queue=(elements=queue->elements) >> 1;
283 while (idx <= half_queue)
286 if (next_index < elements &&
287 (queue->compare(queue->first_cmp_arg,
288 queue->root[next_index]+offset_to_key,
289 queue->root[next_index+1]+offset_to_key) *
290 queue->max_at_top) > 0)
293 (((queue->compare(queue->first_cmp_arg,
294 queue->root[next_index]+offset_to_key,
295 element+offset_to_key) * queue->max_at_top) >= 0)))
297 queue->root[idx]= element;
300 queue->root[idx]=queue->root[next_index];
305 next_index= idx >> 1;
306 while (next_index > start_idx)
308 if ((queue->compare(queue->first_cmp_arg,
309 queue->root[next_index]+offset_to_key,
310 element+offset_to_key) *
311 queue->max_at_top) < 0)
313 queue->root[idx]=queue->root[next_index];
315 next_index= idx >> 1;
317 queue->root[idx]=element;
326 void _downheap(
register QUEUE *queue, uint idx)
329 uint elements,half_queue,next_index,offset_to_key;
331 offset_to_key=queue->offset_to_key;
332 element=queue->root[idx];
333 half_queue=(elements=queue->elements) >> 1;
335 while (idx <= half_queue)
338 if (next_index < elements &&
339 (queue->compare(queue->first_cmp_arg,
340 queue->root[next_index]+offset_to_key,
341 queue->root[next_index+1]+offset_to_key) *
342 queue->max_at_top) > 0)
344 if ((queue->compare(queue->first_cmp_arg,
345 queue->root[next_index]+offset_to_key,
346 element+offset_to_key) * queue->max_at_top) >= 0)
348 queue->root[idx]=queue->root[next_index];
351 queue->root[idx]=element;
361 void queue_fix(
QUEUE *queue)
364 for (i= queue->elements >> 1; i > 0; i--)
379 static uint num_array[1025];
380 static uint tot_no_parts= 0;
381 static uint tot_no_loops= 0;
382 static uint expected_part= 0;
383 static uint expected_num= 0;
384 static my_bool max_ind= 0;
385 static my_bool fix_used= 0;
386 static ulonglong start_time= 0;
388 static my_bool is_divisible_by(uint num, uint divisor)
390 uint quotient= num / divisor;
391 if (quotient * divisor == num)
396 void calculate_next()
398 uint part= expected_part, num= expected_num;
399 uint no_parts= tot_no_parts;
404 while (++part <= no_parts)
406 if (is_divisible_by(num, part) &&
407 (num <= ((1 << 21) + part)))
423 if (is_divisible_by(num, part))
435 void calculate_end_next(uint part)
437 uint no_parts= tot_no_parts, num;
442 for (part= no_parts; part > 0 ; part--)
446 num= num_array[part] & 0x3FFFFF;
447 if (num >= expected_num)
454 if (expected_num == 0)
459 expected_num= 0xFFFFFFFF;
460 for (part= 1; part <= no_parts; part++)
464 num= num_array[part] & 0x3FFFFF;
465 if (num <= expected_num)
472 if (expected_num == 0xFFFFFFFF)
477 static int test_compare(
void *null_arg, uchar *a, uchar *b)
479 uint a_num= (*(uint*)a) & 0x3FFFFF;
480 uint b_num= (*(uint*)b) & 0x3FFFFF;
487 a_part= (*(uint*)a) >> 22;
488 b_part= (*(uint*)b) >> 22;
496 my_bool check_num(uint num_part)
498 uint part= num_part >> 22;
499 uint num= num_part & 0x3FFFFF;
500 if (part == expected_part)
501 if (num == expected_num)
503 printf(
"Expect part %u Expect num 0x%x got part %u num 0x%x max_ind %u fix_used %u \n",
504 expected_part, expected_num, part, num, max_ind, fix_used);
509 void perform_insert(
QUEUE *queue)
511 uint i= 1, no_parts= tot_no_parts;
512 uint backward_start= 0;
518 backward_start= 1 << 21;
522 uint num= (i + backward_start);
525 while (!is_divisible_by(num, i))
527 if (max_ind && (num > expected_num ||
528 (num == expected_num && i < expected_part)))
534 num_array[
i]= num + (i << 22);
536 queue_element(queue, i-1)= (uchar*)&num_array[i];
538 queue_insert(queue, (uchar*)&num_array[i]);
539 }
while (++i <= no_parts);
542 queue->elements= no_parts;
547 my_bool perform_ins_del(
QUEUE *queue, my_bool max_ind)
549 uint i= 0, no_loops= tot_no_loops, j= tot_no_parts;
552 uint num_part= *(uint*)queue_top(queue);
553 uint part= num_part >> 22;
554 if (check_num(num_part))
558 calculate_end_next(part);
559 queue_remove(queue, (uint) 0);
565 num_array[part]-= part;
567 num_array[part]+= part;
568 queue_top(queue)= (uchar*)&num_array[part];
569 queue_replaced(queue);
571 }
while (++i < no_loops);
575 my_bool do_test(uint no_parts, uint l_max_ind, my_bool l_fix_used)
580 fix_used= l_fix_used;
581 init_queue(&queue, no_parts, 0, max_ind, test_compare, NULL);
582 tot_no_parts= no_parts;
584 perform_insert(&queue);
585 if ((result= perform_ins_del(&queue, max_ind)))
586 delete_queue(&queue);
595 static void start_measurement()
597 start_time= my_getsystime();
600 static void stop_measurement()
602 ulonglong stop_time= my_getsystime();
604 stop_time-= start_time;
606 time_in_micros= (uint)stop_time;
607 printf(
"Time expired is %u microseconds \n", time_in_micros);
610 static void benchmark_test()
613 QUEUE *queue= &queue_real;
618 init_queue(queue, tot_no_parts, 0, max_ind, test_compare, NULL);
623 for (tot_no_parts= 2, add=2; tot_no_parts < 128;
624 tot_no_parts+= add, add++)
626 printf(
"Start benchmark queue_fix, tot_no_parts= %u \n", tot_no_parts);
628 for (i= 0; i < 128; i++)
630 perform_insert(queue);
631 queue_remove_all(queue);
636 printf(
"Start benchmark queue_insert\n");
638 for (i= 0; i < 128; i++)
640 perform_insert(queue);
641 queue_remove_all(queue);
650 printf(
"Start benchmarking _downheap \n");
652 perform_insert(queue);
653 for (i= 0; i < 65536; i++)
656 num= *(uint*)queue_top(queue);
659 num_array[part]= num;
660 queue_top(queue)= (uchar*)&num_array[part];
661 queue_replaced(queue);
663 for (i= 0; i < 16; i++)
664 queue_remove(queue, (uint) 0);
665 queue_remove_all(queue);
672 for (i= 1; i < 1024; i+=add, add++)
674 printf(
"Start test for priority queue of size %u\n", i);
675 if (do_test(i, 0, 1))
677 if (do_test(i, 1, 1))
679 if (do_test(i, 0, 0))
681 if (do_test(i, 1, 0))