~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/uniques.cc

  • Committer: Monty Taylor
  • Date: 2008-09-15 17:24:04 UTC
  • Revision ID: monty@inaugust.com-20080915172404-ygh6hiyu0q7qpa9x
Removed strndup calls.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
*/
32
32
 
33
33
#include <drizzled/server_includes.h>
34
 
#include <drizzled/sql_sort.h>
35
 
#include CMATH_H
36
 
 
37
 
#if defined(CMATH_NAMESPACE)
38
 
using namespace CMATH_NAMESPACE;
39
 
#endif
40
 
 
41
 
 
42
 
int unique_write_to_file(unsigned char* key,
 
34
#include "sql_sort.h"
 
35
 
 
36
 
 
37
int unique_write_to_file(uchar* key,
43
38
                         element_count count __attribute__((unused)),
44
39
                         Unique *unique)
45
40
{
52
47
  return my_b_write(&unique->file, key, unique->size) ? 1 : 0;
53
48
}
54
49
 
55
 
int unique_write_to_ptrs(unsigned char* key,
 
50
int unique_write_to_ptrs(uchar* key,
56
51
                         element_count count __attribute__((unused)),
57
52
                         Unique *unique)
58
53
{
62
57
}
63
58
 
64
59
Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg,
65
 
               uint32_t size_arg, uint64_t max_in_memory_size_arg)
 
60
               uint size_arg, uint64_t max_in_memory_size_arg)
66
61
  :max_in_memory_size(max_in_memory_size_arg), size(size_arg), elements(0)
67
62
{
68
63
  my_b_clear(&file);
75
70
  */
76
71
  max_elements= (ulong) (max_in_memory_size /
77
72
                         ALIGN_SIZE(sizeof(TREE_ELEMENT)+size));
78
 
  open_cached_file(&file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE,
79
 
                   MYF(MY_WME));
 
73
  VOID(open_cached_file(&file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE,
 
74
                   MYF(MY_WME)));
80
75
}
81
76
 
82
77
 
131
126
      total_buf_elems* log2(n_buffers) / TIME_FOR_COMPARE_ROWID;
132
127
*/
133
128
 
134
 
static double get_merge_buffers_cost(uint32_t *buff_elems __attribute__((unused)),
135
 
                                     uint32_t elem_size,
136
 
                                     uint32_t *first, uint32_t *last)
 
129
static double get_merge_buffers_cost(uint *buff_elems __attribute__((unused)),
 
130
                                     uint elem_size,
 
131
                                     uint *first, uint *last)
137
132
{
138
 
  uint32_t total_buf_elems= 0;
139
 
  for (uint32_t *pbuf= first; pbuf <= last; pbuf++)
 
133
  uint total_buf_elems= 0;
 
134
  for (uint *pbuf= first; pbuf <= last; pbuf++)
140
135
    total_buf_elems+= *pbuf;
141
136
  *last= total_buf_elems;
142
137
 
175
170
    Cost of merge in disk seeks.
176
171
*/
177
172
 
178
 
static double get_merge_many_buffs_cost(uint32_t *buffer,
179
 
                                        uint32_t maxbuffer, uint32_t max_n_elems,
180
 
                                        uint32_t last_n_elems, int elem_size)
 
173
static double get_merge_many_buffs_cost(uint *buffer,
 
174
                                        uint maxbuffer, uint max_n_elems,
 
175
                                        uint last_n_elems, int elem_size)
181
176
{
182
177
  register int i;
183
178
  double total_cost= 0.0;
184
 
  uint32_t *buff_elems= buffer; /* #s of elements in each of merged sequences */
 
179
  uint *buff_elems= buffer; /* #s of elements in each of merged sequences */
185
180
 
186
181
  /*
187
182
    Set initial state: first maxbuffer sequences contain max_n_elems elements
199
194
  {
200
195
    while (maxbuffer >= MERGEBUFF2)
201
196
    {
202
 
      uint32_t lastbuff= 0;
 
197
      uint lastbuff= 0;
203
198
      for (i = 0; i <= (int) maxbuffer - MERGEBUFF*3/2; i += MERGEBUFF)
204
199
      {
205
200
        total_cost+=get_merge_buffers_cost(buff_elems, elem_size,
268
263
      these will be random seeks.
269
264
*/
270
265
 
271
 
double Unique::get_use_cost(uint32_t *buffer, uint32_t nkeys, uint32_t key_size,
 
266
double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size,
272
267
                            uint64_t max_in_memory_size)
273
268
{
274
269
  ulong max_elements_in_tree;
336
331
 
337
332
  if (tree_walk(&tree, (tree_walk_action) unique_write_to_file,
338
333
                (void*) this, left_root_right) ||
339
 
      insert_dynamic(&file_ptrs, (unsigned char*) &file_ptr))
 
334
      insert_dynamic(&file_ptrs, (uchar*) &file_ptr))
340
335
    return 1;
341
336
  delete_tree(&tree);
342
337
  return 0;
373
368
  BUFFPEK.
374
369
*/
375
370
 
376
 
#ifdef __cplusplus
377
 
extern "C" {
378
 
#endif
 
371
C_MODE_START
379
372
 
380
 
static int buffpek_compare(void *arg, unsigned char *key_ptr1, unsigned char *key_ptr2)
 
373
static int buffpek_compare(void *arg, uchar *key_ptr1, uchar *key_ptr2)
381
374
{
382
375
  BUFFPEK_COMPARE_CONTEXT *ctx= (BUFFPEK_COMPARE_CONTEXT *) arg;
383
376
  return ctx->key_compare(ctx->key_compare_arg,
384
 
                          *((unsigned char **) key_ptr1), *((unsigned char **)key_ptr2));
385
 
}
386
 
 
387
 
#ifdef __cplusplus
388
 
}
389
 
#endif
390
 
 
 
377
                          *((uchar **) key_ptr1), *((uchar **)key_ptr2));
 
378
}
 
