24
#include <drizzled/server_includes.h>
24
#include "mysql_priv.h"
25
26
#include "sql_sort.h"
26
#include <drizzled/drizzled_error_messages.h>
28
/// How to write record_ref.
29
#define WRITE_REF(file,from) \
30
if (my_b_write((file),(uchar*) (from),param->ref_length)) \
28
33
/* functions defined in this file */
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,
35
static char **make_char_array(char **old_pos, register uint fields,
36
uint length, myf my_flag);
37
static uchar *read_buffpek_from_file(IO_CACHE *buffer_file, uint count,
34
39
static ha_rows find_all_keys(SORTPARAM *param,SQL_SELECT *select,
35
unsigned char * *sort_keys, IO_CACHE *buffer_file,
40
uchar * *sort_keys, IO_CACHE *buffer_file,
36
41
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);
42
static int write_keys(SORTPARAM *param,uchar * *sort_keys,
43
uint count, IO_CACHE *buffer_file, IO_CACHE *tempfile);
44
static void make_sortkey(SORTPARAM *param,uchar *to, uchar *ref_pos);
40
45
static void register_used_fields(SORTPARAM *param);
41
static int merge_index(SORTPARAM *param,unsigned char *sort_buffer,
46
static int merge_index(SORTPARAM *param,uchar *sort_buffer,
43
uint32_t maxbuffer,IO_CACHE *tempfile,
48
uint maxbuffer,IO_CACHE *tempfile,
44
49
IO_CACHE *outfile);
45
static bool save_index(SORTPARAM *param,unsigned char **sort_keys, uint32_t count,
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,
50
static bool save_index(SORTPARAM *param,uchar **sort_keys, uint count,
51
FILESORT_INFO *table_sort);
52
static uint suffix_length(ulong string_length);
53
static uint sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
49
54
bool *multi_byte_charset);
50
55
static SORT_ADDON_FIELD *get_addon_fields(THD *thd, Field **ptabfield,
51
uint32_t sortlength, uint32_t *plength);
56
uint sortlength, uint *plength);
52
57
static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
56
61
Creates a set of pointers that can be used to read the rows
87
92
examined_rows will be set to number of examined rows
90
ha_rows filesort(THD *thd, Table *table, SORT_FIELD *sortorder, uint32_t s_length,
95
ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
91
96
SQL_SELECT *select, ha_rows max_rows,
92
97
bool sort_positions, ha_rows *examined_rows)
95
uint32_t memavl, min_sort_memory;
100
ulong memavl, min_sort_memory;
98
103
ha_rows records= HA_POS_ERROR;
99
unsigned char **sort_keys= 0;
104
uchar **sort_keys= 0;
100
105
IO_CACHE tempfile, buffpek_pointers, *selected_records_file, *outfile;
102
107
bool multi_byte_charset;
104
filesort_info_st table_sort;
105
TableList *tab= table->pos_in_table_list;
109
FILESORT_INFO table_sort;
110
TABLE_LIST *tab= table->pos_in_table_list;
106
111
Item_subselect *subselect= tab ? tab->containing_subselect() : 0;
108
DRIZZLE_FILESORT_START();
113
MYSQL_FILESORT_START();
111
116
Release InnoDB's adaptive hash index latch (if holding) before
126
131
my_b_clear(&buffpek_pointers);
129
memset(¶m, 0, sizeof(param));
134
bzero((char*) ¶m,sizeof(param));
130
135
param.sort_length= sortlength(thd, sortorder, s_length, &multi_byte_charset);
131
136
param.ref_length= table->file->ref_length;
132
137
param.addon_field= 0;
133
138
param.addon_length= 0;
134
if (!(table->file->ha_table_flags() & HA_FAST_KEY_READ) && !sort_positions)
139
if (!(table->file->ha_table_flags() & HA_FAST_KEY_READ) &&
140
!table->fulltext_searched && !sort_positions)
137
143
Get the descriptors of all fields whose values are appended
200
206
memavl= thd->variables.sortbuff_size;
201
min_sort_memory= cmax((uint32_t)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
207
min_sort_memory= max(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
202
208
while (memavl >= min_sort_memory)
205
uint32_t keys= memavl/(param.rec_length+sizeof(char*));
206
param.keys=(uint32_t) cmin(records+1, keys);
211
ulong keys= memavl/(param.rec_length+sizeof(char*));
212
param.keys=(uint) min(records+1, keys);
207
213
if ((table_sort.sort_keys=
208
(unsigned char **) make_char_array((char **) table_sort.sort_keys,
214
(uchar **) make_char_array((char **) table_sort.sort_keys,
209
215
param.keys, param.rec_length, MYF(0))))
211
217
old_memavl=memavl;
229
235
&tempfile, selected_records_file)) ==
232
maxbuffer= (uint32_t) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek));
238
maxbuffer= (uint) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek));
234
240
if (maxbuffer == 0) // The whole set is in memory
236
if (save_index(¶m,sort_keys,(uint32_t) records, &table_sort))
242
if (save_index(¶m,sort_keys,(uint) records, &table_sort))
241
247
if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
243
if (table_sort.buffpek)
244
free(table_sort.buffpek);
249
x_free(table_sort.buffpek);
245
250
table_sort.buffpek= 0;
247
252
if (!(table_sort.buffpek=
248
(unsigned char *) read_buffpek_from_file(&buffpek_pointers, maxbuffer,
253
(uchar *) read_buffpek_from_file(&buffpek_pointers, maxbuffer,
249
254
table_sort.buffpek)))
251
256
buffpek= (BUFFPEK *) table_sort.buffpek;
266
271
param.keys=((param.keys*(param.rec_length+sizeof(char*))) /
267
272
param.rec_length-1);
268
273
maxbuffer--; // Offset from 0
269
if (merge_many_buff(¶m,(unsigned char*) sort_keys,buffpek,&maxbuffer,
274
if (merge_many_buff(¶m,(uchar*) sort_keys,buffpek,&maxbuffer,
272
277
if (flush_io_cache(&tempfile) ||
273
278
reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
275
if (merge_index(¶m,(unsigned char*) sort_keys,buffpek,maxbuffer,&tempfile,
280
if (merge_index(¶m,(uchar*) sort_keys,buffpek,maxbuffer,&tempfile,
313
315
MYF(ME_ERROR+ME_WAITTANG));
315
317
statistic_add(thd->status_var.filesort_rows,
316
(uint32_t) records, &LOCK_status);
318
(ulong) records, &LOCK_status);
317
319
*examined_rows= param.examined_rows;
318
memcpy(&table->sort, &table_sort, sizeof(filesort_info_st));
319
DRIZZLE_FILESORT_END();
320
memcpy(&table->sort, &table_sort, sizeof(FILESORT_INFO));
321
MYSQL_FILESORT_END();
320
322
return(error ? HA_POS_ERROR : records);
324
void filesort_free_buffers(Table *table, bool full)
326
void filesort_free_buffers(TABLE *table, bool full)
326
328
if (table->sort.record_pointers)
328
free((unsigned char*) table->sort.record_pointers);
330
my_free((uchar*) table->sort.record_pointers,MYF(0));
329
331
table->sort.record_pointers=0;
333
335
if (table->sort.sort_keys )
335
if ((unsigned char*) table->sort.sort_keys)
336
free((unsigned char*) table->sort.sort_keys);
337
x_free((uchar*) table->sort.sort_keys);
337
338
table->sort.sort_keys= 0;
339
340
if (table->sort.buffpek)
341
if ((unsigned char*) table->sort.buffpek)
342
free((unsigned char*) table->sort.buffpek);
342
x_free((uchar*) table->sort.buffpek);
343
343
table->sort.buffpek= 0;
344
344
table->sort.buffpek_len= 0;
347
347
if (table->sort.addon_buf)
349
free((char *) table->sort.addon_buf);
350
free((char *) table->sort.addon_field);
349
my_free((char *) table->sort.addon_buf, MYF(0));
350
my_free((char *) table->sort.addon_field, MYF(MY_ALLOW_ZERO_PTR));
351
351
table->sort.addon_buf=0;
352
352
table->sort.addon_field=0;
356
356
/** Make a array of string pointers. */
358
static char **make_char_array(char **old_pos, register uint32_t fields,
359
uint32_t length, myf my_flag)
358
static char **make_char_array(char **old_pos, register uint fields,
359
uint length, myf my_flag)
361
361
register char **pos;
365
(old_pos= (char**) my_malloc((uint32_t) fields*(length+sizeof(char*)),
365
(old_pos= (char**) my_malloc((uint) fields*(length+sizeof(char*)),
368
368
pos=old_pos; char_pos=((char*) (pos+fields)) -length;
376
376
/** Read 'count' number of buffer pointers into memory. */
378
static unsigned char *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint32_t count,
378
static uchar *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count,
381
uint32_t length= sizeof(BUFFPEK)*count;
382
unsigned char *tmp= buf;
381
ulong length= sizeof(BUFFPEK)*count;
383
383
if (count > UINT_MAX/sizeof(BUFFPEK))
384
384
return 0; /* sizeof(BUFFPEK)*count will overflow */
386
tmp= (unsigned char *)my_malloc(length, MYF(MY_WME));
386
tmp= (uchar *)my_malloc(length, MYF(MY_WME));
389
389
if (reinit_io_cache(buffpek_pointers,READ_CACHE,0L,0,0) ||
390
my_b_read(buffpek_pointers, (unsigned char*) tmp, length))
390
my_b_read(buffpek_pointers, (uchar*) tmp, length))
392
my_free((char*) tmp, MYF(0));
437
437
static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
438
unsigned char **sort_keys,
439
439
IO_CACHE *buffpek_pointers,
440
440
IO_CACHE *tempfile, IO_CACHE *indexfile)
442
442
int error,flag,quick_select;
443
uint32_t idx,indexpos,ref_length;
444
unsigned char *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
443
uint idx,indexpos,ref_length;
444
uchar *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
447
447
THD *thd= current_thd;
448
448
volatile THD::killed_state *killed= &thd->killed;
621
write_keys(SORTPARAM *param, register unsigned char **sort_keys, uint32_t count,
618
write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
622
619
IO_CACHE *buffpek_pointers, IO_CACHE *tempfile)
624
621
size_t sort_length, rec_length;
628
625
sort_length= param->sort_length;
629
626
rec_length= param->rec_length;
630
my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
627
my_string_ptr_sort((uchar*) sort_keys, (uint) count, sort_length);
631
628
if (!my_b_inited(tempfile) &&
632
629
open_cached_file(tempfile, mysql_tmpdir, TEMP_PREFIX, DISK_BUFFER_SIZE,
634
631
goto err; /* purecov: inspected */
635
632
/* check we won't have more buffpeks than we can possibly keep in memory */
636
if (my_b_tell(buffpek_pointers) + sizeof(BUFFPEK) > (uint64_t)UINT_MAX)
633
if (my_b_tell(buffpek_pointers) + sizeof(BUFFPEK) > (ulonglong)UINT_MAX)
638
635
buffpek.file_pos= my_b_tell(tempfile);
639
636
if ((ha_rows) count > param->max_rows)
640
count=(uint32_t) param->max_rows; /* purecov: inspected */
637
count=(uint) param->max_rows; /* purecov: inspected */
641
638
buffpek.count=(ha_rows) count;
642
639
for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
643
if (my_b_write(tempfile, (unsigned char*) *sort_keys, (uint32_t) rec_length))
640
if (my_b_write(tempfile, (uchar*) *sort_keys, (uint) rec_length))
645
if (my_b_write(buffpek_pointers, (unsigned char*) &buffpek, sizeof(buffpek)))
642
if (my_b_write(buffpek_pointers, (uchar*) &buffpek, sizeof(buffpek)))
758
755
if (sort_field->need_strxnfrm)
760
757
char *from=(char*) res->ptr();
762
if ((unsigned char*) from == to)
759
if ((uchar*) from == to)
764
761
set_if_smaller(length,sort_field->length);
765
762
memcpy(param->tmp_buffer,from,length);
766
763
from=param->tmp_buffer;
768
765
tmp_length= my_strnxfrm(cs,to,sort_field->length,
769
(unsigned char*) from, length);
766
(uchar*) from, length);
770
767
assert(tmp_length == sort_field->length);
774
my_strnxfrm(cs,(unsigned char*)to,length,(const unsigned char*)res->ptr(),length);
771
my_strnxfrm(cs,(uchar*)to,length,(const uchar*)res->ptr(),length);
775
772
cs->cset->fill(cs, (char *)to+length,diff,fill_char);
781
int64_t value= item->val_int_result();
778
longlong value= item->val_int_result();
784
781
*to++=1; /* purecov: inspected */
785
782
if (item->null_value)
788
memset(to-1, 0, sort_field->length+1);
785
bzero((char*) to-1,sort_field->length+1);
791
memset(to, 0, sort_field->length);
788
bzero((char*) to,sort_field->length);
796
to[7]= (unsigned char) value;
797
to[6]= (unsigned char) (value >> 8);
798
to[5]= (unsigned char) (value >> 16);
799
to[4]= (unsigned char) (value >> 24);
800
to[3]= (unsigned char) (value >> 32);
801
to[2]= (unsigned char) (value >> 40);
802
to[1]= (unsigned char) (value >> 48);
803
if (item->unsigned_flag) /* Fix sign */
804
to[0]= (unsigned char) (value >> 56);
806
to[0]= (unsigned char) (value >> 56) ^ 128; /* Reverse signbit */
793
#if SIZEOF_LONG_LONG > 4
794
to[7]= (uchar) value;
795
to[6]= (uchar) (value >> 8);
796
to[5]= (uchar) (value >> 16);
797
to[4]= (uchar) (value >> 24);
798
to[3]= (uchar) (value >> 32);
799
to[2]= (uchar) (value >> 40);
800
to[1]= (uchar) (value >> 48);
801
if (item->unsigned_flag) /* Fix sign */
802
to[0]= (uchar) (value >> 56);
804
to[0]= (uchar) (value >> 56) ^ 128; /* Reverse signbit */
806
to[3]= (uchar) value;
807
to[2]= (uchar) (value >> 8);
808
to[1]= (uchar) (value >> 16);
809
if (item->unsigned_flag) /* Fix sign */
810
to[0]= (uchar) (value >> 24);
812
to[0]= (uchar) (value >> 24) ^ 128; /* Reverse signbit */
809
816
case DECIMAL_RESULT:
882
889
nulls[addonf->null_offset]|= addonf->null_bit;
883
890
#ifdef HAVE_purify
884
memset(to, 0, addonf->length);
891
bzero(to, addonf->length);
889
896
#ifdef HAVE_purify
890
unsigned char *end= field->pack(to, field->ptr);
891
uint32_t length= (uint32_t) ((to + addonf->length) - end);
897
uchar *end= field->pack(to, field->ptr);
898
uint length= (uint) ((to + addonf->length) - end);
892
899
assert((int) length >= 0);
894
memset(end, 0, length);
896
903
(void) field->pack(to, field->ptr);
953
static bool save_index(SORTPARAM *param, unsigned char **sort_keys, uint32_t count,
954
filesort_info_st *table_sort)
960
static bool save_index(SORTPARAM *param, uchar **sort_keys, uint count,
961
FILESORT_INFO *table_sort)
956
uint32_t offset,res_length;
963
uint offset,res_length;
959
my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, param->sort_length);
966
my_string_ptr_sort((uchar*) sort_keys, (uint) count, param->sort_length);
960
967
res_length= param->res_length;
961
968
offset= param->rec_length-res_length;
962
969
if ((ha_rows) count > param->max_rows)
963
count=(uint32_t) param->max_rows;
970
count=(uint) param->max_rows;
964
971
if (!(to= table_sort->record_pointers=
965
(unsigned char*) my_malloc(res_length*count, MYF(MY_WME))))
972
(uchar*) my_malloc(res_length*count, MYF(MY_WME))))
966
973
return(1); /* purecov: inspected */
967
for (unsigned char **end= sort_keys+count ; sort_keys != end ; sort_keys++)
974
for (uchar **end= sort_keys+count ; sort_keys != end ; sort_keys++)
969
976
memcpy(to, *sort_keys+offset, res_length);
976
983
/** Merge buffers to make < MERGEBUFF2 buffers. */
978
int merge_many_buff(SORTPARAM *param, unsigned char *sort_buffer,
979
BUFFPEK *buffpek, uint32_t *maxbuffer, IO_CACHE *t_file)
985
int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
986
BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file)
982
989
IO_CACHE t_file2,*from_file,*to_file,*temp;
983
990
BUFFPEK *lastbuff;
1029
1036
Read data to buffer.
1032
(uint32_t)-1 if something goes wrong
1039
(uint)-1 if something goes wrong
1035
uint32_t read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
1036
uint32_t rec_length)
1042
uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
1038
register uint32_t count;
1045
register uint count;
1041
if ((count=(uint32_t) cmin((ha_rows) buffpek->max_keys,buffpek->count)))
1048
if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
1043
if (pread(fromfile->file,(unsigned char*) buffpek->base, (length= rec_length*count),buffpek->file_pos) == 0)
1044
return((uint32_t) -1); /* purecov: inspected */
1050
if (pread(fromfile->file,(uchar*) buffpek->base, (length= rec_length*count),buffpek->file_pos) == 0)
1051
return((uint) -1); /* purecov: inspected */
1045
1052
buffpek->key=buffpek->base;
1046
1053
buffpek->file_pos+= length; /* New filepos */
1047
1054
buffpek->count-= count;
1062
1069
@param[in] key_length key length
1065
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint32_t key_length)
1072
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
1067
unsigned char *reuse_end= reuse->base + reuse->max_keys * key_length;
1068
for (uint32_t i= 0; i < queue->elements; ++i)
1074
uchar *reuse_end= reuse->base + reuse->max_keys * key_length;
1075
for (uint i= 0; i < queue->elements; ++i)
1070
1077
BUFFPEK *bp= (BUFFPEK *) queue_element(queue, i);
1071
1078
if (bp->base + bp->max_keys * key_length == reuse->base)
1105
1112
int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
1106
IO_CACHE *to_file, unsigned char *sort_buffer,
1113
IO_CACHE *to_file, uchar *sort_buffer,
1107
1114
BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb,
1111
uint32_t rec_length,res_length,offset;
1118
uint rec_length,res_length,offset;
1112
1119
size_t sort_length;
1114
1121
ha_rows max_rows,org_max_rows;
1115
1122
my_off_t to_start_filepos;
1116
unsigned char *strpos;
1117
1124
BUFFPEK *buffpek;
1119
1126
qsort2_cmp cmp;
1133
1140
res_length= param->res_length;
1134
1141
sort_length= param->sort_length;
1135
1142
offset= rec_length-res_length;
1136
maxcount= (uint32_t) (param->keys/((uint32_t) (Tb-Fb) +1));
1143
maxcount= (ulong) (param->keys/((uint) (Tb-Fb) +1));
1137
1144
to_start_filepos= my_b_tell(to_file);
1138
strpos= (unsigned char*) sort_buffer;
1145
strpos= (uchar*) sort_buffer;
1139
1146
org_max_rows=max_rows= param->max_rows;
1141
1148
/* The following will fire if there is not enough space in sort_buffer */
1151
1158
cmp= get_ptr_compare(sort_length);
1152
1159
first_cmp_arg= (void*) &sort_length;
1154
if (init_queue(&queue, (uint32_t) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0,
1161
if (init_queue(&queue, (uint) (Tb-Fb)+1, offsetof(BUFFPEK,key), 0,
1155
1162
(queue_compare) cmp, first_cmp_arg))
1156
1163
return(1); /* purecov: inspected */
1157
1164
for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
1159
1166
buffpek->base= strpos;
1160
1167
buffpek->max_keys= maxcount;
1161
strpos+= (uint32_t) (error= (int) read_to_buffer(from_file, buffpek,
1168
strpos+= (uint) (error= (int) read_to_buffer(from_file, buffpek,
1163
1170
if (error == -1)
1164
1171
goto err; /* purecov: inspected */
1165
1172
buffpek->max_keys= buffpek->mem_count; // If less data in buffers than expected
1166
queue_insert(&queue, (unsigned char*) buffpek);
1173
queue_insert(&queue, (uchar*) buffpek);
1169
1176
if (param->unique_buff)
1206
1213
if (cmp) // Remove duplicates
1208
1215
if (!(*cmp)(first_cmp_arg, &(param->unique_buff),
1209
(unsigned char**) &buffpek->key))
1216
(uchar**) &buffpek->key))
1210
1217
goto skip_duplicate;
1211
memcpy(param->unique_buff, buffpek->key, rec_length);
1218
memcpy(param->unique_buff, (uchar*) buffpek->key, rec_length);
1215
if (my_b_write(to_file,(unsigned char*) buffpek->key, rec_length))
1222
if (my_b_write(to_file,(uchar*) buffpek->key, rec_length))
1217
1224
error=1; goto err; /* purecov: inspected */
1222
if (my_b_write(to_file, (unsigned char*) buffpek->key+offset, res_length))
1229
if (my_b_write(to_file, (uchar*) buffpek->key+offset, res_length))
1224
1231
error=1; goto err; /* purecov: inspected */
1269
1276
if ((ha_rows) buffpek->mem_count > max_rows)
1270
1277
{ /* Don't write too many records */
1271
buffpek->mem_count= (uint32_t) max_rows;
1278
buffpek->mem_count= (uint) max_rows;
1272
1279
buffpek->count= 0; /* Don't read more */
1274
1281
max_rows-= buffpek->mem_count;
1277
if (my_b_write(to_file,(unsigned char*) buffpek->key,
1284
if (my_b_write(to_file,(uchar*) buffpek->key,
1278
1285
(rec_length*buffpek->mem_count)))
1280
1287
error= 1; goto err; /* purecov: inspected */
1310
1317
/* Do a merge to output-file (save only positions) */
1312
static int merge_index(SORTPARAM *param, unsigned char *sort_buffer,
1313
BUFFPEK *buffpek, uint32_t maxbuffer,
1319
static int merge_index(SORTPARAM *param, uchar *sort_buffer,
1320
BUFFPEK *buffpek, uint maxbuffer,
1314
1321
IO_CACHE *tempfile, IO_CACHE *outfile)
1316
1323
if (merge_buffers(param,tempfile,outfile,sort_buffer,buffpek,buffpek,
1569
1580
#define DBL_EXP_DIG (sizeof(double)*8-DBL_MANT_DIG)
1571
void change_double_for_sort(double nr,unsigned char *to)
1582
void change_double_for_sort(double nr,uchar *to)
1573
unsigned char *tmp=(unsigned char*) to;
1584
uchar *tmp=(uchar*) to;
1575
1586
{ /* Change to zero string */
1576
tmp[0]=(unsigned char) 128;
1577
memset(tmp+1, 0, sizeof(nr)-1);
1588
bzero((char*) tmp+1,sizeof(nr)-1);
1581
1592
#ifdef WORDS_BIGENDIAN
1582
memcpy(tmp,&nr,sizeof(nr));
1593
memcpy_fixed(tmp,&nr,sizeof(nr));
1585
unsigned char *ptr= (unsigned char*) &nr;
1596
uchar *ptr= (uchar*) &nr;
1586
1597
#if defined(__FLOAT_WORD_ORDER) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
1587
1598
tmp[0]= ptr[3]; tmp[1]=ptr[2]; tmp[2]= ptr[1]; tmp[3]=ptr[0];
1588
1599
tmp[4]= ptr[7]; tmp[5]=ptr[6]; tmp[6]= ptr[5]; tmp[7]=ptr[4];
1595
1606
if (tmp[0] & 128) /* Negative */
1596
1607
{ /* make complement */
1598
1609
for (i=0 ; i < sizeof(nr); i++)
1599
tmp[i]=tmp[i] ^ (unsigned char) 255;
1610
tmp[i]=tmp[i] ^ (uchar) 255;
1602
1613
{ /* Set high and move exponent one up */
1603
uint16_t exp_part=(((uint16_t) tmp[0] << 8) | (uint16_t) tmp[1] |
1605
exp_part+= (uint16_t) 1 << (16-1-DBL_EXP_DIG);
1606
tmp[0]= (unsigned char) (exp_part >> 8);
1607
tmp[1]= (unsigned char) exp_part;
1614
ushort exp_part=(((ushort) tmp[0] << 8) | (ushort) tmp[1] |
1616
exp_part+= (ushort) 1 << (16-1-DBL_EXP_DIG);
1617
tmp[0]= (uchar) (exp_part >> 8);
1618
tmp[1]= (uchar) exp_part;