~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2006 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
/*
17
  Creates a index for a database by reading keys, sorting them and outputing
18
  them in sorted order through SORT_INFO functions.
19
*/
20
76 by Brian Aker
Next pass on fulltext.
21
#include "myisamdef.h"
1 by brian
clean slate
22
#include <stddef.h>
960.2.7 by Padraig O'Sullivan
Removed all traces of QUEUE from the codebase. We are using
23
#include <queue>
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
24
#include <algorithm>
1 by brian
clean slate
25
26
/* static variables */
27
28
#undef MIN_SORT_MEMORY
29
#undef MYF_RW
30
#undef DISK_BUFFER_SIZE
31
32
#define MERGEBUFF 15
33
#define MERGEBUFF2 31
34
#define MIN_SORT_MEMORY (4096-MALLOC_OVERHEAD)
35
#define MYF_RW  MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL)
36
#define DISK_BUFFER_SIZE (IO_SIZE*16)
37
960.2.7 by Padraig O'Sullivan
Removed all traces of QUEUE from the codebase. We are using
38
using namespace std;
39
1 by brian
clean slate
40
41
/*
42
 Pointers of functions for store and read keys from temp file
43
*/
44
398.1.9 by Monty Taylor
Cleaned up stuff out of global.h.
45
extern void print_error(const char *fmt,...);
1 by brian
clean slate
46
47
/* Functions defined in this file */
48
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
49
extern "C" 
50
{
51
ha_rows  find_all_keys(MI_SORT_PARAM *info,uint32_t keys,
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
52
			      unsigned char **sort_keys,
53
			      DYNAMIC_ARRAY *buffpek,
54
			      size_t *maxbuffer,
55
			      IO_CACHE *tempfile,
56
			      IO_CACHE *tempfile_for_exceptions);
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
57
int  write_keys(MI_SORT_PARAM *info,unsigned char **sort_keys,
482 by Brian Aker
Remove uint.
58
                             uint32_t count, BUFFPEK *buffpek,IO_CACHE *tempfile);
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
59
int  write_key(MI_SORT_PARAM *info, unsigned char *key,
1 by brian
clean slate
60
			    IO_CACHE *tempfile);
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
61
int  write_index(MI_SORT_PARAM *info,unsigned char * *sort_keys,
482 by Brian Aker
Remove uint.
62
                              uint32_t count);
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
63
int  merge_many_buff(MI_SORT_PARAM *info,uint32_t keys,
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
64
			    unsigned char * *sort_keys,
65
			    BUFFPEK *buffpek,size_t *maxbuffer,
66
			    IO_CACHE *t_file);
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
67
uint32_t  read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek,
482 by Brian Aker
Remove uint.
68
                                  uint32_t sort_length);
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
69
int  merge_buffers(MI_SORT_PARAM *info,uint32_t keys,
1 by brian
clean slate
70
                                IO_CACHE *from_file, IO_CACHE *to_file,
481 by Brian Aker
Remove all of uchar.
71
                                unsigned char * *sort_keys, BUFFPEK *lastbuff,
1 by brian
clean slate
72
                                BUFFPEK *Fb, BUFFPEK *Tb);
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
73
int  merge_index(MI_SORT_PARAM *,uint,unsigned char **,BUFFPEK *, int,
1 by brian
clean slate
74
                              IO_CACHE *);
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
75
int  write_keys_varlen(MI_SORT_PARAM *info,unsigned char **sort_keys,
76
                       uint32_t count, BUFFPEK *buffpek,
77
                       IO_CACHE *tempfile);
78
uint32_t  read_to_buffer_varlen(IO_CACHE *fromfile,BUFFPEK *buffpek,
79
                                uint32_t sort_length);
80
int  write_merge_key(MI_SORT_PARAM *info, IO_CACHE *to_file,
81
                     unsigned char *key, uint32_t sort_length, uint32_t count);
82
int  write_merge_key_varlen(MI_SORT_PARAM *info,
83
                            IO_CACHE *to_file,
84
                            unsigned char* key, uint32_t sort_length,
85
                            uint32_t count);
86
}
87
inline int
481 by Brian Aker
Remove all of uchar.
88
my_var_write(MI_SORT_PARAM *info, IO_CACHE *to_file, unsigned char *bufs);
1 by brian
clean slate
89
90
/*
91
  Creates a index of sorted keys
92
93
  SYNOPSIS
94
    _create_index_by_sort()
95
    info		Sort parameters
96
    no_messages		Set to 1 if no output
97
    sortbuff_size	Size if sortbuffer to allocate
98
99
  RESULT
100
    0	ok
101
   <> 0 Error
102
*/
103
281 by Brian Aker
Converted myisam away from my_bool
104
int _create_index_by_sort(MI_SORT_PARAM *info,bool no_messages,
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
105
			  size_t sortbuff_size)
