~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/filesort.cc

  • Committer: Stewart Smith
  • Date: 2008-09-25 10:04:06 UTC
  • mto: This revision was merged to the branch mainline in revision 408.
  • Revision ID: stewart@flamingspork.com-20080925100406-hld92f4dr4nuar3a
Move compression functions (compress, uncompress and compressed_length) out into modules and fix test

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
 
28
28
        /* functions defined in this file */
29
29
 
30
 
static char **make_char_array(char **old_pos, register uint32_t fields,
31
 
                              uint32_t length, myf my_flag);
32
 
static unsigned char *read_buffpek_from_file(IO_CACHE *buffer_file, uint32_t count,
33
 
                                     unsigned char *buf);
 
30
static char **make_char_array(char **old_pos, register uint fields,
 
31
                              uint length, myf my_flag);
 
32
static uchar *read_buffpek_from_file(IO_CACHE *buffer_file, uint count,
 
33
                                     uchar *buf);
34
34
static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select,
35
 
                             unsigned char * *sort_keys, IO_CACHE *buffer_file,
 
35
                             uchar * *sort_keys, IO_CACHE *buffer_file,
36
36
                             IO_CACHE *tempfile,IO_CACHE *indexfile);
37
 
static int write_keys(SORTPARAM *param,unsigned char * *sort_keys,
38
 
                      uint32_t count, IO_CACHE *buffer_file, IO_CACHE *tempfile);
39
 
static void make_sortkey(SORTPARAM *param,unsigned char *to, unsigned char *ref_pos);
 
37
static int write_keys(SORTPARAM *param,uchar * *sort_keys,
 
38
                      uint count, IO_CACHE *buffer_file, IO_CACHE *tempfile);
 
39
static void make_sortkey(SORTPARAM *param,uchar *to, uchar *ref_pos);
40
40
static void register_used_fields(SORTPARAM *param);
41
 
static int merge_index(SORTPARAM *param,unsigned char *sort_buffer,
 
41
static int merge_index(SORTPARAM *param,uchar *sort_buffer,
42
42
                       BUFFPEK *buffpek,
43
 
                       uint32_t maxbuffer,IO_CACHE *tempfile,
 
43
                       uint maxbuffer,IO_CACHE *tempfile,
44
44
                       IO_CACHE *outfile);
45
 
static bool save_index(SORTPARAM *param,unsigned char **sort_keys, uint32_t count, 
 
45
static bool save_index(SORTPARAM *param,uchar **sort_keys, uint count, 
46
46
                       filesort_info_st *table_sort);
47
 
static uint32_t suffix_length(uint32_t string_length);
48
 
static uint32_t sortlength(THD *thd, SORT_FIELD *sortorder, uint32_t s_length,
 
47
static uint suffix_length(uint32_t string_length);
 
48
static uint sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
49
49
                       bool *multi_byte_charset);
50
50
static SORT_ADDON_FIELD *get_addon_fields(THD *thd, Field **ptabfield,
51
 
                                          uint32_t sortlength, uint32_t *plength);
 
51
                                          uint sortlength, uint *plength);
52
52
static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
53
 
                                unsigned char *buff);
 
53
                                uchar *buff);
54
54
/**
55
55
  Sort a table.
56
56
  Creates a set of pointers that can be used to read the rows
87
87
    examined_rows       will be set to number of examined rows
88
88
*/
89
89
 
90
 
