mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
Revert "Fixed compilation failure on MacOSX"
This reverts commit df32495c85
.
This commit is contained in:
parent
275f7d7d82
commit
acc837981f
4 changed files with 351 additions and 388 deletions
|
@ -331,8 +331,7 @@ typedef struct st_sort_info
|
|||
my_off_t filelength, dupp, buff_length;
|
||||
ha_rows max_records;
|
||||
uint current_key, total_keys;
|
||||
volatile uint got_error;
|
||||
uint threads_running;
|
||||
uint got_error, threads_running;
|
||||
myf myf_rw;
|
||||
enum data_file_type new_data_file_type;
|
||||
} MI_SORT_INFO;
|
||||
|
|
|
@ -364,211 +364,192 @@ err:
|
|||
} /* find_all_keys */
|
||||
|
||||
|
||||
static my_bool _ma_thr_find_all_keys_exec(MARIA_SORT_PARAM* sort_param)
|
||||
{
|
||||
DBUG_ENTER("_ma_thr_find_all_keys");
|
||||
DBUG_PRINT("enter", ("master: %d", sort_param->master));
|
||||
|
||||
my_bool error= FALSE;
|
||||
if (sort_param->sort_info->got_error)
|
||||
error= TRUE;
|
||||
if (error)
|
||||
DBUG_RETURN(error);
|
||||
|
||||
set_sort_param_read_write(sort_param);
|
||||
|
||||
ulonglong memavl, old_memavl, sortbuff_size;
|
||||
ha_keys UNINIT_VAR(keys), idx;
|
||||
uint sort_length;
|
||||
uint maxbuffer;
|
||||
uchar **sort_keys= NULL;
|
||||
|
||||
my_b_clear(&sort_param->tempfile);
|
||||
my_b_clear(&sort_param->tempfile_for_exceptions);
|
||||
bzero((char*) &sort_param->buffpek, sizeof(sort_param->buffpek));
|
||||
bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
|
||||
|
||||
|
||||
sortbuff_size= sort_param->sortbuff_size;
|
||||
memavl= MY_MAX(sortbuff_size, MIN_SORT_BUFFER);
|
||||
idx= (ha_keys) sort_param->sort_info->max_records;
|
||||
sort_length= sort_param->key_length;
|
||||
maxbuffer= 1;
|
||||
|
||||
while (memavl >= MIN_SORT_BUFFER)
|
||||
{
|
||||
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <=
|
||||
(my_off_t) memavl)
|
||||
keys= idx+1;
|
||||
else if ((sort_param->sort_info->param->testflag &
|
||||
(T_FORCE_SORT_MEMORY | T_CREATE_MISSING_KEYS)) ==
|
||||
T_FORCE_SORT_MEMORY)
|
||||
{
|
||||
/*
|
||||
Use all of the given sort buffer for key data.
|
||||
Allocate 1000 buffers at a start for new data. More buffers
|
||||
will be allocated when needed.
|
||||
*/
|
||||
keys= memavl / (sort_length+sizeof(char*));
|
||||
maxbuffer= (uint) MY_MIN((ulonglong) 1000, (idx / keys)+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint maxbuffer_org;
|
||||
do
|
||||
{
|
||||
maxbuffer_org= maxbuffer;
|
||||
if (memavl < sizeof(BUFFPEK)*maxbuffer ||
|
||||
(keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
|
||||
(sort_length+sizeof(char*))) <= 1 ||
|
||||
keys < (uint) maxbuffer)
|
||||
{
|
||||
mysql_mutex_lock(&sort_param->sort_info->mutex);
|
||||
_ma_check_print_error(sort_param->sort_info->param,
|
||||
"aria_sort_buffer_size is too small. Current "
|
||||
"aria_sort_buffer_size: %llu rows: %llu "
|
||||
"sort_length: %u",
|
||||
sortbuff_size, (ulonglong) idx, sort_length);
|
||||
mysql_mutex_unlock(&sort_param->sort_info->mutex);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
while ((maxbuffer= (uint) (idx/(keys-1)+1)) != maxbuffer_org);
|
||||
}
|
||||
if ((sort_keys= (uchar **)
|
||||
my_malloc(keys*(sort_length+sizeof(char*))+
|
||||
((sort_param->keyinfo->flag & HA_FULLTEXT) ?
|
||||
HA_FT_MAXBYTELEN : 0), MYF(0))))
|
||||
{
|
||||
if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK),
|
||||
maxbuffer, MY_MIN(maxbuffer/2, 1000), MYF(0)))
|
||||
{
|
||||
my_free(sort_keys);
|
||||
sort_keys= NULL; /* Safety against double free on error. */
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
old_memavl= memavl;
|
||||
if ((memavl= memavl/4*3) < MIN_SORT_MEMORY &&
|
||||
old_memavl > MIN_SORT_MEMORY)
|
||||
memavl= MIN_SORT_MEMORY;
|
||||
}
|
||||
if (memavl < MIN_SORT_MEMORY)
|
||||
{
|
||||
/* purecov: begin inspected */
|
||||
mysql_mutex_lock(&sort_param->sort_info->mutex);
|
||||
_ma_check_print_error(sort_param->sort_info->param,
|
||||
"aria_sort_buffer_size is too small. Current "
|
||||
"aria_sort_buffer_size: %llu rows: %llu "
|
||||
"sort_length: %u",
|
||||
sortbuff_size, (ulonglong) idx, sort_length);
|
||||
my_errno= ENOMEM;
|
||||
mysql_mutex_unlock(&sort_param->sort_info->mutex);
|
||||
DBUG_RETURN(TRUE);
|
||||
/* purecov: end inspected */
|
||||
}
|
||||
if (sort_param->sort_info->param->testflag & T_VERBOSE)
|
||||
my_fprintf(stdout,
|
||||
"Key %d - Allocating buffer for %llu keys\n",
|
||||
sort_param->key + 1, (ulonglong) keys);
|
||||
sort_param->sort_keys= sort_keys;
|
||||
|
||||
idx= error= 0;
|
||||
sort_keys[0]= (uchar*) (sort_keys+keys);
|
||||
|
||||
DBUG_PRINT("info", ("reading keys"));
|
||||
while (!(error= sort_param->sort_info->got_error) &&
|
||||
!(error= (*sort_param->key_read)(sort_param, sort_keys[idx])))
|
||||
{
|
||||
if (sort_param->real_key_length > sort_param->key_length)
|
||||
{
|
||||
if (write_key(sort_param, sort_keys[idx],
|
||||
&sort_param->tempfile_for_exceptions))
|
||||
goto err;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (++idx == keys)
|
||||
{
|
||||
if (sort_param->write_keys(sort_param, sort_keys, idx - 1,
|
||||
(BUFFPEK *)alloc_dynamic(&sort_param->buffpek),
|
||||
&sort_param->tempfile))
|
||||
goto err;
|
||||
sort_keys[0]= (uchar*) (sort_keys+keys);
|
||||
memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length);
|
||||
idx= 1;
|
||||
}
|
||||
sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length;
|
||||
}
|
||||
if (error > 0)
|
||||
goto err;
|
||||
if (sort_param->buffpek.elements)
|
||||
{
|
||||
if (sort_param->write_keys(sort_param,sort_keys, idx,
|
||||
(BUFFPEK *) alloc_dynamic(&sort_param->
|
||||
buffpek),
|
||||
&sort_param->tempfile))
|
||||
goto err;
|
||||
sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx;
|
||||
}
|
||||
else
|
||||
sort_param->keys= idx;
|
||||
|
||||
DBUG_RETURN(FALSE);
|
||||
|
||||
err:
|
||||
DBUG_PRINT("error", ("got some error"));
|
||||
my_free(sort_keys);
|
||||
sort_param->sort_keys= 0;
|
||||
delete_dynamic(& sort_param->buffpek);
|
||||
close_cached_file(&sort_param->tempfile);
|
||||
close_cached_file(&sort_param->tempfile_for_exceptions);
|
||||
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
/* Search after all keys and place them in a temp. file */
|
||||
|
||||
pthread_handler_t _ma_thr_find_all_keys(void *arg)
|
||||
{
|
||||
MARIA_SORT_PARAM *sort_param= (MARIA_SORT_PARAM*) arg;
|
||||
my_bool error= FALSE;
|
||||
/* If my_thread_init fails */
|
||||
int error;
|
||||
size_t memavl, old_memavl;
|
||||
longlong sortbuff_size;
|
||||
ha_keys UNINIT_VAR(keys), idx;
|
||||
uint sort_length;
|
||||
uint maxbuffer;
|
||||
uchar **sort_keys=0;
|
||||
|
||||
error=1;
|
||||
|
||||
if (my_thread_init())
|
||||
error= TRUE;
|
||||
goto err;
|
||||
|
||||
if (error || _ma_thr_find_all_keys_exec(sort_param))
|
||||
error= TRUE;
|
||||
{ /* Add extra block since DBUG_ENTER declare variables */
|
||||
DBUG_ENTER("_ma_thr_find_all_keys");
|
||||
DBUG_PRINT("enter", ("master: %d", sort_param->master));
|
||||
if (sort_param->sort_info->got_error)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
Thread must clean up after itself.
|
||||
*/
|
||||
free_root(&sort_param->wordroot, MYF(0));
|
||||
/*
|
||||
Detach from the share if the writer is involved. Avoid others to
|
||||
be blocked. This includes a flush of the write buffer. This will
|
||||
also indicate EOF to the readers.
|
||||
That means that a writer always gets here first and readers -
|
||||
only when they see EOF. But if a reader finishes prematurely
|
||||
because of an error it may reach this earlier - don't allow it
|
||||
to detach the writer thread.
|
||||
*/
|
||||
if (sort_param->master && sort_param->sort_info->info->rec_cache.share)
|
||||
remove_io_thread(&sort_param->sort_info->info->rec_cache);
|
||||
set_sort_param_read_write(sort_param);
|
||||
|
||||
/* Readers detach from the share if any. Avoid others to be blocked. */
|
||||
if (sort_param->read_cache.share)
|
||||
remove_io_thread(&sort_param->read_cache);
|
||||
my_b_clear(&sort_param->tempfile);
|
||||
my_b_clear(&sort_param->tempfile_for_exceptions);
|
||||
bzero((char*) &sort_param->buffpek,sizeof(sort_param->buffpek));
|
||||
bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
|
||||
|
||||
mysql_mutex_lock(&sort_param->sort_info->mutex);
|
||||
if (error)
|
||||
sort_param->sort_info->got_error= 1;
|
||||
sortbuff_size= sort_param->sortbuff_size;
|
||||
memavl= MY_MAX(sortbuff_size, MIN_SORT_MEMORY);
|
||||
idx= (ha_keys) sort_param->sort_info->max_records;
|
||||
sort_length= sort_param->key_length;
|
||||
maxbuffer= 1;
|
||||
|
||||
if (!--sort_param->sort_info->threads_running)
|
||||
mysql_cond_signal(&sort_param->sort_info->cond);
|
||||
mysql_mutex_unlock(&sort_param->sort_info->mutex);
|
||||
while (memavl >= MIN_SORT_MEMORY)
|
||||
{
|
||||
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <= (my_off_t) memavl)
|
||||
keys= idx+1;
|
||||
else if ((sort_param->sort_info->param->testflag &
|
||||
(T_FORCE_SORT_MEMORY | T_CREATE_MISSING_KEYS)) ==
|
||||
T_FORCE_SORT_MEMORY)
|
||||
{
|
||||
/*
|
||||
Use all of the given sort buffer for key data.
|
||||
Allocate 1000 buffers at a start for new data. More buffers
|
||||
will be allocated when needed.
|
||||
*/
|
||||
keys= memavl / (sort_length+sizeof(char*));
|
||||
maxbuffer= (uint) MY_MIN((ulonglong) 1000, (idx / keys)+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint maxbuffer_org;
|
||||
do
|
||||
{
|
||||
maxbuffer_org= maxbuffer;
|
||||
if (memavl < sizeof(BUFFPEK)*maxbuffer ||
|
||||
(keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
|
||||
(sort_length+sizeof(char*))) <= 1 ||
|
||||
keys < maxbuffer)
|
||||
{
|
||||
_ma_check_print_error(sort_param->sort_info->param,
|
||||
"aria_sort_buffer_size is too small. Current aria_sort_buffer_size: %llu rows: %llu sort_length: %u",
|
||||
sortbuff_size, (ulonglong) idx, sort_length);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
while ((maxbuffer= (uint) (idx/(keys-1)+1)) != maxbuffer_org);
|
||||
}
|
||||
if ((sort_keys= (uchar **)
|
||||
my_malloc(keys*(sort_length+sizeof(char*))+
|
||||
((sort_param->keyinfo->flag & HA_FULLTEXT) ?
|
||||
HA_FT_MAXBYTELEN : 0), MYF(0))))
|
||||
{
|
||||
if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK),
|
||||
maxbuffer, MY_MIN(maxbuffer/2, 1000), MYF(0)))
|
||||
{
|
||||
my_free(sort_keys);
|
||||
sort_keys= (uchar **) NULL; /* for err: label */
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
old_memavl= memavl;
|
||||
if ((memavl= memavl/4*3) < MIN_SORT_MEMORY &&
|
||||
old_memavl > MIN_SORT_MEMORY)
|
||||
memavl= MIN_SORT_MEMORY;
|
||||
}
|
||||
if (memavl < MIN_SORT_MEMORY)
|
||||
{
|
||||
/* purecov: begin inspected */
|
||||
_ma_check_print_error(sort_param->sort_info->param,
|
||||
"aria_sort_buffer_size is too small. Current aria_sort_buffer_size: %llu rows: %llu sort_length: %u",
|
||||
sortbuff_size, (ulonglong) idx, sort_length);
|
||||
my_errno= ENOMEM;
|
||||
goto err;
|
||||
/* purecov: end inspected */
|
||||
}
|
||||
|
||||
if (sort_param->sort_info->param->testflag & T_VERBOSE)
|
||||
my_fprintf(stdout,
|
||||
"Key %d - Allocating buffer for %llu keys\n",
|
||||
sort_param->key + 1, (ulonglong) keys);
|
||||
sort_param->sort_keys= sort_keys;
|
||||
|
||||
idx= error= 0;
|
||||
sort_keys[0]= (uchar*) (sort_keys+keys);
|
||||
|
||||
DBUG_PRINT("info", ("reading keys"));
|
||||
while (!(error= sort_param->sort_info->got_error) &&
|
||||
!(error= (*sort_param->key_read)(sort_param, sort_keys[idx])))
|
||||
{
|
||||
if (sort_param->real_key_length > sort_param->key_length)
|
||||
{
|
||||
if (write_key(sort_param, sort_keys[idx],
|
||||
&sort_param->tempfile_for_exceptions))
|
||||
goto err;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (++idx == keys)
|
||||
{
|
||||
if (sort_param->write_keys(sort_param, sort_keys, idx - 1,
|
||||
(BUFFPEK *)alloc_dynamic(&sort_param->
|
||||
buffpek),
|
||||
&sort_param->tempfile))
|
||||
goto err;
|
||||
sort_keys[0]= (uchar*) (sort_keys+keys);
|
||||
memcpy(sort_keys[0], sort_keys[idx - 1],
|
||||
(size_t) sort_param->key_length);
|
||||
idx= 1;
|
||||
}
|
||||
sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length;
|
||||
}
|
||||
if (error > 0)
|
||||
goto err;
|
||||
if (sort_param->buffpek.elements)
|
||||
{
|
||||
if (sort_param->write_keys(sort_param,sort_keys, idx,
|
||||
(BUFFPEK *) alloc_dynamic(&sort_param->
|
||||
buffpek),
|
||||
&sort_param->tempfile))
|
||||
goto err;
|
||||
sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx;
|
||||
}
|
||||
else
|
||||
sort_param->keys= idx;
|
||||
|
||||
goto ok;
|
||||
|
||||
err:
|
||||
DBUG_PRINT("error", ("got some error"));
|
||||
sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */
|
||||
my_free(sort_keys);
|
||||
sort_param->sort_keys= 0;
|
||||
delete_dynamic(& sort_param->buffpek);
|
||||
close_cached_file(&sort_param->tempfile);
|
||||
close_cached_file(&sort_param->tempfile_for_exceptions);
|
||||
|
||||
ok:
|
||||
free_root(&sort_param->wordroot, MYF(0));
|
||||
/*
|
||||
Detach from the share if the writer is involved. Avoid others to
|
||||
be blocked. This includes a flush of the write buffer. This will
|
||||
also indicate EOF to the readers.
|
||||
That means that a writer always gets here first and readers -
|
||||
only when they see EOF. But if a reader finishes prematurely
|
||||
because of an error it may reach this earlier - don't allow it
|
||||
to detach the writer thread.
|
||||
*/
|
||||
if (sort_param->master && sort_param->sort_info->info->rec_cache.share)
|
||||
remove_io_thread(&sort_param->sort_info->info->rec_cache);
|
||||
|
||||
/* Readers detach from the share if any. Avoid others to be blocked. */
|
||||
if (sort_param->read_cache.share)
|
||||
remove_io_thread(&sort_param->read_cache);
|
||||
|
||||
mysql_mutex_lock(&sort_param->sort_info->mutex);
|
||||
if (!--sort_param->sort_info->threads_running)
|
||||
mysql_cond_signal(&sort_param->sort_info->cond);
|
||||
mysql_mutex_unlock(&sort_param->sort_info->mutex);
|
||||
DBUG_PRINT("exit", ("======== ending thread ========"));
|
||||
}
|
||||
my_thread_end();
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -67,8 +67,7 @@ typedef struct st_maria_sort_info
|
|||
pgcache_page_no_t page;
|
||||
ha_rows max_records;
|
||||
uint current_key, total_keys;
|
||||
volatile uint got_error;
|
||||
uint threads_running;
|
||||
uint got_error, threads_running;
|
||||
myf myf_rw;
|
||||
enum data_file_type new_data_file_type, org_data_file_type;
|
||||
} MARIA_SORT_INFO;
|
||||
|
|
|
@ -344,208 +344,192 @@ static ha_rows find_all_keys(MI_SORT_PARAM *info, ha_rows keys,
|
|||
DBUG_RETURN((*maxbuffer)*(keys-1)+idx);
|
||||
} /* find_all_keys */
|
||||
|
||||
static my_bool thr_find_all_keys_exec(MI_SORT_PARAM *sort_param)
|
||||
{
|
||||
DBUG_ENTER("thr_find_all_keys");
|
||||
DBUG_PRINT("enter", ("master: %d", sort_param->master));
|
||||
|
||||
my_bool error= FALSE;
|
||||
if (sort_param->sort_info->got_error)
|
||||
error= TRUE;
|
||||
if (error)
|
||||
DBUG_RETURN(error);
|
||||
|
||||
set_sort_param_read_write(sort_param);
|
||||
|
||||
ulonglong memavl, old_memavl, sortbuff_size;
|
||||
ha_keys UNINIT_VAR(keys), idx;
|
||||
uint sort_length;
|
||||
uint maxbuffer;
|
||||
uchar **sort_keys= NULL;
|
||||
|
||||
my_b_clear(&sort_param->tempfile);
|
||||
my_b_clear(&sort_param->tempfile_for_exceptions);
|
||||
bzero((char*) &sort_param->buffpek, sizeof(sort_param->buffpek));
|
||||
bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
|
||||
|
||||
|
||||
sortbuff_size= sort_param->sortbuff_size;
|
||||
memavl= MY_MAX(sortbuff_size, MIN_SORT_BUFFER);
|
||||
idx= (ha_keys) sort_param->sort_info->max_records;
|
||||
sort_length= sort_param->key_length;
|
||||
maxbuffer= 1;
|
||||
|
||||
while (memavl >= MIN_SORT_BUFFER)
|
||||
{
|
||||
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <=
|
||||
(my_off_t) memavl)
|
||||
keys= idx+1;
|
||||
else if ((sort_param->sort_info->param->testflag &
|
||||
(T_FORCE_SORT_MEMORY | T_CREATE_MISSING_KEYS)) ==
|
||||
T_FORCE_SORT_MEMORY)
|
||||
{
|
||||
/*
|
||||
Use all of the given sort buffer for key data.
|
||||
Allocate 1000 buffers at a start for new data. More buffers
|
||||
will be allocated when needed.
|
||||
*/
|
||||
keys= memavl / (sort_length+sizeof(char*));
|
||||
maxbuffer= (uint) MY_MIN((ulonglong) 1000, (idx / keys)+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint maxbuffer_org;
|
||||
do
|
||||
{
|
||||
maxbuffer_org= maxbuffer;
|
||||
if (memavl < sizeof(BUFFPEK)*maxbuffer ||
|
||||
(keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
|
||||
(sort_length+sizeof(char*))) <= 1 ||
|
||||
keys < (uint) maxbuffer)
|
||||
{
|
||||
mysql_mutex_lock(&sort_param->sort_info->mutex);
|
||||
mi_check_print_error(sort_param->sort_info->param,
|
||||
"myisam_sort_buffer_size is too small. Current "
|
||||
"myisam_sort_buffer_size: %llu rows: %llu sort_length: %u",
|
||||
sortbuff_size, (ulonglong) idx, sort_length);
|
||||
mysql_mutex_unlock(&sort_param->sort_info->mutex);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
while ((maxbuffer= (uint) (idx/(keys-1)+1)) != maxbuffer_org);
|
||||
}
|
||||
if ((sort_keys= my_malloc(keys * (sort_length + sizeof(char *)) +
|
||||
((sort_param->keyinfo->flag & HA_FULLTEXT) ?
|
||||
HA_FT_MAXBYTELEN : 0), MYF(0))))
|
||||
{
|
||||
if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK),
|
||||
maxbuffer, MY_MIN(maxbuffer/2, 1000), MYF(0)))
|
||||
{
|
||||
my_free(sort_keys);
|
||||
sort_keys= NULL; /* Safety against double free on error. */
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
old_memavl= memavl;
|
||||
if ((memavl= memavl / 4 * 3) < MIN_SORT_BUFFER &&
|
||||
old_memavl > MIN_SORT_BUFFER)
|
||||
memavl= MIN_SORT_BUFFER;
|
||||
}
|
||||
if (memavl < MIN_SORT_BUFFER)
|
||||
{
|
||||
/* purecov: begin inspected */
|
||||
mysql_mutex_lock(&sort_param->sort_info->mutex);
|
||||
mi_check_print_error(sort_param->sort_info->param,
|
||||
"myisam_sort_buffer_size is too small. Current "
|
||||
"myisam_sort_buffer_size: %llu rows: %llu sort_length: %u",
|
||||
sortbuff_size, (ulonglong) idx, sort_length);
|
||||
my_errno= ENOMEM;
|
||||
mysql_mutex_unlock(&sort_param->sort_info->mutex);
|
||||
DBUG_RETURN(TRUE);
|
||||
/* purecov: end inspected */
|
||||
}
|
||||
|
||||
if (sort_param->sort_info->param->testflag & T_VERBOSE)
|
||||
my_fprintf(stdout,
|
||||
"Key %d - Allocating buffer for %llu keys\n",
|
||||
sort_param->key + 1, (ulonglong) keys);
|
||||
sort_param->sort_keys= sort_keys;
|
||||
|
||||
idx= error= 0;
|
||||
sort_keys[0]= (uchar*) (sort_keys+keys);
|
||||
|
||||
DBUG_PRINT("info", ("reading keys"));
|
||||
while (!(error= sort_param->sort_info->got_error) &&
|
||||
!(error= (*sort_param->key_read)(sort_param, sort_keys[idx])))
|
||||
{
|
||||
if (sort_param->real_key_length > sort_param->key_length)
|
||||
{
|
||||
if (write_key(sort_param, sort_keys[idx],
|
||||
&sort_param->tempfile_for_exceptions))
|
||||
goto err;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (++idx == keys)
|
||||
{
|
||||
if (sort_param->write_keys(sort_param, sort_keys, idx - 1,
|
||||
(BUFFPEK*) alloc_dynamic(&sort_param->buffpek),
|
||||
&sort_param->tempfile))
|
||||
goto err;
|
||||
sort_keys[0]= (uchar*) (sort_keys+keys);
|
||||
memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length);
|
||||
idx= 1;
|
||||
}
|
||||
sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length;
|
||||
}
|
||||
if (error > 0)
|
||||
goto err;
|
||||
if (sort_param->buffpek.elements)
|
||||
{
|
||||
if (sort_param->write_keys(sort_param, sort_keys, idx,
|
||||
(BUFFPEK*) alloc_dynamic(&sort_param->buffpek),
|
||||
&sort_param->tempfile))
|
||||
goto err;
|
||||
sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx;
|
||||
}
|
||||
else
|
||||
sort_param->keys= idx;
|
||||
|
||||
DBUG_RETURN(FALSE);
|
||||
|
||||
err:
|
||||
DBUG_PRINT("error", ("got some error"));
|
||||
sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */
|
||||
my_free(sort_keys);
|
||||
sort_param->sort_keys= 0;
|
||||
delete_dynamic(& sort_param->buffpek);
|
||||
close_cached_file(&sort_param->tempfile);
|
||||
close_cached_file(&sort_param->tempfile_for_exceptions);
|
||||
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
/* Search after all keys and place them in a temp. file */
|
||||
|
||||
pthread_handler_t thr_find_all_keys(void *arg)
|
||||
{
|
||||
MI_SORT_PARAM *sort_param= (MI_SORT_PARAM*) arg;
|
||||
my_bool error= FALSE;
|
||||
/* If my_thread_init fails */
|
||||
int error;
|
||||
ulonglong memavl, old_memavl, sortbuff_size;
|
||||
ha_keys UNINIT_VAR(keys), idx;
|
||||
uint sort_length;
|
||||
uint maxbuffer;
|
||||
uchar **sort_keys=0;
|
||||
|
||||
error=1;
|
||||
|
||||
if (my_thread_init())
|
||||
error= TRUE;
|
||||
goto err;
|
||||
|
||||
if (error || thr_find_all_keys_exec(sort_param))
|
||||
error= TRUE;
|
||||
{ /* Add extra block since DBUG_ENTER declare variables */
|
||||
DBUG_ENTER("thr_find_all_keys");
|
||||
DBUG_PRINT("enter", ("master: %d", sort_param->master));
|
||||
if (sort_param->sort_info->got_error)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
Thread must clean up after itself.
|
||||
*/
|
||||
free_root(&sort_param->wordroot, MYF(0));
|
||||
/*
|
||||
Detach from the share if the writer is involved. Avoid others to
|
||||
be blocked. This includes a flush of the write buffer. This will
|
||||
also indicate EOF to the readers.
|
||||
That means that a writer always gets here first and readers -
|
||||
only when they see EOF. But if a reader finishes prematurely
|
||||
because of an error it may reach this earlier - don't allow it
|
||||
to detach the writer thread.
|
||||
*/
|
||||
if (sort_param->master && sort_param->sort_info->info->rec_cache.share)
|
||||
remove_io_thread(&sort_param->sort_info->info->rec_cache);
|
||||
set_sort_param_read_write(sort_param);
|
||||
|
||||
/* Readers detach from the share if any. Avoid others to be blocked. */
|
||||
if (sort_param->read_cache.share)
|
||||
remove_io_thread(&sort_param->read_cache);
|
||||
my_b_clear(&sort_param->tempfile);
|
||||
my_b_clear(&sort_param->tempfile_for_exceptions);
|
||||
bzero((char*) &sort_param->buffpek, sizeof(sort_param->buffpek));
|
||||
bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
|
||||
sort_keys= (uchar **) NULL;
|
||||
|
||||
mysql_mutex_lock(&sort_param->sort_info->mutex);
|
||||
if (error)
|
||||
sort_param->sort_info->got_error= 1;
|
||||
sortbuff_size= sort_param->sortbuff_size;
|
||||
memavl= MY_MAX(sortbuff_size, MIN_SORT_BUFFER);
|
||||
idx= (ha_keys) sort_param->sort_info->max_records;
|
||||
sort_length= sort_param->key_length;
|
||||
maxbuffer= 1;
|
||||
|
||||
if (!--sort_param->sort_info->threads_running)
|
||||
mysql_cond_signal(&sort_param->sort_info->cond);
|
||||
mysql_mutex_unlock(&sort_param->sort_info->mutex);
|
||||
while (memavl >= MIN_SORT_BUFFER)
|
||||
{
|
||||
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <=
|
||||
(my_off_t) memavl)
|
||||
keys= idx+1;
|
||||
else if ((sort_param->sort_info->param->testflag &
|
||||
(T_FORCE_SORT_MEMORY | T_CREATE_MISSING_KEYS)) ==
|
||||
T_FORCE_SORT_MEMORY)
|
||||
{
|
||||
/*
|
||||
Use all of the given sort buffer for key data.
|
||||
Allocate 1000 buffers at a start for new data. More buffers
|
||||
will be allocated when needed.
|
||||
*/
|
||||
keys= memavl / (sort_length+sizeof(char*));
|
||||
maxbuffer= (uint) MY_MIN((ulonglong) 1000, (idx / keys)+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint maxbuffer_org;
|
||||
do
|
||||
{
|
||||
maxbuffer_org= maxbuffer;
|
||||
if (memavl < sizeof(BUFFPEK)*maxbuffer ||
|
||||
(keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
|
||||
(sort_length+sizeof(char*))) <= 1 ||
|
||||
keys < (uint) maxbuffer)
|
||||
{
|
||||
mi_check_print_error(sort_param->sort_info->param,
|
||||
"myisam_sort_buffer_size is too small. Current myisam_sort_buffer_size: %llu rows: %llu sort_length: %u",
|
||||
sortbuff_size, (ulonglong) idx, sort_length);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
while ((maxbuffer= (uint) (idx/(keys-1)+1)) != maxbuffer_org);
|
||||
}
|
||||
if ((sort_keys= (uchar**)
|
||||
my_malloc(keys*(sort_length+sizeof(char*))+
|
||||
((sort_param->keyinfo->flag & HA_FULLTEXT) ?
|
||||
HA_FT_MAXBYTELEN : 0), MYF(0))))
|
||||
{
|
||||
if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK),
|
||||
maxbuffer, MY_MIN(maxbuffer/2, 1000), MYF(0)))
|
||||
{
|
||||
my_free(sort_keys);
|
||||
sort_keys= (uchar **) NULL; /* for err: label */
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
old_memavl= memavl;
|
||||
if ((memavl= memavl / 4 * 3) < MIN_SORT_BUFFER &&
|
||||
old_memavl > MIN_SORT_BUFFER)
|
||||
memavl= MIN_SORT_BUFFER;
|
||||
}
|
||||
if (memavl < MIN_SORT_BUFFER)
|
||||
{
|
||||
/* purecov: begin inspected */
|
||||
mi_check_print_error(sort_param->sort_info->param,
|
||||
"myisam_sort_buffer_size is too small. Current myisam_sort_buffer_size: %llu rows: %llu sort_length: %u",
|
||||
sortbuff_size, (ulonglong) idx, sort_length);
|
||||
my_errno= ENOMEM;
|
||||
goto err;
|
||||
/* purecov: end inspected */
|
||||
}
|
||||
|
||||
if (sort_param->sort_info->param->testflag & T_VERBOSE)
|
||||
my_fprintf(stdout,
|
||||
"Key %d - Allocating buffer for %llu keys\n",
|
||||
sort_param->key + 1, (ulonglong) keys);
|
||||
sort_param->sort_keys= sort_keys;
|
||||
|
||||
idx= error= 0;
|
||||
sort_keys[0]= (uchar*) (sort_keys+keys);
|
||||
|
||||
DBUG_PRINT("info", ("reading keys"));
|
||||
while (!(error= sort_param->sort_info->got_error) &&
|
||||
!(error= (*sort_param->key_read)(sort_param, sort_keys[idx])))
|
||||
{
|
||||
if (sort_param->real_key_length > sort_param->key_length)
|
||||
{
|
||||
if (write_key(sort_param, sort_keys[idx],
|
||||
&sort_param->tempfile_for_exceptions))
|
||||
goto err;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (++idx == keys)
|
||||
{
|
||||
if (sort_param->write_keys(sort_param, sort_keys, idx - 1,
|
||||
(BUFFPEK*) alloc_dynamic(&sort_param->buffpek),
|
||||
&sort_param->tempfile))
|
||||
goto err;
|
||||
sort_keys[0]= (uchar*) (sort_keys+keys);
|
||||
memcpy(sort_keys[0], sort_keys[idx - 1],
|
||||
(size_t) sort_param->key_length);
|
||||
idx= 1;
|
||||
}
|
||||
sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length;
|
||||
}
|
||||
if (error > 0)
|
||||
goto err;
|
||||
if (sort_param->buffpek.elements)
|
||||
{
|
||||
if (sort_param->write_keys(sort_param, sort_keys, idx,
|
||||
(BUFFPEK*) alloc_dynamic(&sort_param->buffpek),
|
||||
&sort_param->tempfile))
|
||||
goto err;
|
||||
sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx;
|
||||
}
|
||||
else
|
||||
sort_param->keys= idx;
|
||||
|
||||
goto ok;
|
||||
|
||||
err:
|
||||
DBUG_PRINT("error", ("got some error"));
|
||||
sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */
|
||||
my_free(sort_keys);
|
||||
sort_param->sort_keys= 0;
|
||||
delete_dynamic(& sort_param->buffpek);
|
||||
close_cached_file(&sort_param->tempfile);
|
||||
close_cached_file(&sort_param->tempfile_for_exceptions);
|
||||
|
||||
ok:
|
||||
free_root(&sort_param->wordroot, MYF(0));
|
||||
/*
|
||||
Detach from the share if the writer is involved. Avoid others to
|
||||
be blocked. This includes a flush of the write buffer. This will
|
||||
also indicate EOF to the readers.
|
||||
That means that a writer always gets here first and readers -
|
||||
only when they see EOF. But if a reader finishes prematurely
|
||||
because of an error it may reach this earlier - don't allow it
|
||||
to detach the writer thread.
|
||||
*/
|
||||
if (sort_param->master && sort_param->sort_info->info->rec_cache.share)
|
||||
remove_io_thread(&sort_param->sort_info->info->rec_cache);
|
||||
|
||||
/* Readers detach from the share if any. Avoid others to be blocked. */
|
||||
if (sort_param->read_cache.share)
|
||||
remove_io_thread(&sort_param->read_cache);
|
||||
|
||||
mysql_mutex_lock(&sort_param->sort_info->mutex);
|
||||
if (!--sort_param->sort_info->threads_running)
|
||||
mysql_cond_signal(&sort_param->sort_info->cond);
|
||||
mysql_mutex_unlock(&sort_param->sort_info->mutex);
|
||||
DBUG_PRINT("exit", ("======== ending thread ========"));
|
||||
DBUG_LEAVE;
|
||||
}
|
||||
my_thread_end();
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue