~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/filesort.cc

  • Committer: Brian Aker
  • Date: 2010-08-17 01:34:55 UTC
  • mto: (1711.1.23 build)
  • mto: This revision was merged to the branch mainline in revision 1714.
  • Revision ID: brian@tangent.org-20100817013455-zx3nm7qilxvpwrgb
Style on structure cleanup

Show diffs side-by-side

added added

removed removed

Lines of Context:
76
76
static void register_used_fields(SORTPARAM *param);
77
77
static int merge_index(SORTPARAM *param,
78
78
                       unsigned char *sort_buffer,
79
 
                       BUFFPEK *buffpek,
 
79
                       buffpek_st *buffpek,
80
80
                       uint32_t maxbuffer,
81
81
                       internal::IO_CACHE *tempfile,
82
82
                       internal::IO_CACHE *outfile);
86
86
                       filesort_info_st *table_sort);
87
87
static uint32_t suffix_length(uint32_t string_length);
88
88
static uint32_t sortlength(Session *session,
89
 
                           SORT_FIELD *sortorder,
 
89
                           SortField *sortorder,
90
90
                           uint32_t s_length,
91
91
                           bool *multi_byte_charset);
92
 
static SORT_ADDON_FIELD *get_addon_fields(Session *session,
93
 
                                          Field **ptabfield,
94
 
                                          uint32_t sortlength,
95
 
                                          uint32_t *plength);
96
 
static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
 
92
static sort_addon_field_st *get_addon_fields(Session *session,
 
93
                                             Field **ptabfield,
 
94
                                             uint32_t sortlength,
 
95
                                             uint32_t *plength);
 
96
static void unpack_addon_fields(sort_addon_field_st *addon_field,
97
97
                                unsigned char *buff);
98
98
/**
99
99
  Sort a table.
131
131
    examined_rows       will be set to number of examined rows
132
132
*/
133
133
 
134
 
ha_rows filesort(Session *session, Table *table, SORT_FIELD *sortorder, uint32_t s_length,
 
134
ha_rows filesort(Session *session, Table *table, SortField *sortorder, uint32_t s_length,
135
135
                 optimizer::SqlSelect *select, ha_rows max_rows,
136
136
                 bool sort_positions, ha_rows *examined_rows)
137
137
{
138
138
  int error;
139
139
  uint32_t memavl, min_sort_memory;
140
140
  uint32_t maxbuffer;
141
 
  BUFFPEK *buffpek;
 
141
  buffpek_st *buffpek;
142
142
  ha_rows records= HA_POS_ERROR;
143
143
  unsigned char **sort_keys= 0;
144
144
  internal::IO_CACHE tempfile, buffpek_pointers, *selected_records_file, *outfile;
291
291
          (unsigned char *) read_buffpek_from_file(&buffpek_pointers, maxbuffer,
292
292
                                 table_sort.buffpek)))
293
293
      goto err;
294
 
    buffpek= (BUFFPEK *) table_sort.buffpek;
 
294
    buffpek= (buffpek_st *) table_sort.buffpek;
295
295
    table_sort.buffpek_len= maxbuffer;
296
296
    close_cached_file(&buffpek_pointers);
297
297
        /* Open cached file if it isn't open */
421
421
static unsigned char *read_buffpek_from_file(internal::IO_CACHE *buffpek_pointers, uint32_t count,
422
422
                                     unsigned char *buf)
423
423
{
424
 
  uint32_t length= sizeof(BUFFPEK)*count;
 
424
  uint32_t length= sizeof(buffpek_st)*count;
425
425
  unsigned char *tmp= buf;
426
 
  if (count > UINT_MAX/sizeof(BUFFPEK))
427
 
    return 0; /* sizeof(BUFFPEK)*count will overflow */
 
426
  if (count > UINT_MAX/sizeof(buffpek_st))
 
427
    return 0; /* sizeof(buffpek_st)*count will overflow */
428
428
  if (!tmp)
429
429
    tmp= (unsigned char *)malloc(length);
430
430
  if (tmp)
447
447
  @param param             Sorting parameter
448
448
  @param select            Use this to get source data
449
449
  @param sort_keys         Array of pointers to sort key + addon buffers.
450
 
  @param buffpek_pointers  File to write BUFFPEKs describing sorted segments
 
450
  @param buffpek_pointers  File to write buffpek_sts describing sorted segments
451
451
                           in tempfile.
452
452
  @param tempfile          File to write sorted sequences of sortkeys to.
453
453
  @param indexfile         If !NULL, use it for source data (contains rowids)
461
461
       {
462
462
         sort sort_keys buffer;
463
463
         dump sorted sequence to 'tempfile';
464
 
         dump BUFFPEK describing sequence location into 'buffpek_pointers';
 
464
         dump buffpek_st describing sequence location into 'buffpek_pointers';
465
465
       }
466
466
       put sort key into 'sort_keys';
467
467
     }
641
641
  @details
642
642
  Sort the buffer and write:
643
643
  -# the sorted sequence to tempfile