1 by brian
clean slate
106
{
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
107
  int error;
108
  size_t maxbuffer, skr;
482 by Brian Aker
Remove uint.
109
  uint32_t memavl,old_memavl,keys,sort_length;
1 by brian
clean slate
110
  DYNAMIC_ARRAY buffpek;
111
  ha_rows records;
481 by Brian Aker
Remove all of uchar.
112
  unsigned char **sort_keys;
1 by brian
clean slate
113
  IO_CACHE tempfile, tempfile_for_exceptions;
114
115
  if (info->keyinfo->flag & HA_VAR_LENGTH_KEY)
116
  {
117
    info->write_keys=write_keys_varlen;
118
    info->read_to_buffer=read_to_buffer_varlen;
119
    info->write_key= write_merge_key_varlen;
120
  }
121
  else
122
  {
123
    info->write_keys=write_keys;
124
    info->read_to_buffer=read_to_buffer;
125
    info->write_key=write_merge_key;
126
  }
127
128
  my_b_clear(&tempfile);
129
  my_b_clear(&tempfile_for_exceptions);
212.6.12 by Mats Kindahl
Removing redundant use of casts in MyISAM storage for memcmp(), memcpy(), memset(), and memmove().
130
  memset(&buffpek, 0, sizeof(buffpek));
481 by Brian Aker
Remove all of uchar.
131
  sort_keys= (unsigned char **) NULL; error= 1;
1 by brian
clean slate
132
  maxbuffer=1;
133
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
134
  memavl=max(sortbuff_size,(size_t)MIN_SORT_MEMORY);
1 by brian
clean slate
135
  records=	info->sort_info->max_records;
136
  sort_length=	info->key_length;
137
138
  while (memavl >= MIN_SORT_MEMORY)
139
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
140
    if ((records < UINT32_MAX) &&
141
       ((my_off_t) (records + 1) *
1 by brian
clean slate
142
        (sort_length + sizeof(char*)) <= (my_off_t) memavl))
143
      keys= (uint)records+1;
144
    else
145
      do
146
      {
147
	skr=maxbuffer;
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
148
	if (memavl < sizeof(BUFFPEK)* maxbuffer ||
149
	    (keys=(memavl-sizeof(BUFFPEK)* maxbuffer)/
1 by brian
clean slate
150
             (sort_length+sizeof(char*))) <= 1 ||
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
151
            keys < maxbuffer)
1 by brian
clean slate
152
	{
153
	  mi_check_print_error(info->sort_info->param,
154
			       "myisam_sort_buffer_size is too small");
155
	  goto err;
156
	}
157
      }
988.2.2 by Trond Norbye
size_t and uint64_t is not the same in 32 bit builds. Add explicit casting
158
      while ((maxbuffer= (size_t)(records/(keys-1)+1)) != skr);
1 by brian
clean slate
159
656.1.25 by Monty Taylor
Removed my_malloc stuff from storage/
160
    if ((sort_keys=(unsigned char **)malloc(keys*(sort_length+sizeof(char*)))))
1 by brian
clean slate
161
    {
162
      if (my_init_dynamic_array(&buffpek, sizeof(BUFFPEK), maxbuffer,
163
			     maxbuffer/2))
164
      {
481 by Brian Aker
Remove all of uchar.
165
	free((unsigned char*) sort_keys);
1 by brian
clean slate
166
        sort_keys= 0;
167
      }
168
      else
169
	break;
170
    }
171
    old_memavl=memavl;
172
    if ((memavl=memavl/4*3) < MIN_SORT_MEMORY && old_memavl > MIN_SORT_MEMORY)
173
      memavl=MIN_SORT_MEMORY;
174
  }
175
  if (memavl < MIN_SORT_MEMORY)
176
  {
177
    mi_check_print_error(info->sort_info->param,"MyISAM sort buffer too small"); /* purecov: tested */
178
    goto err; /* purecov: tested */
179
  }
180
  (*info->lock_in_memory)(info->sort_info->param);/* Everything is allocated */
181
182
  if (!no_messages)
183
    printf("  - Searching for keys, allocating buffer for %d keys\n",keys);
184
185
  if ((records=find_all_keys(info,keys,sort_keys,&buffpek,&maxbuffer,
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
186
			     &tempfile,&tempfile_for_exceptions))
1 by brian
clean slate
187
      == HA_POS_ERROR)
188
    goto err; /* purecov: tested */
189
  if (maxbuffer == 0)
190
  {
191
    if (!no_messages)
305 by Brian Aker
Another pass of ulong removal.
192
      printf("  - Dumping %u keys\n", (uint32_t) records);
1 by brian
clean slate
193
    if (write_index(info,sort_keys, (uint) records))
194
      goto err; /* purecov: inspected */
195
  }
196
  else
197
  {
198
    keys=(keys*(sort_length+sizeof(char*)))/sort_length;
199
    if (maxbuffer >= MERGEBUFF2)
200
    {
201
      if (!no_messages)
305 by Brian Aker
Another pass of ulong removal.
202
	printf("  - Merging %u keys\n", (uint32_t) records); /* purecov: tested */
1 by brian
clean slate
203
      if (merge_many_buff(info,keys,sort_keys,
204
                  dynamic_element(&buffpek,0,BUFFPEK *),&maxbuffer,&tempfile))
205
	goto err;				/* purecov: inspected */
206
    }
207
    if (flush_io_cache(&tempfile) ||
208
	reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
209
      goto err;					/* purecov: inspected */
210
    if (!no_messages)
211
      printf("  - Last merge and dumping keys\n"); /* purecov: tested */
212
    if (merge_index(info,keys,sort_keys,dynamic_element(&buffpek,0,BUFFPEK *),
213
                    maxbuffer,&tempfile))
214
      goto err;					/* purecov: inspected */
215
  }
216
76.1.1 by Brian Aker
Final removal of fulltext core from myisam.
217
  if (flush_pending_blocks(info))
1 by brian
clean slate
218
    goto err;
219
220
  if (my_b_inited(&tempfile_for_exceptions))
221
  {
222
    MI_INFO *idx=info->sort_info->info;
482 by Brian Aker
Remove uint.
223
    uint32_t     keyno=info->key;
224
    uint32_t     key_length, ref_length=idx->s->rec_reflength;
1 by brian
clean slate
225
226
    if (!no_messages)
227
      printf("  - Adding exceptions\n"); /* purecov: tested */
228
    if (flush_io_cache(&tempfile_for_exceptions) ||
229
	reinit_io_cache(&tempfile_for_exceptions,READ_CACHE,0L,0,0))
230
      goto err;
231
481 by Brian Aker
Remove all of uchar.
232
    while (!my_b_read(&tempfile_for_exceptions,(unsigned char*)&key_length,
1 by brian
clean slate
233
		      sizeof(key_length))
481 by Brian Aker
Remove all of uchar.
234
        && !my_b_read(&tempfile_for_exceptions,(unsigned char*)sort_keys,
1 by brian
clean slate
235
		      (uint) key_length))
236
    {
481 by Brian Aker
Remove all of uchar.
237
	if (_mi_ck_write(idx,keyno,(unsigned char*) sort_keys,key_length-ref_length))
1 by brian
clean slate
238
	  goto err;
239
    }
240
  }
241
242
  error =0;
243
244
err:
245
  if (sort_keys)
481 by Brian Aker
Remove all of uchar.
246
    free((unsigned char*) sort_keys);
1 by brian
clean slate
247
  delete_dynamic(&buffpek);
248
  close_cached_file(&tempfile);
249
  close_cached_file(&tempfile_for_exceptions);
250
51.1.119 by Jay Pipes
DBUG symbol removal
251
  return(error ? -1 : 0);
1 by brian
clean slate
252
} /* _create_index_by_sort */
253
254
255
/* Search after all keys and place them in a temp. file */
256
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
257
ha_rows  find_all_keys(MI_SORT_PARAM *info, uint32_t keys,
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
258
			      unsigned char **sort_keys,
259
			      DYNAMIC_ARRAY *buffpek,
260
			      size_t *maxbuffer, IO_CACHE *tempfile,
261
			      IO_CACHE *tempfile_for_exceptions)
