~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/uniques.cc

  • Committer: Monty Taylor
  • Date: 2008-10-16 06:32:30 UTC
  • mto: (511.1.5 codestyle)
  • mto: This revision was merged to the branch mainline in revision 521.
  • Revision ID: monty@inaugust.com-20081016063230-4brxsra0qsmsg84q
Added -Wunused-macros.

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
  deletes in disk order.
31
31
*/
32
32
 
33
 
#include "mysql_priv.h"
 
33
#include <drizzled/server_includes.h>
34
34
#include "sql_sort.h"
35
35
 
36
36
 
37
 
int unique_write_to_file(uchar* key, element_count count, Unique *unique)
 
37
int unique_write_to_file(unsigned char* key,
 
38
                         element_count count __attribute__((unused)),
 
39
                         Unique *unique)
38
40
{
39
41
  /*
40
42
    Use unique->size (size of element stored in the tree) and not
45
47
  return my_b_write(&unique->file, key, unique->size) ? 1 : 0;
46
48
}
47
49
 
48
 
int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique)
 
50
int unique_write_to_ptrs(unsigned char* key,
 
51
                         element_count count __attribute__((unused)),
 
52
                         Unique *unique)
49
53
{
50
54
  memcpy(unique->record_pointers, key, unique->size);
51
55
  unique->record_pointers+=unique->size;
53
57
}
54
58
 
55
59
Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg,
56
 
               uint size_arg, ulonglong max_in_memory_size_arg)
 
60
               uint32_t size_arg, uint64_t max_in_memory_size_arg)
57
61
  :max_in_memory_size(max_in_memory_size_arg), size(size_arg), elements(0)
58
62
{
59
63
  my_b_clear(&file);
66
70
  */
67
71
  max_elements= (ulong) (max_in_memory_size /
68
72
                         ALIGN_SIZE(sizeof(TREE_ELEMENT)+size));
69
 
  VOID(open_cached_file(&file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE,
70
 
                   MYF(MY_WME)));
 
73
  open_cached_file(&file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE,
 
74
                   MYF(MY_WME));
71
75
}
72
76
 
73
77
 
122
126
      total_buf_elems* log2(n_buffers) / TIME_FOR_COMPARE_ROWID;
123
127
*/
124
128
 
125
 
static double get_merge_buffers_cost(uint *buff_elems, uint elem_size,
126
 
                                     uint *first, uint *last)
 
129
static double get_merge_buffers_cost(uint32_t *buff_elems __attribute__((unused)),
 
130
                                     uint32_t elem_size,
 
131
                                     uint32_t *first, uint32_t *last)
