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 |