1 by brian
clean slate
262
{
263
  int error;
482 by Brian Aker
Remove uint.
264
  uint32_t idx;
1 by brian
clean slate
265
266
  idx=error=0;
481 by Brian Aker
Remove all of uchar.
267
  sort_keys[0]=(unsigned char*) (sort_keys+keys);
1 by brian
clean slate
268
269
  while (!(error=(*info->key_read)(info,sort_keys[idx])))
270
  {
271
    if (info->real_key_length > info->key_length)
272
    {
273
      if (write_key(info,sort_keys[idx],tempfile_for_exceptions))
51.1.119 by Jay Pipes
DBUG symbol removal
274
        return(HA_POS_ERROR);		/* purecov: inspected */
1 by brian
clean slate
275
      continue;
276
    }
277
278
    if (++idx == keys)
279
    {
280
      if (info->write_keys(info,sort_keys,idx-1,(BUFFPEK *)alloc_dynamic(buffpek),
281
		     tempfile))
51.1.119 by Jay Pipes
DBUG symbol removal
282
      return(HA_POS_ERROR);		/* purecov: inspected */
1 by brian
clean slate
283
481 by Brian Aker
Remove all of uchar.
284
      sort_keys[0]=(unsigned char*) (sort_keys+keys);
1 by brian
clean slate
285
      memcpy(sort_keys[0],sort_keys[idx-1],(size_t) info->key_length);
286
      idx=1;
287
    }
288
    sort_keys[idx]=sort_keys[idx-1]+info->key_length;
289
  }
290
  if (error > 0)
51.1.119 by Jay Pipes
DBUG symbol removal
291
    return(HA_POS_ERROR);		/* Aborted by get_key */ /* purecov: inspected */
1 by brian
clean slate
292
  if (buffpek->elements)
293
  {
294
    if (info->write_keys(info,sort_keys,idx,(BUFFPEK *)alloc_dynamic(buffpek),
295
		   tempfile))
51.1.119 by Jay Pipes
DBUG symbol removal
296
      return(HA_POS_ERROR);		/* purecov: inspected */
1 by brian
clean slate
297
    *maxbuffer=buffpek->elements-1;
298
  }
299
  else
300
    *maxbuffer=0;
301
51.1.119 by Jay Pipes
DBUG symbol removal
302
  return((*maxbuffer)*(keys-1)+idx);
1 by brian
clean slate
303
} /* find_all_keys */
304
305
306
/* Search after all keys and place them in a temp. file */
307
308
pthread_handler_t thr_find_all_keys(void *arg)
309
{
310
  MI_SORT_PARAM *sort_param= (MI_SORT_PARAM*) arg;
311
  int error;
482 by Brian Aker
Remove uint.
312
  uint32_t memavl,old_memavl,keys,sort_length;
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
313
  uint32_t idx;
314
  size_t maxbuffer;
481 by Brian Aker
Remove all of uchar.
315
  unsigned char **sort_keys=0;
1 by brian
clean slate
316
317
  error=1;
318
319
  if (my_thread_init())
320
    goto err;
321
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
322
  {
1 by brian
clean slate
323
    if (sort_param->sort_info->got_error)
324
      goto err;
325
326
    if (sort_param->keyinfo->flag & HA_VAR_LENGTH_KEY)
327
    {
328
      sort_param->write_keys=     write_keys_varlen;
329
      sort_param->read_to_buffer= read_to_buffer_varlen;
330
      sort_param->write_key=      write_merge_key_varlen;
331
    }
332
    else
333
    {
334
      sort_param->write_keys=     write_keys;
335
      sort_param->read_to_buffer= read_to_buffer;
336
      sort_param->write_key=      write_merge_key;
337
    }
338
339
    my_b_clear(&sort_param->tempfile);
340
    my_b_clear(&sort_param->tempfile_for_exceptions);
212.6.12 by Mats Kindahl
Removing redundant use of casts in MyISAM storage for memcmp(), memcpy(), memset(), and memmove().
341
    memset(&sort_param->buffpek, 0, sizeof(sort_param->buffpek));
342
    memset(&sort_param->unique, 0,  sizeof(sort_param->unique));
481 by Brian Aker
Remove all of uchar.
343
    sort_keys= (unsigned char **) NULL;
1 by brian
clean slate
344
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
345
    memavl=       max(sort_param->sortbuff_size, (uint32_t)MIN_SORT_MEMORY);
1 by brian
clean slate
346
    idx=          (uint)sort_param->sort_info->max_records;
347
    sort_length=  sort_param->key_length;
348
    maxbuffer=    1;
349
350
    while (memavl >= MIN_SORT_MEMORY)
351
    {
352
      if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <=
353
          (my_off_t) memavl)
354
        keys= idx+1;
355
      else
356
      {
482 by Brian Aker
Remove uint.
357
        uint32_t skr;
1 by brian
clean slate
358
        do
359
        {
360
          skr= maxbuffer;
361
          if (memavl < sizeof(BUFFPEK)*maxbuffer ||
362
              (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
363
               (sort_length+sizeof(char*))) <= 1 ||
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
364
              keys < maxbuffer)
1 by brian
clean slate
365
          {
366
            mi_check_print_error(sort_param->sort_info->param,
367
                                 "myisam_sort_buffer_size is too small");
368
            goto err;
369
          }
370
        }
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
371
        while ((maxbuffer= (idx/(keys-1)+1)) != skr);
1 by brian
clean slate
372
      }
481 by Brian Aker
Remove all of uchar.
373
      if ((sort_keys= (unsigned char**)
656.1.25 by Monty Taylor
Removed my_malloc stuff from storage/
374
           malloc(keys*(sort_length+sizeof(char*)))))
1 by brian
clean slate
375
      {
376
        if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK),
377
                                  maxbuffer, maxbuffer/2))
378
        {
481 by Brian Aker
Remove all of uchar.
379
          free((unsigned char*) sort_keys);
380
          sort_keys= (unsigned char **) NULL; /* for err: label */
1 by brian
clean slate
381
        }
382
        else
383
          break;
384
      }
385
      old_memavl= memavl;
386
      if ((memavl= memavl/4*3) < MIN_SORT_MEMORY &&
387
          old_memavl > MIN_SORT_MEMORY)
388
        memavl= MIN_SORT_MEMORY;
389
    }
390
    if (memavl < MIN_SORT_MEMORY)