644
 
  -# a BUFFPEK describing the sorted sequence position to buffpek_pointers
 
644
  -# a buffpek_st describing the sorted sequence position to buffpek_pointers
645
645
 
646
646
    (was: Skriver en buffert med nycklar till filen)
647
647
 
648
648
  @param param             Sort parameters
649
649
  @param sort_keys         Array of pointers to keys to sort
650
650
  @param count             Number of elements in sort_keys array
651
 
  @param buffpek_pointers  One 'BUFFPEK' struct will be written into this file.
652
 
                           The BUFFPEK::{file_pos, count} will indicate where
 
651
  @param buffpek_pointers  One 'buffpek_st' struct will be written into this file.
 
652
                           The buffpek_st::{file_pos, count} will indicate where
653
653
                           the sorted data was stored.
654
654
  @param tempfile          The sorted sequence will be written into this file.
655
655
 
665
665
{
666
666
  size_t sort_length, rec_length;
667
667
  unsigned char **end;
668
 
  BUFFPEK buffpek;
 
668
  buffpek_st buffpek;
669
669
 
670
670
  sort_length= param->sort_length;
671
671
  rec_length= param->rec_length;
675
675
                       MYF(MY_WME)))
676
676
    goto err;
677
677
  /* check we won't have more buffpeks than we can possibly keep in memory */
678
 
  if (my_b_tell(buffpek_pointers) + sizeof(BUFFPEK) > (uint64_t)UINT_MAX)
 
678
  if (my_b_tell(buffpek_pointers) + sizeof(buffpek_st) > (uint64_t)UINT_MAX)
679
679
    goto err;
680
680
  buffpek.file_pos= my_b_tell(tempfile);
681
681
  if ((ha_rows) count > param->max_rows)
721
721
static void make_sortkey(register SORTPARAM *param,
722
722
                         register unsigned char *to, unsigned char *ref_pos)