379
 
 
380
C_MODE_END
391
381
 
392
382
 
393
383
/*
424
414
    <> 0  error
425
415
*/
426
416
 
427
 
static bool merge_walk(unsigned char *merge_buffer, ulong merge_buffer_size,
428
 
                       uint32_t key_length, BUFFPEK *begin, BUFFPEK *end,
 
417
static bool merge_walk(uchar *merge_buffer, ulong merge_buffer_size,
 
418
                       uint key_length, BUFFPEK *begin, BUFFPEK *end,
429
419
                       tree_walk_action walk_action, void *walk_action_arg,
430
420
                       qsort_cmp2 compare, void *compare_arg,
431
421
                       IO_CACHE *file)
439
429
    return 1;
440
430
  /* we need space for one key when a piece of merge buffer is re-read */
441
431
  merge_buffer_size-= key_length;
442
 
  unsigned char *save_key_buff= merge_buffer + merge_buffer_size;
443
 
  uint32_t max_key_count_per_piece= (uint) (merge_buffer_size/(end-begin) /
 
432
  uchar *save_key_buff= merge_buffer + merge_buffer_size;
 
433
  uint max_key_count_per_piece= (uint) (merge_buffer_size/(end-begin) /
444
434
                                        key_length);
445
435
  /* if piece_size is aligned reuse_freed_buffer will always hit */
446
 
  uint32_t piece_size= max_key_count_per_piece * key_length;
447
 
  uint32_t bytes_read;               /* to hold return value of read_to_buffer */
 
436
  uint piece_size= max_key_count_per_piece * key_length;
 
437
  uint bytes_read;               /* to hold return value of read_to_buffer */
448
438
  BUFFPEK *top;
449
439
  int res= 1;
450
440
  /*
461
451
    if (bytes_read == (uint) (-1))
462
452
      goto end;
463
453
    assert(bytes_read);
464
 
    queue_insert(&queue, (unsigned char *) top);
 
454
    queue_insert(&queue, (uchar *) top);
465
455
  }
466
456
  top= (BUFFPEK *) queue_top(&queue);
467
457
  while (queue.elements > 1)
558
548
bool Unique::walk(tree_walk_action action, void *walk_action_arg)
559
549
{
560
550
  int res;
561
 
  unsigned char *merge_buffer;
 
551
  uchar *merge_buffer;
562
552
 
563
553
  if (elements == 0)                       /* the whole tree is in memory */
564
554
    return tree_walk(&tree, action, walk_action_arg, left_root_right);
568
558
    return 1;
569
559
  if (flush_io_cache(&file) || reinit_io_cache(&file, READ_CACHE, 0L, 0, 0))
570
560
    return 1;
571
 
  if (!(merge_buffer= (unsigned char *) my_malloc((ulong) max_in_memory_size, MYF(0))))
 
561
  if (!(merge_buffer= (uchar *) my_malloc((ulong) max_in_memory_size, MYF(0))))
572
562
    return 1;
573
563
  res= merge_walk(merge_buffer, (ulong) max_in_memory_size, size,
574
564
                  (BUFFPEK *) file_ptrs.buffer,
575
565
                  (BUFFPEK *) file_ptrs.buffer + file_ptrs.elements,
576
566
                  action, walk_action_arg,
577
567
                  tree.compare, tree.custom_arg, &file);
578
 
  free((char*) merge_buffer);
 
568
  my_free((char*) merge_buffer, MYF(0));
579
569
  return res;
580
570
}
581
571
 
592
582
  if (my_b_tell(&file) == 0)
593
583
  {
594
584
    /* Whole tree is in memory;  Don't use disk if you don't need to */
595
 
    if ((record_pointers=table->sort.record_pointers= (unsigned char*)
 
585
    if ((record_pointers=table->sort.record_pointers= (uchar*)
596
586
         my_malloc(size * tree.elements_in_tree, MYF(0))))
597
587
    {
598
588
      (void) tree_walk(&tree, (tree_walk_action) unique_write_to_ptrs,
606
596
 
607
597
  IO_CACHE *outfile=table->sort.io_cache;
608
598
  BUFFPEK *file_ptr= (BUFFPEK*) file_ptrs.buffer;
609
 
  uint32_t maxbuffer= file_ptrs.elements - 1;
610
 
  unsigned char *sort_buffer;
 
599
  uint maxbuffer= file_ptrs.elements - 1;
 
600
  uchar *sort_buffer;
611
601
  my_off_t save_pos;
612
602
  bool error=1;
613
603
 
627
617
  sort_param.keys= (uint) (max_in_memory_size / sort_param.sort_length);
628
618
  sort_param.not_killable=1;
629
619
 
630
 
  if (!(sort_buffer=(unsigned char*) my_malloc((sort_param.keys+1) *
 
620
  if (!(sort_buffer=(uchar*) my_malloc((sort_param.keys+1) *
631
621
                                       sort_param.sort_length,
632
622
                                       MYF(0))))
633
623
    return 1;
649
639
    goto err;
650
640
  error=0;
651
641
err:
652
 
  if (sort_buffer)
653
 
    free(sort_buffer);
 
642
  x_free(sort_buffer);
654
643
  if (flush_io_cache(outfile))
655
644
    error=1;
656
645