391
    {
392
      mi_check_print_error(sort_param->sort_info->param,
393
                           "MyISAM sort buffer too small");
394
      goto err; /* purecov: tested */
395
    }
396
397
    if (sort_param->sort_info->param->testflag & T_VERBOSE)
398
      printf("Key %d - Allocating buffer for %d keys\n",
399
             sort_param->key + 1, keys);
400
    sort_param->sort_keys= sort_keys;
401
402
    idx= error= 0;
481 by Brian Aker
Remove all of uchar.
403
    sort_keys[0]= (unsigned char*) (sort_keys+keys);
1 by brian
clean slate
404
405
    while (!(error= sort_param->sort_info->got_error) &&
406
           !(error= (*sort_param->key_read)(sort_param, sort_keys[idx])))
407
    {
408
      if (sort_param->real_key_length > sort_param->key_length)
409
      {
410
        if (write_key(sort_param, sort_keys[idx],
411
                      &sort_param->tempfile_for_exceptions))
412
          goto err;
413
        continue;
414
      }
415
416
      if (++idx == keys)
417
      {
418
        if (sort_param->write_keys(sort_param, sort_keys, idx - 1,
419
                                   (BUFFPEK*) alloc_dynamic(&sort_param->buffpek),
420
                                   &sort_param->tempfile))
421
          goto err;
481 by Brian Aker
Remove all of uchar.
422
        sort_keys[0]= (unsigned char*) (sort_keys+keys);
1 by brian
clean slate
423
        memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length);
424
        idx= 1;
425
      }
426
      sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length;
427
    }
428
    if (error > 0)
429
      goto err;
430
    if (sort_param->buffpek.elements)
431
    {
432
      if (sort_param->write_keys(sort_param, sort_keys, idx,
433
                                 (BUFFPEK*) alloc_dynamic(&sort_param->buffpek),
434
                                 &sort_param->tempfile))
435
        goto err;
436
      sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx;
437
    }
438
    else
439
      sort_param->keys= idx;
440
441
    sort_param->sort_keys_length= keys;
442
    goto ok;
443
444
err:
445
    sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */
446
    if (sort_keys)
481 by Brian Aker
Remove all of uchar.
447
      free((unsigned char*) sort_keys);
1 by brian
clean slate
448
    sort_param->sort_keys= 0;
449
    delete_dynamic(& sort_param->buffpek);
450
    close_cached_file(&sort_param->tempfile);
451
    close_cached_file(&sort_param->tempfile_for_exceptions);
452
453
ok:
454
    free_root(&sort_param->wordroot, MYF(0));
455
    /*
456
      Detach from the share if the writer is involved. Avoid others to
457
      be blocked. This includes a flush of the write buffer. This will
458
      also indicate EOF to the readers.
459
    */
460
    if (sort_param->sort_info->info->rec_cache.share)
461
      remove_io_thread(&sort_param->sort_info->info->rec_cache);
462
463
    /* Readers detach from the share if any. Avoid others to be blocked. */
464
    if (sort_param->read_cache.share)
465
      remove_io_thread(&sort_param->read_cache);
466
467
    pthread_mutex_lock(&sort_param->sort_info->mutex);
468
    if (!--sort_param->sort_info->threads_running)
469
      pthread_cond_signal(&sort_param->sort_info->cond);
470
    pthread_mutex_unlock(&sort_param->sort_info->mutex);
471
  }
472
  my_thread_end();
473
  return NULL;