127
132
{
128
 
  uint total_buf_elems= 0;
129
 
  for (uint *pbuf= first; pbuf <= last; pbuf++)
 
133
  uint32_t total_buf_elems= 0;
 
134
  for (uint32_t *pbuf= first; pbuf <= last; pbuf++)
130
135
    total_buf_elems+= *pbuf;
131
136
  *last= total_buf_elems;
132
137
 
165
170
    Cost of merge in disk seeks.
166
171
*/
167
172
 
168
 
static double get_merge_many_buffs_cost(uint *buffer,
169
 
                                        uint maxbuffer, uint max_n_elems,
170
 
                                        uint last_n_elems, int elem_size)
 
173
static double get_merge_many_buffs_cost(uint32_t *buffer,
 
174
                                        uint32_t maxbuffer, uint32_t max_n_elems,
 
175
                                        uint32_t last_n_elems, int elem_size)
171
176
{
172
177
  register int i;
173
178
  double total_cost= 0.0;
174
 
  uint *buff_elems= buffer; /* #s of elements in each of merged sequences */
 
179
  uint32_t *buff_elems= buffer; /* #s of elements in each of merged sequences */
175
180
 
176
181
  /*
177
182
    Set initial state: first maxbuffer sequences contain max_n_elems elements
189
194
  {
190
195
    while (maxbuffer >= MERGEBUFF2)
191
196
    {
192
 
      uint lastbuff= 0;
 
197
      uint32_t lastbuff= 0;
193
198
      for (i = 0; i <= (int) maxbuffer - MERGEBUFF*3/2; i += MERGEBUFF)
194
199
      {
195
200
        total_cost+=get_merge_buffers_cost(buff_elems, elem_size,
258
263
      these will be random seeks.
259
264
*/
260
265
 
261
 
double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size,
262
 
                            ulonglong max_in_memory_size)
 
266
double Unique::get_use_cost(uint32_t *buffer, uint32_t nkeys, uint32_t key_size,
 
267
                            uint64_t max_in_memory_size)
263
268
{
264
269
  ulong max_elements_in_tree;
265
270
  ulong last_tree_elems;
278
283
    result+= n_full_trees * log2_n_fact(max_elements_in_tree + 1.0);
279
284
  result /= TIME_FOR_COMPARE_ROWID;
280
285
 
281
 
  DBUG_PRINT("info",("unique trees sizes: %u=%u*%lu + %lu", nkeys,
282
 
                     n_full_trees, n_full_trees?max_elements_in_tree:0,
283
 
                     last_tree_elems));
284
286
 
285
287
  if (!n_full_trees)
286
288
    return result;
329
331
 
330
332
  if (tree_walk(&tree, (tree_walk_action) unique_write_to_file,
331
333
                (void*) this, left_root_right) ||
332
 
      insert_dynamic(&file_ptrs, (uchar*) &file_ptr))
 
334
      insert_dynamic(&file_ptrs, (unsigned char*) &file_ptr))
333
335
    return 1;
334
336
  delete_tree(&tree);
335
337
  return 0;
366
368
  BUFFPEK.
367
369
*/
368
370
 
369
 
C_MODE_START
 
371
#ifdef __cplusplus
 
372
extern "C" {
 
373
#endif
370
374
 
371
 
static int buffpek_compare(void *arg, uchar *key_ptr1, uchar *key_ptr2)
 
375
static int buffpek_compare(void *arg, unsigned char *key_ptr1, unsigned char *key_ptr2)
372
376
{
373
377
  BUFFPEK_COMPARE_CONTEXT *ctx= (BUFFPEK_COMPARE_CONTEXT *) arg;
374
378
  return ctx->key_compare(ctx->key_compare_arg,
375
 
                          *((uchar **) key_ptr1), *((uchar **)key_ptr2));
376
 
}
377
 
 
378
 
C_MODE_END
 
379
                          *((unsigned char **) key_ptr1), *((unsigned char **)key_ptr2));
 
380
}
 
381
 
 
382
#ifdef __cplusplus
 
383
}
 
384
#endif
 
385
 
379
386
 
380
387
 
381
388
/*
412
419
    <> 0  error
413
420
*/
414
421
 
415
 