ha_rows filesort(THD *thd, Table *table, SORT_FIELD *sortorder, uint32_t s_length,
 
90
ha_rows filesort(THD *thd, Table *table, SORT_FIELD *sortorder, uint s_length,
91
91
                 SQL_SELECT *select, ha_rows max_rows,
92
92
                 bool sort_positions, ha_rows *examined_rows)
93
93
{
94
94
  int error;
95
95
  uint32_t memavl, min_sort_memory;
96
 
  uint32_t maxbuffer;
 
96
  uint maxbuffer;
97
97
  BUFFPEK *buffpek;
98
98
  ha_rows records= HA_POS_ERROR;
99
 
  unsigned char **sort_keys= 0;
 
99
  uchar **sort_keys= 0;
100
100
  IO_CACHE tempfile, buffpek_pointers, *selected_records_file, *outfile; 
101
101
  SORTPARAM param;
102
102
  bool multi_byte_charset;
149
149
  if (param.addon_field)
150
150
  {
151
151
    param.res_length= param.addon_length;
152
 
    if (!(table_sort.addon_buf= (unsigned char *) my_malloc(param.addon_length,
 
152
    if (!(table_sort.addon_buf= (uchar *) my_malloc(param.addon_length,
153
153
                                                    MYF(MY_WME))))
154
154
      goto err;
155
155
  }
176
176
#ifdef CAN_TRUST_RANGE
177
177
  if (select && select->quick && select->quick->records > 0L)
178
178
  {
179
 
    records=cmin((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
 
179
    records=min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
180
180
                table->file->stats.records)+EXTRA_RECORDS;
181
181
    selected_records_file=0;
182
182
  }
198
198
    goto err;
199
199
 
200
200
  memavl= thd->variables.sortbuff_size;
201
 
  min_sort_memory= cmax((uint32_t)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
 
201
  min_sort_memory= max((uint)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
202
202
  while (memavl >= min_sort_memory)
203
203
  {
204
204
    uint32_t old_memavl;
205
205
    uint32_t keys= memavl/(param.rec_length+sizeof(char*));
206
 
    param.keys=(uint32_t) cmin(records+1, keys);
 
206
    param.keys=(uint) min(records+1, keys);
207
207
    if ((table_sort.sort_keys=
208
 
         (unsigned char **) make_char_array((char **) table_sort.sort_keys,
 
208
         (uchar **) make_char_array((char **) table_sort.sort_keys,
209
209
                                    param.keys, param.rec_length, MYF(0))))
210
210
      break;
211
211
    old_memavl=memavl;
229
229
                             &tempfile, selected_records_file)) ==
230
230
      HA_POS_ERROR)
231
231
    goto err;
232
 
  maxbuffer= (uint32_t) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek));
 
232
  maxbuffer= (uint) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek));
233
233
 
234
234
  if (maxbuffer == 0)                   // The whole set is in memory
235
235
  {
236
 
    if (save_index(&param,sort_keys,(uint32_t) records, &table_sort))
 
236
    if (save_index(&param,sort_keys,(uint) records, &table_sort))
237
237
      goto err;
238
238
  }
239
239
  else
240
240
  {
241
241
    if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
242
242
    {
243
 
      if (table_sort.buffpek)
244
 
        free(table_sort.buffpek);
 
243
      x_free(table_sort.buffpek);
245
244
      table_sort.buffpek= 0;
246
245
    }
247
246
    if (!(table_sort.buffpek=
248
 
          (unsigned char *) read_buffpek_from_file(&buffpek_pointers, maxbuffer,
 
247
          (uchar *) read_buffpek_from_file(&buffpek_pointers, maxbuffer,
249
248
                                 table_sort.buffpek)))
250
249
      goto err;
251
250
    buffpek= (BUFFPEK *) table_sort.buffpek;
266
265
    param.keys=((param.keys*(param.rec_length+sizeof(char*))) /
267
266
                param.rec_length-1);
268
267
    maxbuffer--;                                // Offset from 0
269
 
    if (merge_many_buff(&param,(unsigned char*) sort_keys,buffpek,&maxbuffer,
 
268
    if (merge_many_buff(&param,(uchar*) sort_keys,buffpek,&maxbuffer,
270
269
                        &tempfile))
271
270
      goto err;
272
271
    if (flush_io_cache(&tempfile) ||
273
272
        reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
274
273
      goto err;
275
 
    if (merge_index(&param,(unsigned char*) sort_keys,buffpek,maxbuffer,&tempfile,
 
274
    if (merge_index(&param,(uchar*) sort_keys,buffpek,maxbuffer,&tempfile,
276
275
                    outfile))
277
276
      goto err;
278
277
  }
282
281
 
283
282
 err:
284
283
  if (param.tmp_buffer)
285
 
    if (param.tmp_buffer)
286
 
      free(param.tmp_buffer);
 
284
    x_free(param.tmp_buffer);
287
285
  if (!subselect || !subselect->is_uncacheable())
288
286
  {
289
 
    if ((unsigned char*) sort_keys)
290
 
      free((unsigned char*) sort_keys);
 
287
    x_free((uchar*) sort_keys);
291
288
    table_sort.sort_keys= 0;
292
 
    if ((unsigned char*) buffpek)
293
 
      free((unsigned char*) buffpek);
 
289
    x_free((uchar*) buffpek);
294
290
    table_sort.buffpek= 0;
295
291
    table_sort.buffpek_len= 0;
296
292
  }
325
321
{
326
322
  if (table->sort.record_pointers)
327
323
  {
328
 
    free((unsigned char*) table->sort.record_pointers);
 
324
    my_free((uchar*) table->sort.record_pointers,MYF(0));
329
325
    table->sort.record_pointers=0;
330
326
  }
331
327
  if (full)
332
328
  {
333
329
    if (table->sort.sort_keys )
334
330
    {
335
 
      if ((unsigned char*) table->sort.sort_keys)
336
 
        free((unsigned char*) table->sort.sort_keys);
 
331
      x_free((uchar*) table->sort.sort_keys);
337
332
      table->sort.sort_keys= 0;
338
333
    }
339
334
    if (table->sort.buffpek)
340
335
    {
341
 
      if ((unsigned char*) table->sort.buffpek)
342
 
        free((unsigned char*) table->sort.buffpek);
 
336
      x_free((uchar*) table->sort.buffpek);
343
337
      table->sort.buffpek= 0;
344
338
      table->sort.buffpek_len= 0;
345
339
    }
346
340
  }
347
341
  if (table->sort.addon_buf)
348
342
  {
349
 
    free((char *) table->sort.addon_buf);
350
 
    free((char *) table->sort.addon_field);
 
343
    my_free((char *) table->sort.addon_buf, MYF(0));
 
344
    my_free((char *) table->sort.addon_field, MYF(MY_ALLOW_ZERO_PTR));
351
345
    table->sort.addon_buf=0;
352
346
    table->sort.addon_field=0;
353
347
  }
355
349
 
356
350
/** Make a array of string pointers. */
357
351
 
358
 
static char **make_char_array(char **old_pos, register uint32_t fields,
359
 
                              uint32_t length, myf my_flag)
 
352
static char **make_char_array(char **old_pos, register uint fields,
 
353
                              uint length, myf my_flag)
360
354
{
361
355
  register char **pos;
362
356
  char *char_pos;
363
357
 
364
358
  if (old_pos ||
365
 
      (old_pos= (char**) my_malloc((uint32_t) fields*(length+sizeof(char*)),
 
359
      (old_pos= (char**) my_malloc((uint) fields*(length+sizeof(char*)),
366
360
                                   my_flag)))
367
361
  {
368
362
    pos=old_pos; char_pos=((char*) (pos+fields)) -length;
375
369
 
376
370
/** Read 'count' number of buffer pointers into memory. */
377
371
 
378
 
static unsigned char *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint32_t count,
379
 
                                     unsigned char *buf)
 
372
static uchar *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count,
 
373
                                     uchar *buf)
380
374
{
381
375
  uint32_t length= sizeof(BUFFPEK)*count;
382
 
  unsigned char *tmp= buf;
 
376
  uchar *tmp= buf;
383
377
  if (count > UINT_MAX/sizeof(BUFFPEK))
384
378
    return 0; /* sizeof(BUFFPEK)*count will overflow */
385
379
  if (!tmp)
386
 
    tmp= (unsigned char *)my_malloc(length, MYF(MY_WME));
 
380
    tmp= (uchar *)my_malloc(length, MYF(MY_WME));
387
381
  if (tmp)
388
382
  {
389
383
    if (reinit_io_cache(buffpek_pointers,READ_CACHE,0L,0,0) ||
390
 
        my_b_read(buffpek_pointers, (unsigned char*) tmp, length))
 
384
        my_b_read(buffpek_pointers, (uchar*) tmp, length))
391
385
    {
392
 
      free((char*) tmp);
 
386
      my_free((char*) tmp, MYF(0));
393
387
      tmp=0;
394
388
    }
395
389
  }
435
429
*/
436
430
 
437
431
static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
438
 
                             unsigned char **sort_keys,
 
432
                             uchar **sort_keys,
439
433
                             IO_CACHE *buffpek_pointers,
440
434
                             IO_CACHE *tempfile, IO_CACHE *indexfile)
441
435
{
442
436
  int error,flag,quick_select;
443
 
  uint32_t idx,indexpos,ref_length;
444
 
  unsigned char *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
 
437
  uint idx,indexpos,ref_length;
 
438
  uchar *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
445
439
  my_off_t record;
446
440
  Table *sort_form;
447
441
  THD *thd= current_thd;
464
458
  next_pos=ref_pos;
465
459
  if (! indexfile && ! quick_select)
466
460
  {
467
 
    next_pos=(unsigned char*) 0;                        /* Find records in sequence */
 
461
    next_pos=(uchar*) 0;                        /* Find records in sequence */
468
462
    file->ha_rnd_init(1);
469
463
    file->extra_opt(HA_EXTRA_CACHE,
470
464
                    current_thd->variables.read_buff_size);
489
483
  register_used_fields(param);
490
484
  if (select && select->cond)
491
485
    select->cond->walk(&Item::register_field_in_read_map, 1,
492
 
                       (unsigned char*) sort_form);
 
486
                       (uchar*) sort_form);
493
487
  sort_form->column_bitmaps_set(&sort_form->tmp_set, &sort_form->tmp_set);
494
488
 
495
489
  for (;;)
507
501
    {
508
502
      if (indexfile)
509
503
      {
510
 
        if (my_b_read(indexfile,(unsigned char*) ref_pos,ref_length)) /* purecov: deadcode */
 
504
        if (my_b_read(indexfile,(uchar*) ref_pos,ref_length)) /* purecov: deadcode */
511
505
        {
512
506
          error= my_errno ? my_errno : -1;              /* Abort */
513
507
          break;
615
609
*/
616
610
 
617
611
static int
618
 
write_keys(SORTPARAM *param, register unsigned char **sort_keys, uint32_t count,
 
612
write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
619
613
           IO_CACHE *buffpek_pointers, IO_CACHE *tempfile)
620
614
{
621
615
  size_t sort_length, rec_length;
622
 
  unsigned char **end;
 
616
  uchar **end;
623
617
  BUFFPEK buffpek;
624
618
 
625
619
  sort_length= param->sort_length;
626
620
  rec_length= param->rec_length;
627
 
  my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
 
621
  my_string_ptr_sort((uchar*) sort_keys, (uint) count, sort_length);
628
622
  if (!my_b_inited(tempfile) &&
629
623
      open_cached_file(tempfile, mysql_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE,
630
624
                       MYF(MY_WME)))
634
628
    goto err;
635
629
  buffpek.file_pos= my_b_tell(tempfile);
636
630
  if ((ha_rows) count > param->max_rows)
637
 
    count=(uint32_t) param->max_rows;               /* purecov: inspected */
 
631
    count=(uint) param->max_rows;               /* purecov: inspected */
638
632
  buffpek.count=(ha_rows) count;
639
633
  for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
640
 
    if (my_b_write(tempfile, (unsigned char*) *sort_keys, (uint32_t) rec_length))
 
634
    if (my_b_write(tempfile, (uchar*) *sort_keys, (uint) rec_length))
641
635
      goto err;
642
 
  if (my_b_write(buffpek_pointers, (unsigned char*) &buffpek, sizeof(buffpek)))
 
636
  if (my_b_write(buffpek_pointers, (uchar*) &buffpek, sizeof(buffpek)))
643
637
    goto err;
644
638
  return(0);
645
639
 
652
646
  Store length as suffix in high-byte-first order.
653
647
*/
654
648
 
655
 
static inline void store_length(unsigned char *to, uint32_t length, uint32_t pack_length)
 
649
static inline void store_length(uchar *to, uint length, uint pack_length)
656
650
{
657
651
  switch (pack_length) {
658
652
  case 1:
659
 
    *to= (unsigned char) length;
 
653
    *to= (uchar) length;
660
654
    break;
661
655
  case 2:
662
656
    mi_int2store(to, length);
674
668
/** Make a sort-key from record. */
675
669
 
676
670
static void make_sortkey(register SORTPARAM *param,
677
 
                         register unsigned char *to, unsigned char *ref_pos)
 
671
                         register uchar *to, uchar *ref_pos)
678
672
{
679
673
  register Field *field;
680
674
  register SORT_FIELD *sort_field;
681
 
  register uint32_t length;
 
675
  register uint length;
682
676
 
683
677
  for (sort_field=param->local_sortorder ;
684
678
       sort_field != param->end ;
713
707
        const CHARSET_INFO * const cs=item->collation.collation;
714
708
        char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' ');
715
709
        int diff;
716
 
        uint32_t sort_field_length;
 
710
        uint sort_field_length;
717
711
 
718
712
        if (maybe_null)
719
713
          *to++=1;
755
749
        if (sort_field->need_strxnfrm)
756
750
        {
757
751
          char *from=(char*) res->ptr();
758
 
          uint32_t tmp_length;
759
 
          if ((unsigned char*) from == to)
 
752
          uint tmp_length;
 
753
          if ((uchar*) from == to)
760
754
          {
761
755
            set_if_smaller(length,sort_field->length);
762
756
            memcpy(param->tmp_buffer,from,length);
763
757
            from=param->tmp_buffer;
764
758
          }
765
759
          tmp_length= my_strnxfrm(cs,to,sort_field->length,
766
 
                                  (unsigned char*) from, length);
 
760
                                  (uchar*) from, length);
767
761
          assert(tmp_length == sort_field->length);
768
762
        }
769
763
        else
770
764
        {
771
 
          my_strnxfrm(cs,(unsigned char*)to,length,(const unsigned char*)res->ptr(),length);
 
765
          my_strnxfrm(cs,(uchar*)to,length,(const uchar*)res->ptr(),length);
772
766
          cs->cset->fill(cs, (char *)to+length,diff,fill_char);
773
767
        }
774
768
        break;
791
785
            }
792
786
          }
793
787
#if SIZEOF_LONG_LONG > 4
794
 
          to[7]= (unsigned char) value;
795
 
          to[6]= (unsigned char) (value >> 8);
796
 
          to[5]= (unsigned char) (value >> 16);
797
 
          to[4]= (unsigned char) (value >> 24);
798
 
          to[3]= (unsigned char) (value >> 32);
799
 
          to[2]= (unsigned char) (value >> 40);
800
 
          to[1]= (unsigned char) (value >> 48);
 
788
          to[7]= (uchar) value;
 
789
          to[6]= (uchar) (value >> 8);
 
790
          to[5]= (uchar) (value >> 16);
 
791
          to[4]= (uchar) (value >> 24);
 
792
          to[3]= (uchar) (value >> 32);
 
793
          to[2]= (uchar) (value >> 40);
 
794
          to[1]= (uchar) (value >> 48);
801
795
          if (item->unsigned_flag)                    /* Fix sign */
802
 
            to[0]= (unsigned char) (value >> 56);
 
796
            to[0]= (uchar) (value >> 56);
803
797
          else
804
 
            to[0]= (unsigned char) (value >> 56) ^ 128; /* Reverse signbit */
 
798
            to[0]= (uchar) (value >> 56) ^ 128; /* Reverse signbit */
805
799
#else
806
 
          to[3]= (unsigned char) value;
807
 
          to[2]= (unsigned char) (value >> 8);
808
 
          to[1]= (unsigned char) (value >> 16);
 
800
          to[3]= (uchar) value;
 
801
          to[2]= (uchar) (value >> 8);
 
802
          to[1]= (uchar) (value >> 16);
809
803
          if (item->unsigned_flag)                    /* Fix sign */
810
 
            to[0]= (unsigned char) (value >> 24);
 
804
            to[0]= (uchar) (value >> 24);
811
805
          else
812
 
            to[0]= (unsigned char) (value >> 24) ^ 128; /* Reverse signbit */
 
806
            to[0]= (uchar) (value >> 24) ^ 128; /* Reverse signbit */
813
807
#endif
814
808
          break;
815
809
        }
844
838
            }
845
839
            *to++=1;
846
840
          }
847
 
          change_double_for_sort(value,(unsigned char*) to);
 
841
          change_double_for_sort(value,(uchar*) to);
848
842
          break;
849
843
        }
850
844
      case ROW_RESULT:
861
855
      length=sort_field->length;
862
856
      while (length--)
863
857
      {
864
 
        *to = (unsigned char) (~ *to);
 
858
        *to = (uchar) (~ *to);
865
859
        to++;
866
860
      }
867
861
    }
878
872
      the same for all records.
879
873
    */
880
874
    SORT_ADDON_FIELD *addonf= param->addon_field;
881
 
    unsigned char *nulls= to;
 
875
    uchar *nulls= to;
882
876
    assert(addonf != 0);
883
877
    memset(nulls, 0, addonf->offset);
884
878
    to+= addonf->offset;
894
888
      else
895
889
      {
896
890
#ifdef HAVE_purify
897
 
        unsigned char *end= field->pack(to, field->ptr);
898
 
        uint32_t length= (uint32_t) ((to + addonf->length) - end);
 
891
        uchar *end= field->pack(to, field->ptr);
 
892
        uint length= (uint) ((to + addonf->length) - end);
899
893
        assert((int) length >= 0);
900
894
        if (length)
901
895
          memset(end, 0, length);
938
932
    else
939
933
    {                                           // Item
940
934
      sort_field->item->walk(&Item::register_field_in_read_map, 1,
941
 
                             (unsigned char *) table);
 
935
                             (uchar *) table);
942
936
    }
943
937
  }
944
938
 
957
951
}
958
952
 
959
953
 
960
 
static bool save_index(SORTPARAM *param, unsigned char **sort_keys, uint32_t count, 
 
954
static bool save_index(SORTPARAM *param, uchar **sort_keys, uint count, 
961
955
                       filesort_info_st *table_sort)
962
956
{
963
 
  uint32_t offset,res_length;
964
 
  unsigned char *to;
 
957
  uint offset,res_length;
 
958
  uchar *to;
965
959
 
966
 
  my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, param->sort_length);
 
960
  my_string_ptr_sort((uchar*) sort_keys, (uint) count, param->sort_length);
967
961
  res_length= param->res_length;
968
962
  offset= param->rec_length-res_length;
969
963
  if ((ha_rows) count > param->max_rows)
970
 
    count=(uint32_t) param->max_rows;
 
964
    count=(uint) param->max_rows;
971
965
  if (!(to= table_sort->record_pointers= 
972
 
        (unsigned char*) my_malloc(res_length*count, MYF(MY_WME))))
 
966
        (uchar*) my_malloc(res_length*count, MYF(MY_WME))))
973
967
    return(1);                 /* purecov: inspected */
974
 
  for (unsigned char **end= sort_keys+count ; sort_keys != end ; sort_keys++)
 
968
  for (uchar **end= sort_keys+count ; sort_keys != end ; sort_keys++)
975
969
  {
976
970
    memcpy(to, *sort_keys+offset, res_length);
977
971
    to+= res_length;
982
976
 
983
977
/** Merge buffers to make < MERGEBUFF2 buffers. */
984
978
 
985
 
int merge_many_buff(SORTPARAM *param, unsigned char *sort_buffer,
986
 
                    BUFFPEK *buffpek, uint32_t *maxbuffer, IO_CACHE *t_file)
 
979
int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
 
980
                    BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file)
987
981
{
988
 
  register uint32_t i;
 
982
  register uint i;
989
983
  IO_CACHE t_file2,*from_file,*to_file,*temp;
990
984
  BUFFPEK *lastbuff;
991
985
 
1018
1012
    temp=from_file; from_file=to_file; to_file=temp;
1019
1013
    setup_io_cache(from_file);
1020
1014
    setup_io_cache(to_file);
1021
 
    *maxbuffer= (uint32_t) (lastbuff-buffpek)-1;
 
1015
    *maxbuffer= (uint) (lastbuff-buffpek)-1;
1022
1016
  }
1023
1017
cleanup:
1024
1018
  close_cached_file(to_file);                   // This holds old result
1036
1030
  Read data to buffer.
1037
1031
 
1038
1032
  @retval
1039
 
    (uint32_t)-1 if something goes wrong
 
1033
    (uint)-1 if something goes wrong
1040
1034
*/
1041
1035
 
1042
 
uint32_t read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
1043
 
                    uint32_t rec_length)
 
1036
uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
 
1037
                    uint rec_length)
1044
1038
{
1045
 
  register uint32_t count;
1046
 
  uint32_t length;
 
1039
  register uint count;
 
1040
  uint length;
1047
1041
 
1048
 
  if ((count=(uint32_t) cmin((ha_rows) buffpek->max_keys,buffpek->count)))
 
1042
  if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
1049
1043
  {
1050
 
    if (pread(fromfile->file,(unsigned char*) buffpek->base, (length= rec_length*count),buffpek->file_pos) == 0)
1051
 
      return((uint32_t) -1);                    /* purecov: inspected */
 
1044
    if (pread(fromfile->file,(uchar*) buffpek->base, (length= rec_length*count),buffpek->file_pos) == 0)
 
1045
      return((uint) -1);                        /* purecov: inspected */
1052
1046
    buffpek->key=buffpek->base;
1053
1047
    buffpek->file_pos+= length;                 /* New filepos */
1054
1048
    buffpek->count-=    count;
1069
1063
  @param[in] key_length key length
1070
1064
*/
1071
1065
 
1072
 
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint32_t key_length)
 
1066
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
1073
1067
{
1074
 
  unsigned char *reuse_end= reuse->base + reuse->max_keys * key_length;
1075
 
  for (uint32_t i= 0; i < queue->elements; ++i)
 
1068
  uchar *reuse_end= reuse->base + reuse->max_keys * key_length;
 
1069
  for (uint i= 0; i < queue->elements; ++i)
1076
1070
  {
1077
1071
    BUFFPEK *bp= (BUFFPEK *) queue_element(queue, i);
1078
1072
    if (bp->base + bp->max_keys * key_length == reuse->base)
1110
1104
*/
1111
1105
 
1112
1106
int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
1113
 
                  IO_CACHE *to_file, unsigned char *sort_buffer,
 
1107
                  IO_CACHE *to_file, uchar *sort_buffer,
1114
1108
                  BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb,
1115
1109
                  int flag)
1116
1110
{
1117
1111
  int error;
1118
 
  uint32_t rec_length,res_length,offset;
 
1112
  uint rec_length,res_length,offset;
1119
1113
  size_t sort_length;
1120
1114
  uint32_t maxcount;
1121
1115
  ha_rows max_rows,org_max_rows;
1122
1116
  my_off_t to_start_filepos;
1123
 
  unsigned char *strpos;
 
1117
  uchar *strpos;
1124
1118
  BUFFPEK *buffpek;
1125
1119
  QUEUE queue;
1126
1120
  qsort2_cmp cmp;
1140
1134
  res_length= param->res_length;
1141
1135
  sort_length= param->sort_length;
1142
1136
  offset= rec_length-res_length;
1143
 
  maxcount= (uint32_t) (param->keys/((uint32_t) (Tb-Fb) +1));
 
1137
  maxcount= (uint32_t) (param->keys/((uint) (Tb-Fb) +1));
1144
1138
  to_start_filepos= my_b_tell(to_file);
1145
 
  strpos= (unsigned char*) sort_buffer;
 
1139
  strpos= (uchar*) sort_buffer;
1146
1140
  org_max_rows=max_rows= param->max_rows;
1147
1141
 
1148
1142
  /* The following will fire if there is not enough space in sort_buffer */
1158
1152
    cmp= get_ptr_compare(sort_length);
1159
1153
    first_cmp_arg= (void*) &sort_length;
1160
1154
  }
1161
 
  if (init_queue(&queue, (uint32_t) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0,
 
1155
  if (init_queue(&queue, (uint) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0,
1162
1156
                 (queue_compare) cmp, first_cmp_arg))
1163
1157
    return(1);                                /* purecov: inspected */
1164
1158
  for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
1165
1159
  {
1166
1160
    buffpek->base= strpos;
1167
1161
    buffpek->max_keys= maxcount;
1168
 
    strpos+= (uint32_t) (error= (int) read_to_buffer(from_file, buffpek,
 
1162
    strpos+= (uint) (error= (int) read_to_buffer(from_file, buffpek,
1169
1163
                                                                         rec_length));
1170
1164
    if (error == -1)
1171
1165
      goto err;                                 /* purecov: inspected */
1172
1166
    buffpek->max_keys= buffpek->mem_count;      // If less data in buffers than expected
1173
 
    queue_insert(&queue, (unsigned char*) buffpek);
 
1167
    queue_insert(&queue, (uchar*) buffpek);
1174
1168
  }
1175
1169
 
1176
1170
  if (param->unique_buff)
1185
1179
    */
1186
1180
    buffpek= (BUFFPEK*) queue_top(&queue);
1187
1181
    memcpy(param->unique_buff, buffpek->key, rec_length);
1188
 
    if (my_b_write(to_file, (unsigned char*) buffpek->key, rec_length))
 
1182
    if (my_b_write(to_file, (uchar*) buffpek->key, rec_length))
1189
1183
    {
1190
1184
      error=1; goto err;                        /* purecov: inspected */
1191
1185
    }
1213
1207
      if (cmp)                                        // Remove duplicates
1214
1208
      {
1215
1209
        if (!(*cmp)(first_cmp_arg, &(param->unique_buff),
1216
 
                    (unsigned char**) &buffpek->key))
 
1210
                    (uchar**) &buffpek->key))
1217
1211
              goto skip_duplicate;
1218
1212
            memcpy(param->unique_buff, buffpek->key, rec_length);
1219
1213
      }
1220
1214
      if (flag == 0)
1221
1215
      {
1222
 
        if (my_b_write(to_file,(unsigned char*) buffpek->key, rec_length))
 
1216
        if (my_b_write(to_file,(uchar*) buffpek->key, rec_length))
1223
1217
        {
1224
1218
          error=1; goto err;                        /* purecov: inspected */
1225
1219
        }
1226
1220
      }
1227
1221
      else
1228
1222
      {
1229
 
        if (my_b_write(to_file, (unsigned char*) buffpek->key+offset, res_length))
 
1223
        if (my_b_write(to_file, (uchar*) buffpek->key+offset, res_length))
1230
1224
        {
1231
1225
          error=1; goto err;                        /* purecov: inspected */
1232
1226
        }
1244
1238
        if (!(error= (int) read_to_buffer(from_file,buffpek,
1245
1239
                                          rec_length)))
1246
1240
        {
1247
 
          queue_remove(&queue,0);
 
1241
          VOID(queue_remove(&queue,0));
1248
1242
          reuse_freed_buff(&queue, buffpek, rec_length);
1249
1243
          break;                        /* One buffer have been removed */
1250
1244
        }
1264
1258
  */
1265
1259
  if (cmp)
1266
1260
  {
1267
 
    if (!(*cmp)(first_cmp_arg, &(param->unique_buff), (unsigned char**) &buffpek->key))
 
1261
    if (!(*cmp)(first_cmp_arg, &(param->unique_buff), (uchar**) &buffpek->key))
1268
1262
    {
1269
1263
      buffpek->key+= rec_length;         // Remove duplicate
1270
1264
      --buffpek->mem_count;
1275
1269
  {
1276
1270
    if ((ha_rows) buffpek->mem_count > max_rows)
1277
1271
    {                                        /* Don't write too many records */
1278
 
      buffpek->mem_count= (uint32_t) max_rows;
 
1272
      buffpek->mem_count= (uint) max_rows;
1279
1273
      buffpek->count= 0;                        /* Don't read more */
1280
1274
    }
1281
1275
    max_rows-= buffpek->mem_count;
1282
1276
    if (flag == 0)
1283
1277
    {
1284
 
      if (my_b_write(to_file,(unsigned char*) buffpek->key,
 
1278
      if (my_b_write(to_file,(uchar*) buffpek->key,
1285
1279
                     (rec_length*buffpek->mem_count)))
1286
1280
      {
1287
1281
        error= 1; goto err;                        /* purecov: inspected */
1289
1283
    }
1290
1284
    else
1291
1285
    {
1292
 
      register unsigned char *end;
 
1286
      register uchar *end;
1293
1287
      strpos= buffpek->key+offset;
1294
1288
      for (end= strpos+buffpek->mem_count*rec_length ;
1295
1289
           strpos != end ;
1296
1290
           strpos+= rec_length)
1297
1291
      {     
1298
 
        if (my_b_write(to_file, (unsigned char *) strpos, res_length))
 
1292
        if (my_b_write(to_file, (uchar *) strpos, res_length))
1299
1293
        {
1300
1294
          error=1; goto err;                        
1301
1295
        }
1306
1300
         != -1 && error != 0);
1307
1301
 
1308
1302
end:
1309
 
  lastbuff->count= cmin(org_max_rows-max_rows, param->max_rows);
 
1303
  lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
1310
1304
  lastbuff->file_pos= to_start_filepos;
1311
1305
err:
1312
1306
  delete_queue(&queue);
1316
1310
 
1317
1311
        /* Do a merge to output-file (save only positions) */
1318
1312
 
1319
 
static int merge_index(SORTPARAM *param, unsigned char *sort_buffer,
1320
 
                       BUFFPEK *buffpek, uint32_t maxbuffer,
 
1313
static int merge_index(SORTPARAM *param, uchar *sort_buffer,
 
1314
                       BUFFPEK *buffpek, uint maxbuffer,
1321
1315
                       IO_CACHE *tempfile, IO_CACHE *outfile)
1322
1316
{
1323
1317
  if (merge_buffers(param,tempfile,outfile,sort_buffer,buffpek,buffpek,
1327
1321
} /* merge_index */
1328
1322
 
1329
1323
 
1330
 
static uint32_t suffix_length(uint32_t string_length)
 
1324
static uint suffix_length(uint32_t string_length)
1331
1325
{
1332
1326
  if (string_length < 256)
1333
1327
    return 1;
1358
1352
    Total length of sort buffer in bytes
1359
1353
*/
1360
1354
 
1361
 
static uint32_t
1362
 
sortlength(THD *thd, SORT_FIELD *sortorder, uint32_t s_length,
 
1355
static uint
 
1356
sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
1363
1357
           bool *multi_byte_charset)
1364
1358
{
1365
 
  register uint32_t length;
 
1359
  register uint length;
1366
1360
  const CHARSET_INFO *cs;
1367
1361
  *multi_byte_charset= 0;
1368
1362
 
1468
1462
*/
1469
1463
 
1470
1464
static SORT_ADDON_FIELD *
1471
 
get_addon_fields(THD *thd, Field **ptabfield, uint32_t sortlength, uint32_t *plength)
 
1465
get_addon_fields(THD *thd, Field **ptabfield, uint sortlength, uint *plength)
1472
1466
{
1473
1467
  Field **pfield;
1474
1468
  Field *field;
1475
1469
  SORT_ADDON_FIELD *addonf;
1476
 
  uint32_t length= 0;
1477
 
  uint32_t fields= 0;
1478
 
  uint32_t null_fields= 0;
 
1470
  uint length= 0;
 
1471
  uint fields= 0;
 
1472
  uint null_fields= 0;
1479
1473
  MY_BITMAP *read_set= (*ptabfield)->table->read_set;
1480
1474
 
1481
1475
  /*
1555
1549
*/
1556
1550
 
1557
1551
static void 
1558
 
unpack_addon_fields(struct st_sort_addon_field *addon_field, unsigned char *buff)
 
1552
unpack_addon_fields(struct st_sort_addon_field *addon_field, uchar *buff)
1559
1553
{
1560
1554
  Field *field;
1561
1555
  SORT_ADDON_FIELD *addonf= addon_field;
1579
1573
 
1580
1574
#define DBL_EXP_DIG (sizeof(double)*8-DBL_MANT_DIG)
1581
1575
 
1582
 
void change_double_for_sort(double nr,unsigned char *to)
 
1576
void change_double_for_sort(double nr,uchar *to)
1583
1577
{
1584
 
  unsigned char *tmp=(unsigned char*) to;
 
1578
  uchar *tmp=(uchar*) to;
1585
1579
  if (nr == 0.0)
1586
1580
  {                                             /* Change to zero string */
1587
 
    tmp[0]=(unsigned char) 128;
 
1581
    tmp[0]=(uchar) 128;
1588
1582
    memset(tmp+1, 0, sizeof(nr)-1);
1589
1583
  }
1590
1584
  else
1593
1587
    memcpy(tmp,&nr,sizeof(nr));
1594
1588
#else
1595
1589
    {
1596
 
      unsigned char *ptr= (unsigned char*) &nr;
 
1590
      uchar *ptr= (uchar*) &nr;
1597
1591
#if defined(__FLOAT_WORD_ORDER) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
1598
1592
      tmp[0]= ptr[3]; tmp[1]=ptr[2]; tmp[2]= ptr[1]; tmp[3]=ptr[0];
1599
1593
      tmp[4]= ptr[7]; tmp[5]=ptr[6]; tmp[6]= ptr[5]; tmp[7]=ptr[4];
1605
1599
#endif
1606
1600
    if (tmp[0] & 128)                           /* Negative */
1607
1601
    {                                           /* make complement */
1608
 
      uint32_t i;
 
1602
      uint i;
1609
1603
      for (i=0 ; i < sizeof(nr); i++)
1610
 
        tmp[i]=tmp[i] ^ (unsigned char) 255;
 
1604
        tmp[i]=tmp[i] ^ (uchar) 255;
1611
1605
    }
1612
1606
    else
1613
1607
    {                                   /* Set high and move exponent one up */
1614
 
      uint16_t exp_part=(((uint16_t) tmp[0] << 8) | (uint16_t) tmp[1] |
1615
 
                       (uint16_t) 32768);
1616
 
      exp_part+= (uint16_t) 1 << (16-1-DBL_EXP_DIG);
1617
 
      tmp[0]= (unsigned char) (exp_part >> 8);
1618
 
      tmp[1]= (unsigned char) exp_part;
 
1608
      ushort exp_part=(((ushort) tmp[0] << 8) | (ushort) tmp[1] |
 
1609
                       (ushort) 32768);
 
1610
      exp_part+= (ushort) 1 << (16-1-DBL_EXP_DIG);
 
1611
      tmp[0]= (uchar) (exp_part >> 8);
 
1612
      tmp[1]= (uchar) exp_part;
1619
1613
    }
1620
1614
  }
1621
1615
}