474
}
475
476
477
int thr_write_keys(MI_SORT_PARAM *sort_param)
478
{
479
  SORT_INFO *sort_info= sort_param->sort_info;
480
  MI_CHECK *param= sort_info->param;
305 by Brian Aker
Another pass of ulong removal.
481
  uint32_t length= 0, keys;
482
  ulong *rec_per_key_part= param->rec_per_key_part;
1 by brian
clean slate
483
  int got_error=sort_info->got_error;
482 by Brian Aker
Remove uint.
484
  uint32_t i;
1 by brian
clean slate
485
  MI_INFO *info=sort_info->info;
486
  MYISAM_SHARE *share=info->s;
487
  MI_SORT_PARAM *sinfo;
481 by Brian Aker
Remove all of uchar.
488
  unsigned char *mergebuf=0;
1 by brian
clean slate
489
490
  for (i= 0, sinfo= sort_param ;
491
       i < sort_info->total_keys ;
492
       i++, rec_per_key_part+=sinfo->keyinfo->keysegs, sinfo++)
493
  {
494
    if (!sinfo->sort_keys)
495
    {
496
      got_error=1;
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
497
      void * rec_buff_ptr= mi_get_rec_buff_ptr(info, sinfo->rec_buff);
498
      if (rec_buff_ptr != NULL)
499
        free(rec_buff_ptr);
1 by brian
clean slate
500
      continue;
501
    }
502
    if (!got_error)
503
    {
504
      mi_set_key_active(share->state.key_map, sinfo->key);
505
      if (!sinfo->buffpek.elements)
506
      {
507
        if (param->testflag & T_VERBOSE)
508
        {
509
          printf("Key %d  - Dumping %u keys\n",sinfo->key+1, sinfo->keys);
510
          fflush(stdout);
511
        }
76.1.1 by Brian Aker
Final removal of fulltext core from myisam.
512
        if (write_index(sinfo, sinfo->sort_keys, sinfo->keys) || flush_pending_blocks(sinfo))
1 by brian
clean slate
513
          got_error=1;
514
      }
515
      if (!got_error && param->testflag & T_STATISTICS)
516
        update_key_parts(sinfo->keyinfo, rec_per_key_part, sinfo->unique,
517
                         param->stats_method == MI_STATS_METHOD_IGNORE_NULLS?
518
                         sinfo->notnull: NULL,
151 by Brian Aker
Ulonglong to uint64_t
519
                         (uint64_t) info->state->records);
1 by brian
clean slate
520
    }
481 by Brian Aker
Remove all of uchar.
521
    free((unsigned char*) sinfo->sort_keys);
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
522
    void * rec_buff_ptr= mi_get_rec_buff_ptr(info, sinfo->rec_buff);
523
    if (rec_buff_ptr != NULL)
524
      free(rec_buff_ptr);
1 by brian
clean slate
525
    sinfo->sort_keys=0;
526
  }
527
528
  for (i= 0, sinfo= sort_param ;
529
       i < sort_info->total_keys ;
530
       i++,
531
	 delete_dynamic(&sinfo->buffpek),
532
	 close_cached_file(&sinfo->tempfile),
533
	 close_cached_file(&sinfo->tempfile_for_exceptions),
534
	 sinfo++)
535
  {
536
    if (got_error)
537
      continue;
538
    if (sinfo->keyinfo->flag & HA_VAR_LENGTH_KEY)
539
    {
540
      sinfo->write_keys=write_keys_varlen;
541
      sinfo->read_to_buffer=read_to_buffer_varlen;
542
      sinfo->write_key=write_merge_key_varlen;
543
    }
544
    else
545
    {
546
      sinfo->write_keys=write_keys;
547
      sinfo->read_to_buffer=read_to_buffer;
548
      sinfo->write_key=write_merge_key;
549
    }
550
    if (sinfo->buffpek.elements)
551
    {
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
552
      size_t maxbuffer=sinfo->buffpek.elements-1;
1 by brian
clean slate
553
      if (!mergebuf)
554
      {
555
        length=param->sort_buffer_length;
556
        while (length >= MIN_SORT_MEMORY)
557
        {
960.2.2 by Monty Taylor
Moved MyISAM files to C++ so we can continue to consolidate code.
558
          if ((mergebuf= (unsigned char *)malloc(length)))
1 by brian
clean slate
559
              break;
560
          length=length*3/4;
561
        }
562
        if (!mergebuf)
563
        {
564
          got_error=1;
565
          continue;
566
        }
567
      }
568
      keys=length/sinfo->key_length;
569
      if (maxbuffer >= MERGEBUFF2)
570
      {
571
        if (param->testflag & T_VERBOSE)
572
          printf("Key %d  - Merging %u keys\n",sinfo->key+1, sinfo->keys);
481 by Brian Aker
Remove all of uchar.
573
        if (merge_many_buff(sinfo, keys, (unsigned char **)mergebuf,
1 by brian
clean slate
574
			    dynamic_element(&sinfo->buffpek, 0, BUFFPEK *),
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
575
			    &maxbuffer, &sinfo->tempfile))
1 by brian
clean slate
576
        {
577
          got_error=1;
578
          continue;
579
        }
580
      }
581
      if (flush_io_cache(&sinfo->tempfile) ||
582
          reinit_io_cache(&sinfo->tempfile,READ_CACHE,0L,0,0))
583
      {
584
        got_error=1;
585
        continue;
586
      }
587
      if (param->testflag & T_VERBOSE)
588
        printf("Key %d  - Last merge and dumping keys\n", sinfo->key+1);
481 by Brian Aker
Remove all of uchar.
589
      if (merge_index(sinfo, keys, (unsigned char **)mergebuf,
1 by brian
clean slate
590
                      dynamic_element(&sinfo->buffpek,0,BUFFPEK *),
591
                      maxbuffer,&sinfo->tempfile) ||
592
	  flush_pending_blocks(sinfo))
593
      {
594
        got_error=1;
595
        continue;
596
      }
597
    }
598
    if (my_b_inited(&sinfo->tempfile_for_exceptions))
599
    {
482 by Brian Aker
Remove uint.
600
      uint32_t key_length;
1 by brian
clean slate
601
602
      if (param->testflag & T_VERBOSE)
603
        printf("Key %d  - Dumping 'long' keys\n", sinfo->key+1);
604
605
      if (flush_io_cache(&sinfo->tempfile_for_exceptions) ||
606
          reinit_io_cache(&sinfo->tempfile_for_exceptions,READ_CACHE,0L,0,0))
607
      {
608
        got_error=1;
609
        continue;
610
      }
611
612
      while (!got_error &&
481 by Brian Aker
Remove all of uchar.
613
	     !my_b_read(&sinfo->tempfile_for_exceptions,(unsigned char*)&key_length,
1 by brian
clean slate
614
			sizeof(key_length)))
615
      {
481 by Brian Aker
Remove all of uchar.
616
        unsigned char ft_buf[10];
1 by brian
clean slate
617
        if (key_length > sizeof(ft_buf) ||
481 by Brian Aker
Remove all of uchar.
618
            my_b_read(&sinfo->tempfile_for_exceptions, (unsigned char*)ft_buf,
1 by brian
clean slate
619
                      (uint)key_length) ||
481 by Brian Aker
Remove all of uchar.
620
            _mi_ck_write(info, sinfo->key, (unsigned char*)ft_buf,
1 by brian
clean slate
621
                         key_length - info->s->rec_reflength))
622
          got_error=1;
623
      }
624
    }
625
  }
481 by Brian Aker
Remove all of uchar.
626
  free((unsigned char*) mergebuf);
51.1.119 by Jay Pipes
DBUG symbol removal
627
  return(got_error);
1 by brian
clean slate
628
}
629
630
        /* Write all keys in memory to file for later merge */
631
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
632
int  write_keys(MI_SORT_PARAM *info, register unsigned char **sort_keys,
482 by Brian Aker
Remove uint.
633
                             uint32_t count, BUFFPEK *buffpek, IO_CACHE *tempfile)
1 by brian
clean slate
634
{
481 by Brian Aker
Remove all of uchar.
635
  unsigned char **end;
482 by Brian Aker
Remove uint.
636
  uint32_t sort_length=info->key_length;
1 by brian
clean slate
637
481 by Brian Aker
Remove all of uchar.
638
  my_qsort2((unsigned char*) sort_keys,count,sizeof(unsigned char*),(qsort2_cmp) info->key_cmp,
1 by brian
clean slate
639
            info);
640
  if (!my_b_inited(tempfile) &&
680 by Brian Aker
Remove locks around temp tables for searching tmp directory path.
641
      open_cached_file(tempfile, P_tmpdir, "ST",
1 by brian
clean slate
642
                       DISK_BUFFER_SIZE, info->sort_info->param->myf_rw))
51.1.119 by Jay Pipes
DBUG symbol removal
643
    return(1); /* purecov: inspected */
1 by brian
clean slate
644
645
  buffpek->file_pos=my_b_tell(tempfile);
646
  buffpek->count=count;
647
648
  for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
649
  {
481 by Brian Aker
Remove all of uchar.
650
    if (my_b_write(tempfile,(unsigned char*) *sort_keys,(uint) sort_length))
51.1.119 by Jay Pipes
DBUG symbol removal
651
      return(1); /* purecov: inspected */
1 by brian
clean slate
652
  }
51.1.119 by Jay Pipes
DBUG symbol removal
653
  return(0);
1 by brian
clean slate
654
} /* write_keys */
655
656
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
657
inline int
481 by Brian Aker
Remove all of uchar.
658
my_var_write(MI_SORT_PARAM *info, IO_CACHE *to_file, unsigned char *bufs)
1 by brian
clean slate
659
{
660
  int err;
481 by Brian Aker
Remove all of uchar.
661
  uint16_t len = _mi_keylength(info->keyinfo, (unsigned char*) bufs);
1 by brian
clean slate
662
663
  /* The following is safe as this is a local file */
481 by Brian Aker
Remove all of uchar.
664
  if ((err= my_b_write(to_file, (unsigned char*)&len, sizeof(len))))
1 by brian
clean slate
665
    return (err);
666
  if ((err= my_b_write(to_file,bufs, (uint) len)))
667
    return (err);
668
  return (0);
669
}
670
671
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
672
int  write_keys_varlen(MI_SORT_PARAM *info,
481 by Brian Aker
Remove all of uchar.
673
				    register unsigned char **sort_keys,
482 by Brian Aker
Remove uint.
674
                                    uint32_t count, BUFFPEK *buffpek,
1 by brian
clean slate
675
				    IO_CACHE *tempfile)
