16 #include "filesort_utils.h"
29 double get_merge_cost(ha_rows num_elements, ha_rows num_buffers, uint elem_size)
32 2.0 * ((double) num_elements * elem_size) / IO_SIZE
44 double get_merge_many_buffs_cost_fast(ha_rows num_rows,
45 ha_rows num_keys_per_buffer,
48 ha_rows num_buffers= num_rows / num_keys_per_buffer;
49 ha_rows last_n_elems= num_rows % num_keys_per_buffer;
54 ( num_buffers * num_keys_per_buffer * log(1.0 + num_keys_per_buffer) +
58 while (num_buffers >= MERGEBUFF2)
61 const ha_rows loop_limit= num_buffers - MERGEBUFF*3/2;
62 const ha_rows num_merge_calls= 1 + loop_limit/MERGEBUFF;
63 const ha_rows num_remaining_buffs=
64 num_buffers - num_merge_calls * MERGEBUFF;
69 get_merge_cost(num_keys_per_buffer * MERGEBUFF, MERGEBUFF, elem_size);
72 last_n_elems+= num_remaining_buffs * num_keys_per_buffer;
76 get_merge_cost(last_n_elems, 1 + num_remaining_buffs, elem_size);
78 num_buffers= num_merge_calls;
79 num_keys_per_buffer*= MERGEBUFF;
83 last_n_elems+= num_keys_per_buffer * num_buffers;
84 total_cost+= get_merge_cost(last_n_elems, 1 + num_buffers, elem_size);
91 DBUG_ENTER(
"alloc_sort_buffer");
93 DBUG_EXECUTE_IF(
"alloc_sort_buffer_fail",
94 DBUG_SET(
"+d,simulate_out_of_memory"););
96 if (m_idx_array.is_null())
99 (uchar**) my_malloc(num_records * (record_length +
sizeof(uchar*)),
101 m_idx_array=
Idx_array(sort_keys, num_records);
102 m_record_length= record_length;
103 uchar **start_of_data= m_idx_array.array() + m_idx_array.size();
104 m_start_of_data=
reinterpret_cast<uchar*
>(start_of_data);
108 DBUG_ASSERT(num_records == m_idx_array.size());
109 DBUG_ASSERT(record_length == m_record_length);
111 DBUG_RETURN(m_idx_array.array());
117 my_free(m_idx_array.array());
120 m_start_of_data= NULL;
131 inline bool my_mem_compare(
const uchar *s1,
const uchar *s2,
size_t len)
133 DBUG_ASSERT(len > 0);
134 DBUG_ASSERT(s1 != NULL);
135 DBUG_ASSERT(s2 != NULL);
138 return *--s1 < *--s2;
139 }
while (--len != 0);
145 public std::binary_function<const uchar*, const uchar*, bool>
148 Mem_compare(
size_t n) : m_size(n) {}
149 bool operator()(
const uchar *s1,
const uchar *s2)
const
153 return memcmp(s1, s2, m_size) < 0;
155 return my_mem_compare(s1, s2, m_size);
162 template <
typename type>
163 size_t try_reserve(std::pair<type*, ptrdiff_t> *
buf, ptrdiff_t
size)
165 *buf= std::get_temporary_buffer<type>(
size);
166 if (buf->second != size)
168 std::return_temporary_buffer(buf->first);
180 if (param->sort_length == 0)
184 std::pair<uchar**, ptrdiff_t> buffer;
185 if (radixsort_is_appliccable(count, param->sort_length) &&
186 try_reserve(&buffer, count))
188 radixsort_for_str_ptr(keys, count, param->sort_length, buffer.first);
189 std::return_temporary_buffer(buffer.first);
200 size_t size= param->sort_length;
201 my_qsort2(keys, count,
sizeof(uchar*), get_ptr_compare(size), &size);
204 std::stable_sort(keys, keys + count, Mem_compare(param->sort_length));