723
723
{
724
 
  register Field *field;
725
 
  register SORT_FIELD *sort_field;
 
724
  Field *field;
 
725
  SortField *sort_field;
726
726
  size_t length;
727
727
 
728
728
  for (sort_field=param->local_sortorder ;
910
910
      In this implementation we use fixed layout for field values -
911
911
      the same for all records.
912
912
    */
913
 
    SORT_ADDON_FIELD *addonf= param->addon_field;
 
913
    sort_addon_field_st *addonf= param->addon_field;
914
914
    unsigned char *nulls= to;
915
915
    assert(addonf != 0);
916
916
    memset(nulls, 0, addonf->offset);
954
954
 
955
955
static void register_used_fields(SORTPARAM *param)
956
956
{
957
 
  register SORT_FIELD *sort_field;
 
957
  SortField *sort_field;
958
958
  Table *table=param->sort_form;
959
959
 
960
960
  for (sort_field= param->local_sortorder ;
976
976
 
977
977
  if (param->addon_field)
978
978
  {
979
 
    SORT_ADDON_FIELD *addonf= param->addon_field;
 
979
    sort_addon_field_st *addonf= param->addon_field;
980
980
    Field *field;
981
981
    for ( ; (field= addonf->field) ; addonf++)
982
982
      table->setReadSet(field->field_index);
1015
1015
/** Merge buffers to make < MERGEBUFF2 buffers. */
1016
1016
 
1017
1017
int merge_many_buff(SORTPARAM *param, unsigned char *sort_buffer,
1018
 
                    BUFFPEK *buffpek, uint32_t *maxbuffer, internal::IO_CACHE *t_file)
 
1018
                    buffpek_st *buffpek, uint32_t *maxbuffer, internal::IO_CACHE *t_file)
1019
1019
{
1020
1020
  register uint32_t i;
1021
1021
  internal::IO_CACHE t_file2,*from_file,*to_file,*temp;
1022
 
  BUFFPEK *lastbuff;
 
1022
  buffpek_st *lastbuff;
1023
1023
 
1024
1024
  if (*maxbuffer < MERGEBUFF2)
1025
1025
    return(0);
1071
1071
    (uint32_t)-1 if something goes wrong
1072
1072
*/
1073
1073
 
1074
 
uint32_t read_to_buffer(internal::IO_CACHE *fromfile, BUFFPEK *buffpek,
 
1074
uint32_t read_to_buffer(internal::IO_CACHE *fromfile, buffpek_st *buffpek,
1075
1075
                        uint32_t rec_length)
1076
1076
{
1077
1077
  register uint32_t count;
1098
1098
  public:
1099
1099
  compare_functor(qsort2_cmp in_key_compare, void *in_compare_arg)
1100
1100
    : key_compare(in_key_compare), key_compare_arg(in_compare_arg) { }
1101
 
  inline bool operator()(const BUFFPEK *i, const BUFFPEK *j) const
 
1101
  inline bool operator()(const buffpek_st *i, const buffpek_st *j) const
1102
1102
  {
1103
1103
    int val= key_compare(key_compare_arg,
1104
1104
                      &i->key, &j->key);
1111
1111
  Merge buffers to one buffer.
1112
1112
 
1113
1113
  @param param        Sort parameter
1114
 
  @param from_file    File with source data (BUFFPEKs point to this file)
 
1114
  @param from_file    File with source data (buffpek_sts point to this file)
1115
1115
  @param to_file      File to write the sorted result data.
1116
1116
  @param sort_buffer  Buffer for data to store up to MERGEBUFF2 sort keys.
1117
 
  @param lastbuff     OUT Store here BUFFPEK describing data written to to_file
1118
 
  @param Fb           First element in source BUFFPEKs array
1119
 
  @param Tb           Last element in source BUFFPEKs array
 
1117
  @param lastbuff     OUT Store here buffpek_st describing data written to to_file
 
1118
  @param Fb           First element in source buffpek_sts array
 
1119
  @param Tb           Last element in source buffpek_sts array
1120
1120
  @param flag
1121
1121
 
1122
1122
  @retval
1127
1127
 
1128
1128
int merge_buffers(SORTPARAM *param, internal::IO_CACHE *from_file,
1129
1129
                  internal::IO_CACHE *to_file, unsigned char *sort_buffer,
1130
 
                  BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb,
 
1130
                  buffpek_st *lastbuff, buffpek_st *Fb, buffpek_st *Tb,
1131
1131
                  int flag)
1132
1132
{
1133
1133
  int error;
1137
1137
  ha_rows max_rows,org_max_rows;
1138
1138
  internal::my_off_t to_start_filepos;
1139
1139
  unsigned char *strpos;
1140
 
  BUFFPEK *buffpek;
 
1140
  buffpek_st *buffpek;
1141
1141
  qsort2_cmp cmp;
1142
1142
  void *first_cmp_arg;
1143
1143
  volatile Session::killed_state *killed= &current_session->killed;
1173
1173
    cmp= internal::get_ptr_compare(sort_length);
1174
1174
    first_cmp_arg= (void*) &sort_length;
1175
1175
  }
1176
 
  priority_queue<BUFFPEK *, vector<BUFFPEK *>, compare_functor > 
 
1176
  priority_queue<buffpek_st *, vector<buffpek_st *>, compare_functor > 
1177
1177
    queue(compare_functor(cmp, first_cmp_arg));
1178
1178
  for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
1179
1179
  {
1333
1333
        /* Do a merge to output-file (save only positions) */
1334
1334
 
1335
1335
static int merge_index(SORTPARAM *param, unsigned char *sort_buffer,
1336
 
                       BUFFPEK *buffpek, uint32_t maxbuffer,
 
1336
                       buffpek_st *buffpek, uint32_t maxbuffer,
1337
1337
                       internal::IO_CACHE *tempfile, internal::IO_CACHE *outfile)
1338
1338
{
1339
1339
  if (merge_buffers(param,tempfile,outfile,sort_buffer,buffpek,buffpek,
1375
1375
*/
1376
1376
 
1377
1377
static uint32_t
1378
 
sortlength(Session *session, SORT_FIELD *sortorder, uint32_t s_length,
 
1378
sortlength(Session *session, SortField *sortorder, uint32_t s_length,
1379
1379
           bool *multi_byte_charset)
1380
1380
{
1381
1381
  register uint32_t length;
1481
1481
    NULL   if we do not store field values with sort data.
1482
1482
*/
1483
1483
 
1484
 
static SORT_ADDON_FIELD *
 
1484
static sort_addon_field_st *
1485
1485
get_addon_fields(Session *session, Field **ptabfield, uint32_t sortlength, uint32_t *plength)
1486
1486
{
1487
1487
  Field **pfield;
1488
1488
  Field *field;
1489
 
  SORT_ADDON_FIELD *addonf;
 
1489
  sort_addon_field_st *addonf;
1490
1490
  uint32_t length= 0;
1491
1491
  uint32_t fields= 0;
1492
1492
  uint32_t null_fields= 0;
1518
1518
  length+= (null_fields+7)/8;
1519
1519
 
1520
1520
  if (length+sortlength > session->variables.max_length_for_sort_data ||
1521
 
      !(addonf= (SORT_ADDON_FIELD *) malloc(sizeof(SORT_ADDON_FIELD)*
 
1521
      !(addonf= (sort_addon_field_st *) malloc(sizeof(sort_addon_field_st)*
1522
1522
                                            (fields+1))))
1523
1523
    return 0;
1524
1524
 
1568
1568
*/
1569
1569
 
1570
1570
static void
1571
 
unpack_addon_fields(struct st_sort_addon_field *addon_field, unsigned char *buff)
 
1571
unpack_addon_fields(struct sort_addon_field_st *addon_field, unsigned char *buff)
1572
1572
{
1573
1573
  Field *field;
1574
 
  SORT_ADDON_FIELD *addonf= addon_field;
 
1574
  sort_addon_field_st *addonf= addon_field;
1575
1575
 
1576
1576
  for ( ; (field= addonf->field) ; addonf++)
1577
1577
  {