676
{
481 by Brian Aker
Remove all of uchar.
677
  unsigned char **end;
1 by brian
clean slate
678
  int err;
679
481 by Brian Aker
Remove all of uchar.
680
  my_qsort2((unsigned char*) sort_keys,count,sizeof(unsigned char*),(qsort2_cmp) info->key_cmp,
1 by brian
clean slate
681
            info);
682
  if (!my_b_inited(tempfile) &&
680 by Brian Aker
Remove locks around temp tables for searching tmp directory path.
683
      open_cached_file(tempfile, P_tmpdir, "ST",
1 by brian
clean slate
684
                       DISK_BUFFER_SIZE, info->sort_info->param->myf_rw))
51.1.119 by Jay Pipes
DBUG symbol removal
685
    return(1); /* purecov: inspected */
1 by brian
clean slate
686
687
  buffpek->file_pos=my_b_tell(tempfile);
688
  buffpek->count=count;
689
  for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
690
  {
481 by Brian Aker
Remove all of uchar.
691
    if ((err= my_var_write(info,tempfile, (unsigned char*) *sort_keys)))
51.1.119 by Jay Pipes
DBUG symbol removal
692
      return(err);
1 by brian
clean slate
693
  }
51.1.119 by Jay Pipes
DBUG symbol removal
694
  return(0);
1 by brian
clean slate
695
} /* write_keys_varlen */
696
697
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
698
int  write_key(MI_SORT_PARAM *info, unsigned char *key,
1 by brian
clean slate
699
			    IO_CACHE *tempfile)
700
{
482 by Brian Aker
Remove uint.
701
  uint32_t key_length=info->real_key_length;
1 by brian
clean slate
702
703
  if (!my_b_inited(tempfile) &&
680 by Brian Aker
Remove locks around temp tables for searching tmp directory path.
704
      open_cached_file(tempfile, P_tmpdir, "ST",
1 by brian
clean slate
705
                       DISK_BUFFER_SIZE, info->sort_info->param->myf_rw))
51.1.119 by Jay Pipes
DBUG symbol removal
706
    return(1);
1 by brian
clean slate
707
481 by Brian Aker
Remove all of uchar.
708
  if (my_b_write(tempfile,(unsigned char*)&key_length,sizeof(key_length)) ||
709
      my_b_write(tempfile,(unsigned char*)key,(uint) key_length))
51.1.119 by Jay Pipes
DBUG symbol removal
710
    return(1);
711
  return(0);
1 by brian
clean slate
712
} /* write_key */
713
714
715
/* Write index */
716
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
717
int  write_index(MI_SORT_PARAM *info, register unsigned char **sort_keys,
482 by Brian Aker
Remove uint.
718
                              register uint32_t count)
1 by brian
clean slate
719
{
481 by Brian Aker
Remove all of uchar.
720
  my_qsort2((unsigned char*) sort_keys,(size_t) count,sizeof(unsigned char*),
1 by brian
clean slate
721
           (qsort2_cmp) info->key_cmp,info);
722
  while (count--)
723
  {
724
    if ((*info->key_write)(info,*sort_keys++))
51.1.119 by Jay Pipes
DBUG symbol removal
725
      return(-1); /* purecov: inspected */
1 by brian
clean slate
726
  }
51.1.119 by Jay Pipes
DBUG symbol removal
727
  return(0);
1 by brian
clean slate
728
} /* write_index */
729
730
731
        /* Merge buffers to make < MERGEBUFF2 buffers */
732
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
733
int  merge_many_buff(MI_SORT_PARAM *info, uint32_t keys,
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
734
			    unsigned char **sort_keys, BUFFPEK *buffpek,
735
			    size_t *maxbuffer, IO_CACHE *t_file)
1 by brian
clean slate
736
{
629.4.1 by Monty Taylor
First step in support size_t sys_var stuff.
737
  uint32_t i;
1 by brian
clean slate
738
  IO_CACHE t_file2, *from_file, *to_file, *temp;
739
  BUFFPEK *lastbuff;
740
741
  if (*maxbuffer < MERGEBUFF2)
51.1.119 by Jay Pipes
DBUG symbol removal
742
    return(0);                             /* purecov: inspected */
1 by brian
clean slate
743
  if (flush_io_cache(t_file) ||
680 by Brian Aker
Remove locks around temp tables for searching tmp directory path.
744
      open_cached_file(&t_file2, P_tmpdir, "ST",
1 by brian
clean slate
745
                       DISK_BUFFER_SIZE, info->sort_info->param->myf_rw))
51.1.119 by Jay Pipes
DBUG symbol removal
746
    return(1);                             /* purecov: inspected */
1 by brian
clean slate
747
748
  from_file= t_file ; to_file= &t_file2;
749
  while (*maxbuffer >= MERGEBUFF2)
750
  {
751
    reinit_io_cache(from_file,READ_CACHE,0L,0,0);
752
    reinit_io_cache(to_file,WRITE_CACHE,0L,0,0);
753
    lastbuff=buffpek;
754
    for (i=0 ; i <= *maxbuffer-MERGEBUFF*3/2 ; i+=MERGEBUFF)
755
    {
756
      if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
757
                        buffpek+i,buffpek+i+MERGEBUFF-1))
758
        goto cleanup;
759
    }
760
    if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
