~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/uniques.cc

  • Committer: Monty Taylor
  • Date: 2008-07-01 14:33:36 UTC
  • mto: (28.1.12 backport_patch)
  • mto: This revision was merged to the branch mainline in revision 34.
  • Revision ID: monty@inaugust.com-20080701143336-8uihm7dhpu92rt0q
Somehow missed moving password.c. Duh.

Show diffs side-by-side

added added

removed removed

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