summaryrefslogtreecommitdiff
path: root/sql/filesort_utils.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/filesort_utils.cc')
-rw-r--r--sql/filesort_utils.cc75
1 files changed, 43 insertions, 32 deletions
diff --git a/sql/filesort_utils.cc b/sql/filesort_utils.cc
index 849e6ee761a..5a51300a0fa 100644
--- a/sql/filesort_utils.cc
+++ b/sql/filesort_utils.cc
@@ -21,6 +21,8 @@
#include "table.h"
+PSI_memory_key key_memory_Filesort_buffer_sort_keys;
+
namespace {
/**
A local helper function. See comments for get_merge_buffers_cost().
@@ -51,9 +53,9 @@ double get_merge_many_buffs_cost_fast(ha_rows num_rows,
// Calculate CPU cost of sorting buffers.
total_cost=
- ( num_buffers * num_keys_per_buffer * log(1.0 + num_keys_per_buffer) +
- last_n_elems * log(1.0 + last_n_elems) )
- / TIME_FOR_COMPARE_ROWID;
+ ((num_buffers * num_keys_per_buffer * log(1.0 + num_keys_per_buffer) +
+ last_n_elems * log(1.0 + last_n_elems)) /
+ TIME_FOR_COMPARE_ROWID);
// Simulate behavior of merge_many_buff().
while (num_buffers >= MERGEBUFF2)
@@ -97,81 +99,90 @@ double get_merge_many_buffs_cost_fast(ha_rows num_rows,
# Pointer to allocated buffer
*/
-uchar **Filesort_buffer::alloc_sort_buffer(uint num_records,
- uint record_length)
+uchar *Filesort_buffer::alloc_sort_buffer(uint num_records,
+ uint record_length)
{
size_t buff_size;
- uchar **sort_keys, **start_of_data;
DBUG_ENTER("alloc_sort_buffer");
DBUG_EXECUTE_IF("alloc_sort_buffer_fail",
DBUG_SET("+d,simulate_out_of_memory"););
- buff_size= ((size_t)num_records) * (record_length + sizeof(uchar*));
+ buff_size= ALIGN_SIZE(num_records * (record_length + sizeof(uchar*)));
- if (!m_idx_array.is_null())
+ if (m_rawmem)
{
/*
Reuse old buffer if exists and is large enough
Note that we don't make the buffer smaller, as we want to be
prepared for next subquery iteration.
*/
-
- sort_keys= m_idx_array.array();
- if (buff_size > allocated_size)
+ if (buff_size > m_size_in_bytes)
{
/*
Better to free and alloc than realloc as we don't have to remember
the old values
*/
- my_free(sort_keys);
- if (!(sort_keys= (uchar**) my_malloc(buff_size,
- MYF(MY_THREAD_SPECIFIC))))
+ my_free(m_rawmem);
+ if (!(m_rawmem= (uchar*) my_malloc(key_memory_Filesort_buffer_sort_keys,
+ buff_size, MYF(MY_THREAD_SPECIFIC))))
{
- reset();
+ m_size_in_bytes= 0;
DBUG_RETURN(0);
}
- allocated_size= buff_size;
}
}
else
{
- if (!(sort_keys= (uchar**) my_malloc(buff_size, MYF(MY_THREAD_SPECIFIC))))
+ if (!(m_rawmem= (uchar*) my_malloc(key_memory_Filesort_buffer_sort_keys,
+ buff_size, MYF(MY_THREAD_SPECIFIC))))
+ {
+ m_size_in_bytes= 0;
DBUG_RETURN(0);
- allocated_size= buff_size;
+ }
+
}
- m_idx_array= Idx_array(sort_keys, num_records);
+ m_size_in_bytes= buff_size;
+ m_record_pointers= reinterpret_cast<uchar**>(m_rawmem) +
+ ((m_size_in_bytes / sizeof(uchar*)) - 1);
+ m_num_records= num_records;
m_record_length= record_length;
- start_of_data= m_idx_array.array() + m_idx_array.size();
- m_start_of_data= reinterpret_cast<uchar*>(start_of_data);
-
- DBUG_RETURN(m_idx_array.array());
+ m_idx= 0;
+ DBUG_RETURN(m_rawmem);
}
void Filesort_buffer::free_sort_buffer()
{
- my_free(m_idx_array.array());
- m_idx_array.reset();
- m_start_of_data= NULL;
+ my_free(m_rawmem);
+ *this= Filesort_buffer();
}
void Filesort_buffer::sort_buffer(const Sort_param *param, uint count)
{
size_t size= param->sort_length;
+ m_sort_keys= get_sort_keys();
+
if (count <= 1 || size == 0)
return;
- uchar **keys= get_sort_keys();
+
+ // don't reverse for PQ, it is already done
+ if (!param->using_pq)
+ reverse_record_pointers();
+
uchar **buffer= NULL;
- if (radixsort_is_appliccable(count, param->sort_length) &&
- (buffer= (uchar**) my_malloc(count*sizeof(char*),
+ if (!param->using_packed_sortkeys() &&
+ radixsort_is_appliccable(count, param->sort_length) &&
+ (buffer= (uchar**) my_malloc(PSI_INSTRUMENT_ME, count*sizeof(char*),
MYF(MY_THREAD_SPECIFIC))))
{
- radixsort_for_str_ptr(keys, count, param->sort_length, buffer);
+ radixsort_for_str_ptr(m_sort_keys, count, param->sort_length, buffer);
my_free(buffer);
return;
}
-
- my_qsort2(keys, count, sizeof(uchar*), get_ptr_compare(size), &size);
+
+ my_qsort2(m_sort_keys, count, sizeof(uchar*),
+ param->get_compare_function(),
+ param->get_compare_argument(&size));
}