761
                      buffpek+i,buffpek+ *maxbuffer))
762
      break; /* purecov: inspected */
763
    if (flush_io_cache(to_file))
764
      break;                                    /* purecov: inspected */
765
    temp=from_file; from_file=to_file; to_file=temp;
766
    *maxbuffer= (int) (lastbuff-buffpek)-1;
767
  }
768
cleanup:
769
  close_cached_file(to_file);                   /* This holds old result */
770
  if (to_file == t_file)
771
    *t_file=t_file2;                            /* Copy result file */
772
51.1.119 by Jay Pipes
DBUG symbol removal
773
  return(*maxbuffer >= MERGEBUFF2);        /* Return 1 if interrupted */
1 by brian
clean slate
774
} /* merge_many_buff */
775
776
777
/*
778
   Read data to buffer
779
780
  SYNOPSIS
781
    read_to_buffer()
782
    fromfile		File to read from
783
    buffpek		Where to read from
784
    sort_length		max length to read
785
  RESULT
786
    > 0	Ammount of bytes read
787
    -1	Error
788
*/
789
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
790
uint32_t  read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
482 by Brian Aker
Remove uint.
791
                                  uint32_t sort_length)
1 by brian
clean slate
792
{
482 by Brian Aker
Remove uint.
793
  register uint32_t count;
794
  uint32_t length;
1 by brian
clean slate
795
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
796
  if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
1 by brian
clean slate
797
  {
481 by Brian Aker
Remove all of uchar.
798
    if (my_pread(fromfile->file,(unsigned char*) buffpek->base,
1 by brian
clean slate
799
                 (length= sort_length*count),buffpek->file_pos,MYF_RW))
800
      return((uint) -1);                        /* purecov: inspected */
801
    buffpek->key=buffpek->base;
802
    buffpek->file_pos+= length;                 /* New filepos */
803
    buffpek->count-=    count;
804
    buffpek->mem_count= count;
805
  }
806
  return (count*sort_length);
807
} /* read_to_buffer */
808
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
809
uint32_t  read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek,
482 by Brian Aker
Remove uint.
810
                                         uint32_t sort_length)
1 by brian
clean slate
811
{
482 by Brian Aker
Remove uint.
812
  register uint32_t count;
206 by Brian Aker
Removed final uint dead types.
813
  uint16_t length_of_key = 0;
482 by Brian Aker
Remove uint.
814
  uint32_t idx;
481 by Brian Aker
Remove all of uchar.
815
  unsigned char *buffp;
1 by brian
clean slate
816
1067.4.8 by Nathan Williams
Converted all usages of cmin/cmax in plugin directory to std::min/max.
817
  if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
1 by brian
clean slate
818
  {
819
    buffp = buffpek->base;
820
821
    for (idx=1;idx<=count;idx++)
822
    {
481 by Brian Aker
Remove all of uchar.
823
      if (my_pread(fromfile->file,(unsigned char*)&length_of_key,sizeof(length_of_key),
1 by brian
clean slate
824
                   buffpek->file_pos,MYF_RW))
825
        return((uint) -1);
826
      buffpek->file_pos+=sizeof(length_of_key);
481 by Brian Aker
Remove all of uchar.
827
      if (my_pread(fromfile->file,(unsigned char*) buffp,length_of_key,
1 by brian
clean slate
828
                   buffpek->file_pos,MYF_RW))
829
        return((uint) -1);
830
      buffpek->file_pos+=length_of_key;
831
      buffp = buffp + sort_length;
832
    }
833
    buffpek->key=buffpek->base;
834
    buffpek->count-=    count;
835
    buffpek->mem_count= count;
836
  }
837
  return (count*sort_length);
838
} /* read_to_buffer_varlen */
839
840
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
841
int  write_merge_key_varlen(MI_SORT_PARAM *info,
481 by Brian Aker
Remove all of uchar.
842
					 IO_CACHE *to_file, unsigned char* key,
482 by Brian Aker
Remove uint.
843
                                         uint32_t sort_length, uint32_t count)
1 by brian
clean slate
844
{
482 by Brian Aker
Remove uint.
845
  uint32_t idx;
481 by Brian Aker
Remove all of uchar.
846
  unsigned char *bufs = key;
1 by brian
clean slate
847
848
  for (idx=1;idx<=count;idx++)
849
  {
850
    int err;
851
    if ((err= my_var_write(info, to_file, bufs)))
852
      return (err);
853
    bufs=bufs+sort_length;
854
  }
855
  return(0);
856
}
857
858
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
859
int  write_merge_key(MI_SORT_PARAM *info,
481 by Brian Aker
Remove all of uchar.
860
				  IO_CACHE *to_file, unsigned char *key,
482 by Brian Aker
Remove uint.
861
				  uint32_t sort_length, uint32_t count)
1 by brian
clean slate
862
{
779.3.1 by Monty Taylor
More cleanup.
863
  (void)info;
1 by brian
clean slate
864
  return my_b_write(to_file, key, (size_t) sort_length*count);
865
}
866
960.2.16 by Padraig O'Sullivan
Adding comments to the function object that is used as the comparison
867
/*
868
 * Function object to be used as the comparison function
869
 * for the priority queue in the merge_buffers method.
870
 */
960.2.8 by Padraig O'Sullivan
Adding a function object to be used as the comparison parameter for the
871
class compare_functor
872
{
960.2.12 by Padraig O'Sullivan
Making the class members of my function object have the correct type.
873
  qsort2_cmp key_compare;
960.2.8 by Padraig O'Sullivan
Adding a function object to be used as the comparison parameter for the
874
  void *key_compare_arg;
875
  public:
960.2.12 by Padraig O'Sullivan
Making the class members of my function object have the correct type.
876
  compare_functor(qsort2_cmp in_key_compare, void *in_compare_arg)
960.2.8 by Padraig O'Sullivan
Adding a function object to be used as the comparison parameter for the
877
    : key_compare(in_key_compare), key_compare_arg(in_compare_arg) { }
878
  inline bool operator()(const BUFFPEK *i, const BUFFPEK *j) const
879
  {
880
    int val= key_compare(key_compare_arg,
881
                      &i->key, &j->key);
882
    return (val >= 0);
883
  }
884
};
885
1 by brian
clean slate
886
/*
887
  Merge buffers to one buffer
888
  If to_file == 0 then use info->key_write
889
*/
890
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
891
int
482 by Brian Aker
Remove uint.
892
merge_buffers(MI_SORT_PARAM *info, uint32_t keys, IO_CACHE *from_file,
481 by Brian Aker
Remove all of uchar.
893
              IO_CACHE *to_file, unsigned char **sort_keys, BUFFPEK *lastbuff,
1 by brian
clean slate
894
              BUFFPEK *Fb, BUFFPEK *Tb)
