~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/filesort.cc

  • Committer: Mark Atwood
  • Date: 2011-08-11 03:05:03 UTC
  • mfrom: (2385.1.12 refactor4)
  • Revision ID: me@mark.atwood.name-20110811030503-rp9xjihc5x3y0x4q
merge lp:~olafvdspek/drizzle/refactor4

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
  Sorts a database
22
22
*/
23
23
 
24
 
#include "config.h"
 
24
#include <config.h>
25
25
 
26
26
#include <float.h>
27
27
#include <limits.h>
30
30
#include <algorithm>
31
31
#include <iostream>
32
32
 
33
 
#include "drizzled/drizzled.h"
34
 
#include "drizzled/sql_sort.h"
35
 
#include "drizzled/filesort.h"
36
 
#include "drizzled/error.h"
37
 
#include "drizzled/probes.h"
38
 
#include "drizzled/session.h"
39
 
#include "drizzled/table.h"
40
 
#include "drizzled/table_list.h"
41
 
#include "drizzled/optimizer/range.h"
42
 
#include "drizzled/records.h"
43
 
#include "drizzled/internal/iocache.h"
44
 
#include "drizzled/internal/my_sys.h"
45
 
#include "plugin/myisam/myisam.h"
46
 
#include "drizzled/plugin/transactional_storage_engine.h"
47
 
#include "drizzled/atomics.h"
48
 
#include "drizzled/global_buffer.h"
49
 
 
 
33
#include <drizzled/drizzled.h>
 
34
#include <drizzled/sql_sort.h>
 
35
#include <drizzled/filesort.h>
 
36
#include <drizzled/error.h>
 
37
#include <drizzled/probes.h>
 
38
#include <drizzled/session.h>
 
39
#include <drizzled/table.h>
 
40
#include <drizzled/table_list.h>
 
41
#include <drizzled/optimizer/range.h>
 
42
#include <drizzled/records.h>
 
43
#include <drizzled/internal/iocache.h>
 
44
#include <drizzled/internal/my_sys.h>
 
45
#include <plugin/myisam/myisam.h>
 
46
#include <drizzled/plugin/transactional_storage_engine.h>
 
47
#include <drizzled/atomics.h>
 
48
#include <drizzled/global_buffer.h>
 
49
#include <drizzled/sort_field.h>
 
50
#include <drizzled/item/subselect.h>
 
51
#include <drizzled/statistics_variables.h>
 
52
#include <drizzled/system_variables.h>
50
53
 
51
54
using namespace std;
52
55
 
53
 
namespace drizzled
54
 