static bool merge_walk(uchar *merge_buffer, ulong merge_buffer_size,
416
 
                       uint key_length, BUFFPEK *begin, BUFFPEK *end,
 
422
static bool merge_walk(unsigned char *merge_buffer, ulong merge_buffer_size,
 
423
                       uint32_t key_length, BUFFPEK *begin, BUFFPEK *end,
417
424
                       tree_walk_action walk_action, void *walk_action_arg,
418
425
                       qsort_cmp2 compare, void *compare_arg,
419
426
                       IO_CACHE *file)
427
434
    return 1;
428
435
  /* we need space for one key when a piece of merge buffer is re-read */
429
436
  merge_buffer_size-= key_length;
430
 
  uchar *save_key_buff= merge_buffer + merge_buffer_size;
431
 
  uint max_key_count_per_piece= (uint) (merge_buffer_size/(end-begin) /
 
437
  unsigned char *save_key_buff= merge_buffer + merge_buffer_size;
 
438
  uint32_t max_key_count_per_piece= (uint) (merge_buffer_size/(end-begin) /
432
439
                                        key_length);
433
440
  /* if piece_size is aligned reuse_freed_buffer will always hit */
434
 
  uint piece_size= max_key_count_per_piece * key_length;
435
 
  uint bytes_read;               /* to hold return value of read_to_buffer */
 
441
  uint32_t piece_size= max_key_count_per_piece * key_length;
 
442
  uint32_t bytes_read;               /* to hold return value of read_to_buffer */
436
443
  BUFFPEK *top;
437
444
  int res= 1;
438
445
  /*
448
455
    bytes_read= read_to_buffer(file, top, key_length);
449
456
    if (bytes_read == (uint) (-1))
450
457
      goto end;
451
 
    DBUG_ASSERT(bytes_read);
452
 
    queue_insert(&queue, (uchar *) top);
 
458
    assert(bytes_read);
 
459
    queue_insert(&queue, (unsigned char *) top);
453
460
  }
454
461
  top= (BUFFPEK *) queue_top(&queue);
455
462
  while (queue.elements > 1)
546
553
bool Unique::walk(tree_walk_action action, void *walk_action_arg)
547
554
{
548
555
  int res;
549
 
  uchar *merge_buffer;
 
556
  unsigned char *merge_buffer;
550
557
 
551
558
  if (elements == 0)                       /* the whole tree is in memory */
552
559
    return tree_walk(&tree, action, walk_action_arg, left_root_right);
556
563
    return 1;
557
564
  if (flush_io_cache(&file) || reinit_io_cache(&file, READ_CACHE, 0L, 0, 0))
558
565
    return 1;
559
 
  if (!(merge_buffer= (uchar *) my_malloc((ulong) max_in_memory_size, MYF(0))))
 
566
  if (!(merge_buffer= (unsigned char *) my_malloc((ulong) max_in_memory_size, MYF(0))))
560
567
    return 1;
561
568
  res= merge_walk(merge_buffer, (ulong) max_in_memory_size, size,
562
569
                  (BUFFPEK *) file_ptrs.buffer,
563
570
                  (BUFFPEK *) file_ptrs.buffer + file_ptrs.elements,
564
571
                  action, walk_action_arg,
565
572
                  tree.compare, tree.custom_arg, &file);
566
 
  my_free((char*) merge_buffer, MYF(0));
 
573
  free((char*) merge_buffer);
567
574
  return res;
568
575
}
569
576
 
570
577
/*
571
 
  Modify the TABLE element so that when one calls init_records()
 
578
  Modify the Table element so that when one calls init_records()
572
579
  the rows will be read in priority order.
573
580
*/
574
581
 
575
 
bool Unique::get(TABLE *table)
 
582
bool Unique::get(Table *table)
576
583
{
577
584
  SORTPARAM sort_param;
578
585
  table->sort.found_records=elements+tree.elements_in_tree;
580
587
  if (my_b_tell(&file) == 0)
581
588
  {
582
589
    /* Whole tree is in memory;  Don't use disk if you don't need to */
583
 
    if ((record_pointers=table->sort.record_pointers= (uchar*)
 
590
    if ((record_pointers=table->sort.record_pointers= (unsigned char*)
584
591
         my_malloc(size * tree.elements_in_tree, MYF(0))))
585
592
    {
586
593
      (void) tree_walk(&tree, (tree_walk_action) unique_write_to_ptrs,
594
601
 
595
602
  IO_CACHE *outfile=table->sort.io_cache;
596
603
  BUFFPEK *file_ptr= (BUFFPEK*) file_ptrs.buffer;
597
 
  uint maxbuffer= file_ptrs.elements - 1;
598
 
  uchar *sort_buffer;
 
604
  uint32_t maxbuffer= file_ptrs.elements - 1;
 
605
  unsigned char *sort_buffer;
599
606
  my_off_t save_pos;
600
607
  bool error=1;
601
608
 
607
614
    return 1;
608
615
  reinit_io_cache(outfile,WRITE_CACHE,0L,0,0);
609
616
 
610
 
  bzero((char*) &sort_param,sizeof(sort_param));
 
617
  memset(&sort_param, 0, sizeof(sort_param));
611
618
  sort_param.max_rows= elements;
612
619
  sort_param.sort_form=table;
613
620
  sort_param.rec_length= sort_param.sort_length= sort_param.ref_length=
615
622
  sort_param.keys= (uint) (max_in_memory_size / sort_param.sort_length);
616
623
  sort_param.not_killable=1;
617
624
 
618
 
  if (!(sort_buffer=(uchar*) my_malloc((sort_param.keys+1) *
 
625
  if (!(sort_buffer=(unsigned char*) my_malloc((sort_param.keys+1) *
619
626
                                       sort_param.sort_length,
620
627
                                       MYF(0))))
621
628
    return 1;
637
644
    goto err;
638
645
  error=0;
639
646
err:
640
 
  x_free(sort_buffer);
 
647
  if (sort_buffer)
 
648
    free(sort_buffer);
641
649
  if (flush_io_cache(outfile))
642
650
    error=1;
643
651