895
{
896
  int error;
482 by Brian Aker
Remove uint.
897
  uint32_t sort_length,maxcount;
1 by brian
clean slate
898
  ha_rows count;
899
  my_off_t to_start_filepos= 0;
481 by Brian Aker
Remove all of uchar.
900
  unsigned char *strpos;
960.2.11 by Padraig O'Sullivan
Removing unused variables.
901
  BUFFPEK *buffpek;
960.2.8 by Padraig O'Sullivan
Adding a function object to be used as the comparison parameter for the
902
  priority_queue<BUFFPEK *, vector<BUFFPEK *>, compare_functor > 
960.2.16 by Padraig O'Sullivan
Adding comments to the function object that is used as the comparison
903
    queue(compare_functor((qsort2_cmp) info->key_cmp, static_cast<void *>(info)));
1 by brian
clean slate
904
  volatile int *killed= killed_ptr(info->sort_info->param);
905
906
  count=error=0;
907
  maxcount=keys/((uint) (Tb-Fb) +1);
51.1.119 by Jay Pipes
DBUG symbol removal
908
  assert(maxcount > 0);
1 by brian
clean slate
909
  if (to_file)
910
    to_start_filepos=my_b_tell(to_file);
481 by Brian Aker
Remove all of uchar.
911
  strpos=(unsigned char*) sort_keys;
1 by brian
clean slate
912
  sort_length=info->key_length;
913
914
  for (buffpek= Fb ; buffpek <= Tb ; buffpek++)
915
  {
916
    count+= buffpek->count;
917
    buffpek->base= strpos;
918
    buffpek->max_keys=maxcount;
919
    strpos+= (uint) (error=(int) info->read_to_buffer(from_file,buffpek,
920
                                                      sort_length));
921
    if (error == -1)
922
      goto err; /* purecov: inspected */
960.2.7 by Padraig O'Sullivan
Removed all traces of QUEUE from the codebase. We are using
923
    queue.push(buffpek);
1 by brian
clean slate
924
  }
925
960.2.7 by Padraig O'Sullivan
Removed all traces of QUEUE from the codebase. We are using
926
  while (queue.size() > 1)
1 by brian
clean slate
927
  {
928
    for (;;)
929
    {
930
      if (*killed)
931
      {
932
        error=1; goto err;
933
      }
960.2.7 by Padraig O'Sullivan
Removed all traces of QUEUE from the codebase. We are using
934
      buffpek= queue.top();
1 by brian
clean slate
935
      if (to_file)
936
      {
481 by Brian Aker
Remove all of uchar.
937
        if (info->write_key(info,to_file,(unsigned char*) buffpek->key,
1 by brian
clean slate
938
                            (uint) sort_length,1))
939
        {
940
          error=1; goto err; /* purecov: inspected */
941
        }
942
      }
943
      else
944
      {
945
        if ((*info->key_write)(info,(void*) buffpek->key))
946
        {
947
          error=1; goto err; /* purecov: inspected */
948
        }
949
      }
950
      buffpek->key+=sort_length;
951
      if (! --buffpek->mem_count)
952
      {
953
        if (!(error=(int) info->read_to_buffer(from_file,buffpek,sort_length)))
954
        {
960.2.7 by Padraig O'Sullivan
Removed all traces of QUEUE from the codebase. We are using
955
          queue.pop();
1 by brian
clean slate
956
          break;                /* One buffer have been removed */
957
        }
958
      }
959
      else if (error == -1)
960
        goto err;               /* purecov: inspected */
960.2.7 by Padraig O'Sullivan
Removed all traces of QUEUE from the codebase. We are using
961
      /* Top element has been replaced */
962
      queue.pop();
963
      queue.push(buffpek);
1 by brian
clean slate
964
    }
965
  }
960.2.7 by Padraig O'Sullivan
Removed all traces of QUEUE from the codebase. We are using
966
  buffpek= queue.top();
481 by Brian Aker
Remove all of uchar.
967
  buffpek->base=(unsigned char *) sort_keys;
1 by brian
clean slate
968
  buffpek->max_keys=keys;
969
  do
970
  {
971
    if (to_file)
972
    {
481 by Brian Aker
Remove all of uchar.
973
      if (info->write_key(info,to_file,(unsigned char*) buffpek->key,
1 by brian
clean slate
974
                         sort_length,buffpek->mem_count))
975
      {
976
        error=1; goto err; /* purecov: inspected */
977
      }
978
    }
979
    else
980
    {
481 by Brian Aker
Remove all of uchar.
981
      register unsigned char *end;
1 by brian
clean slate
982
      strpos= buffpek->key;
983
      for (end=strpos+buffpek->mem_count*sort_length;
984
           strpos != end ;
985
           strpos+=sort_length)
986
      {
987
        if ((*info->key_write)(info,(void*) strpos))
988
        {
989
          error=1; goto err; /* purecov: inspected */
990
        }
991
      }
992
    }
993
  }
994
  while ((error=(int) info->read_to_buffer(from_file,buffpek,sort_length)) != -1 &&
995
         error != 0);
996
997
  lastbuff->count=count;
998
  if (to_file)
999
    lastbuff->file_pos=to_start_filepos;
1000
err:
51.1.119 by Jay Pipes
DBUG symbol removal
1001
  return(error);
1 by brian
clean slate
1002
} /* merge_buffers */
1003
1004
1005
        /* Do a merge to output-file (save only positions) */
1006
960.3.1 by Monty Taylor
Fixed linkage issues on solaris.
1007
int
482 by Brian Aker
Remove uint.
1008
merge_index(MI_SORT_PARAM *info, uint32_t keys, unsigned char **sort_keys,
1 by brian
clean slate
1009
            BUFFPEK *buffpek, int maxbuffer, IO_CACHE *tempfile)
1010
{
1011
  if (merge_buffers(info,keys,tempfile,(IO_CACHE*) 0,sort_keys,buffpek,buffpek,
1012
                    buffpek+maxbuffer))
51.1.119 by Jay Pipes
DBUG symbol removal
1013
    return(1); /* purecov: inspected */
1014
  return(0);
1 by brian
clean slate
1015
} /* merge_index */
1016