{
 
56
namespace drizzled {
55
57
 
56
58
/* Defines used by filesort and uniques */
57
59
#define MERGEBUFF               7
112
114
 
113
115
  ~SortParam()
114
116
  {
115
 
    if (tmp_buffer)
116
 
      free(tmp_buffer);
 
117
    free(tmp_buffer);
117
118
  }
118
119
 
119
120
  int write_keys(unsigned char * *sort_keys,
120
121
                 uint32_t count,
121
 
                 internal::IO_CACHE *buffer_file,
122
 
                 internal::IO_CACHE *tempfile);
 
122
                 internal::io_cache_st *buffer_file,
 
123
                 internal::io_cache_st *tempfile);
123
124
 
124
125
  void make_sortkey(unsigned char *to,
125
126
                    unsigned char *ref_pos);
126
127
  void register_used_fields();
127
 
  bool save_index(unsigned char **sort_keys,
 
128
  void save_index(unsigned char **sort_keys,
128
129
                  uint32_t count,
129
130
                  filesort_info *table_sort);
130
131
 
132
133
 
133
134
/* functions defined in this file */
134
135
 
135
 
static char **make_char_array(char **old_pos, register uint32_t fields,
 
136
static char **make_char_array(char **old_pos, uint32_t fields,
136
137
                              uint32_t length);
137
138
 
138
 
static unsigned char *read_buffpek_from_file(internal::IO_CACHE *buffer_file,
 
139
static unsigned char *read_buffpek_from_file(internal::io_cache_st *buffer_file,
139
140
                                             uint32_t count,
140
141
                                             unsigned char *buf);
141
142
 
194
195
  buffpek *buffpek_inst= 0;
195
196
  ha_rows records= HA_POS_ERROR;
196
197
  unsigned char **sort_keys= 0;
197
 
  internal::IO_CACHE tempfile;
198
 
  internal::IO_CACHE buffpek_pointers;
199
 
  internal::IO_CACHE *selected_records_file;
200
 
  internal::IO_CACHE *outfile;
 
198
  internal::io_cache_st tempfile;
 
199
  internal::io_cache_st buffpek_pointers;
 
200
  internal::io_cache_st *selected_records_file;
 
201
  internal::io_cache_st *outfile;
201
202
  SortParam param;
202
203
  bool multi_byte_charset;
203
204
 
246
247
  if (param.addon_field)
247
248
  {
248
249
    param.res_length= param.addon_length;
249
 
    if (!(table_sort.addon_buf= (unsigned char *) malloc(param.addon_length)))
250
 
    {
251
 
      goto err;
252
 
    }
 
250
    table_sort.addon_buf= (unsigned char *) malloc(param.addon_length);
253
251
  }
254
252
  else
255
253
  {
291
289
    selected_records_file= 0;
292
290
  }
293
291
 
294
 
  if (multi_byte_charset && !(param.tmp_buffer= (char*) malloc(param.sort_length)))
295
 
  {
296
 
    goto err;
297
 
  }
 
292
  if (multi_byte_charset)
 
293
    param.tmp_buffer= (char*) malloc(param.sort_length);
298
294
 
299
295
  memavl= getSession().variables.sortbuff_size;
300
296
  min_sort_memory= max((uint32_t)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
345
341
 
346
342
  if (maxbuffer == 0)                   // The whole set is in memory
347
343
  {
348
 
    if (param.save_index(sort_keys,(uint32_t) records, &table_sort))
349
 
    {
350
 
      goto err;
351
 
    }
 
344
    param.save_index(sort_keys,(uint32_t) records, &table_sort);
352
345
  }
353
346
  else
354
347
  {
355
348
    if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
356
349
    {
357
 
      if (table_sort.buffpek)
358
 
        free(table_sort.buffpek);
 
350
      free(table_sort.buffpek);
359
351
      table_sort.buffpek = 0;
360
352
    }
361
353
    if (!(table_sort.buffpek=
454
446
 
455
447
/** Make a array of string pointers. */
456
448
 
457
 
static char **make_char_array(char **old_pos, register uint32_t fields,
 
449
static char **make_char_array(char **old_pos, uint32_t fields,
458
450
                              uint32_t length)
459
451
{
460
 
  register char **pos;
461
 
  char *char_pos;
462
 
 
463
 
  if (old_pos ||
464
 
      (old_pos= (char**) malloc((uint32_t) fields*(length+sizeof(char*)))))
465
 
  {
466
 
    pos=old_pos; char_pos=((char*) (pos+fields)) -length;
467
 
    while (fields--) *(pos++) = (char_pos+= length);
468
 
  }
469
 
 
470
 
  return(old_pos);
 
452
  if (not old_pos)
 
453
    old_pos= (char**) malloc((uint32_t) fields * (length + sizeof(char*)));
 
454
  char** pos= old_pos; 
 
455
  char* char_pos= ((char*) (pos+fields)) - length;
 
456
  while (fields--) 
 
457
    *(pos++) = (char_pos+= length);
 
458
 
 
459
  return old_pos;
471
460
} /* make_char_array */
472
461
 
473
462
 
474
463
/** Read 'count' number of buffer pointers into memory. */
475
464
 
476
 
static unsigned char *read_buffpek_from_file(internal::IO_CACHE *buffpek_pointers, uint32_t count,
 
465
static unsigned char *read_buffpek_from_file(internal::io_cache_st *buffpek_pointers, uint32_t count,
477
466
                                     unsigned char *buf)
478
467
{
479
468
  uint32_t length= sizeof(buffpek)*count;
482
471
    return 0; /* sizeof(buffpek)*count will overflow */
483
472
  if (!tmp)
484
473
    tmp= (unsigned char *)malloc(length);
485
 
  if (tmp)
486
474
  {
487
475
    if (buffpek_pointers->reinit_io_cache(internal::READ_CACHE,0L,0,0) ||
488
476
        my_b_read(buffpek_pointers, (unsigned char*) tmp, length))
535
523
ha_rows FileSort::find_all_keys(SortParam *param, 
536
524
                                optimizer::SqlSelect *select,
537
525
                                unsigned char **sort_keys,
538
 
                                internal::IO_CACHE *buffpek_pointers,
539
 
                                internal::IO_CACHE *tempfile, internal::IO_CACHE *indexfile)
 
526
                                internal::io_cache_st *buffpek_pointers,
 
527
                                internal::io_cache_st *tempfile, internal::io_cache_st *indexfile)
540
528
{
541
529
  int error,flag,quick_select;
542
530
  uint32_t idx,indexpos,ref_length;
721
709
    1 Error
722
710
*/
723
711
 
724
 
int SortParam::write_keys(register unsigned char **sort_keys, uint32_t count,
725
 
                          internal::IO_CACHE *buffpek_pointers, internal::IO_CACHE *tempfile)
 
712
int SortParam::write_keys(unsigned char **sort_keys, uint32_t count,
 
713
                          internal::io_cache_st *buffpek_pointers, internal::io_cache_st *tempfile)
726
714
{
727
715
  buffpek buffpek;
728
716
 
786
774
 
787
775
/** Make a sort-key from record. */
788
776
 
789
 
void SortParam::make_sortkey(register unsigned char *to, unsigned char *ref_pos)
 
777
void SortParam::make_sortkey(unsigned char *to, unsigned char *ref_pos)
790
778
{
791
779
  Field *field;
792
780
  SortField *sort_field;
823
811
      switch (sort_field->result_type) {
824
812
      case STRING_RESULT:
825
813
        {
826
 
          const CHARSET_INFO * const cs=item->collation.collation;
 
814
          const charset_info_st * const cs=item->collation.collation;
827
815
          char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' ');
828
816
          int diff;
829
817
          uint32_t sort_field_length;
1019
1007
 
1020
1008
 
1021
1009
/*
1022
 
  Register fields used by sorting in the sorted table's read set
 
1010
  fields used by sorting in the sorted table's read set
1023
1011
*/
1024
1012
 
1025
1013
void SortParam::register_used_fields()
1059
1047
}
1060
1048
 
1061
1049
 
1062
 
bool SortParam::save_index(unsigned char **sort_keys, uint32_t count, filesort_info *table_sort)
 
1050
void SortParam::save_index(unsigned char **sort_keys, uint32_t count, filesort_info *table_sort)
1063
1051
{
1064
 
  uint32_t offset;
1065
 
  unsigned char *to;
1066
 
 
1067
1052
  internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
1068
 
  offset= rec_length - res_length;
 
1053
  uint32_t offset= rec_length - res_length;
1069
1054
 
1070
1055
  if ((ha_rows) count > max_rows)
1071
1056
    count=(uint32_t) max_rows;
1072
1057
 
1073
 
  if (!(to= table_sort->record_pointers= (unsigned char*) malloc(res_length*count)))
1074
 
    return true;
 
1058
  unsigned char* to= table_sort->record_pointers= (unsigned char*) malloc(res_length*count);
1075
1059
 
1076
1060
  for (unsigned char **end_ptr= sort_keys+count ; sort_keys != end_ptr ; sort_keys++)
1077
1061
  {
1078
1062
    memcpy(to, *sort_keys+offset, res_length);
1079
1063
    to+= res_length;
1080
1064
  }
1081
 
 
1082
 
  return false;
1083
1065
}
1084
1066
 
1085
1067
 
1086
1068
/** Merge buffers to make < MERGEBUFF2 buffers. */
1087
1069
 
1088
1070
int FileSort::merge_many_buff(SortParam *param, unsigned char *sort_buffer,
1089
 
                              buffpek *buffpek_inst, uint32_t *maxbuffer, internal::IO_CACHE *t_file)
 
1071
                              buffpek *buffpek_inst, uint32_t *maxbuffer, internal::io_cache_st *t_file)
1090
1072
{
1091
 
  internal::IO_CACHE t_file2,*from_file,*to_file,*temp;
 
1073
  internal::io_cache_st t_file2,*from_file,*to_file,*temp;
1092
1074
  buffpek *lastbuff;
1093
1075
 
1094
1076
  if (*maxbuffer < MERGEBUFF2)
1102
1084
  from_file= t_file ; to_file= &t_file2;
1103
1085
  while (*maxbuffer >= MERGEBUFF2)
1104
1086
  {
1105
 
    register uint32_t i;
 
1087
    uint32_t i;
1106
1088
 
1107
1089
    if (from_file->reinit_io_cache(internal::READ_CACHE,0L,0,0))
1108
1090
    {
1160
1142
    (uint32_t)-1 if something goes wrong
1161
1143
*/
1162
1144
 
1163
 
uint32_t FileSort::read_to_buffer(internal::IO_CACHE *fromfile, buffpek *buffpek_inst, uint32_t rec_length)
 
1145
uint32_t FileSort::read_to_buffer(internal::io_cache_st *fromfile, buffpek *buffpek_inst, uint32_t rec_length)
1164
1146
{
1165
 
  register uint32_t count;
 
1147
  uint32_t count;
1166
1148
  uint32_t length;
1167
1149
 
1168
1150
  if ((count= (uint32_t) min((ha_rows) buffpek_inst->max_keys,buffpek_inst->count)))
1217
1199
    other  error
1218
1200
*/
1219
1201
 
1220
 
int FileSort::merge_buffers(SortParam *param, internal::IO_CACHE *from_file,
1221
 
                            internal::IO_CACHE *to_file, unsigned char *sort_buffer,
 
1202
int FileSort::merge_buffers(SortParam *param, internal::io_cache_st *from_file,
 
1203
                            internal::io_cache_st *to_file, unsigned char *sort_buffer,
1222
1204
                            buffpek *lastbuff, buffpek *Fb, buffpek *Tb,
1223
1205
                            int flag)
1224
1206
{
1403
1385
    }
1404
1386
    else
1405
1387
    {
1406
 
      register unsigned char *end;
 
1388
      unsigned char *end;
1407
1389
      strpos= buffpek_inst->key+offset;
1408
1390
      for (end= strpos+buffpek_inst->mem_count*rec_length ;
1409
1391
           strpos != end ;
1432
1414
 
1433
1415
int FileSort::merge_index(SortParam *param, unsigned char *sort_buffer,
1434
1416
                          buffpek *buffpek_inst, uint32_t maxbuffer,
1435
 
                          internal::IO_CACHE *tempfile, internal::IO_CACHE *outfile)
 
1417
                          internal::io_cache_st *tempfile, internal::io_cache_st *outfile)
1436
1418
{
1437
1419
  if (merge_buffers(param,tempfile,outfile,sort_buffer,buffpek_inst,buffpek_inst,
1438
1420
                    buffpek_inst+maxbuffer,1))
1474
1456
 
1475
1457
uint32_t FileSort::sortlength(SortField *sortorder, uint32_t s_length, bool *multi_byte_charset)
1476
1458
{
1477
 
  register uint32_t length;
1478
 
  const CHARSET_INFO *cs;
 
1459
  uint32_t length;
 
1460
  const charset_info_st *cs;
1479
1461
  *multi_byte_charset= 0;
1480
1462
 
1481
1463
  length=0;
1610
1592
    return 0;
1611
1593
  length+= (null_fields+7)/8;
1612
1594
 
1613
 
  if (length+sortlength_arg > getSession().variables.max_length_for_sort_data ||
1614
 
      !(addonf= (sort_addon_field *) malloc(sizeof(sort_addon_field)*
1615
 
                                            (fields+1))))
 
1595
  if (length+sortlength_arg > getSession().variables.max_length_for_sort_data)
1616
1596
    return 0;
 
1597
  addonf= (sort_addon_field *) malloc(sizeof(sort_addon_field) * (fields+1));
1617
1598
 
1618
1599
  *plength= length;
1619
1600
  length= (null_fields+7)/8;