- SQL filesortcc question - 6 Updates
- Why are there throw() following the delete[]? - 2 Updates
- Concrete classes considered harmful - 2 Updates
- What practice can get speed improvement in C++? - 8 Updates
- Elementary question on references. - 1 Update
doctor@doctor.nl2k.ab.ca (The Doctor): Jul 15 08:40PM All right to essentials on this one. Using g++ 3.2.3 , Gmake 4.01 and Cmake 2.6.4 I get Script started on Wed Jul 15 06:45:13 2015 doctor.nl2k.ab.ca//usr/source/mysql-5.6.25$ gmake [ 0%] Built target INFO_BIN ... Scanning dependencies of target sql [ 47%] Building CXX object sql/CMakeFiles/sql.dir/sql_yacc.cc.o [ 47%] Building CXX object sql/CMakeFiles/sql.dir/abstract_query_plan.cc.o [ 47%] Building CXX object sql/CMakeFiles/sql.dir/datadict.cc.o [ 47%] Building CXX object sql/CMakeFiles/sql.dir/debug_sync.cc.o [ 47%] Building CXX object sql/CMakeFiles/sql.dir/derror.cc.o [ 47%] Building CXX object sql/CMakeFiles/sql.dir/des_key_file.cc.o [ 47%] Building CXX object sql/CMakeFiles/sql.dir/discover.cc.o [ 48%] Building CXX object sql/CMakeFiles/sql.dir/field.cc.o /usr/source/mysql-5.6.25/sql/field.cc: In member function `virtual void Field_string::make_sort_key(uchar*, unsigned int)': /usr/source/mysql-5.6.25/sql/field.cc:6886: warning: unused variable `uint tmp' [ 48%] Building CXX object sql/CMakeFiles/sql.dir/field_conv.cc.o [ 48%] Building CXX object sql/CMakeFiles/sql.dir/filesort.cc.o [ 48%] Building CXX object sql/CMakeFiles/sql.dir/filesort_utils.cc.o /usr/source/mysql-5.6.25/sql/filesort_utils.cc: In function `size_t <unnamed>::try_reserve(std::pair<type*, ptrdiff_t>*, int)': /usr/source/mysql-5.6.25/sql/filesort_utils.cc:178: parse error before `>' token /usr/source/mysql-5.6.25/sql/filesort_utils.cc: In member function `void Filesort_buffer::sort_buffer(const Sort_param*, unsigned int)': /usr/source/mysql-5.6.25/sql/filesort_utils.cc:202: `return_temporary_buffer' undeclared in namespace `std' /usr/source/mysql-5.6.25/sql/filesort_utils.cc: In function `size_t <unnamed>::try_reserve(std::pair<type*, ptrdiff_t>*, int) [with type = uchar*]': /usr/source/mysql-5.6.25/sql/filesort_utils.cc:199: instantiated from here /usr/source/mysql-5.6.25/sql/filesort_utils.cc:181: `return_temporary_buffer' undeclared in namespace `std' gmake[2]: *** [sql/CMakeFiles/sql.dir/filesort_utils.cc.o] Error 1 gmake[1]: *** [sql/CMakeFiles/sql.dir/all] Error 2 gmake: *** [all] Error 2 doctor.nl2k.ab.ca//usr/source/mysql-5.6.25$ exit exit Script done on Wed Jul 15 07:21:55 2015 The code in question is /* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "filesort_utils.h" #include "sql_const.h" #include "sql_sort.h" #include "table.h" #include <stddef.h> #include <algorithm> #include <functional> #include <vector> namespace { /** A local helper function. See comments for get_merge_buffers_cost(). */ double get_merge_cost(ha_rows num_elements, ha_rows num_buffers, uint elem_size) { return 2.0 * ((double) num_elements * elem_size) / IO_SIZE + num_elements * log((double) num_buffers) * ROWID_COMPARE_COST / M_LN2; } } /** This is a simplified, and faster version of @see get_merge_many_buffs_cost(). We calculate the cost of merging buffers, by simulating the actions of @see merge_many_buff. For explanations of formulas below, see comments for get_merge_buffers_cost(). TODO: Use this function for Unique::get_use_cost(). */ double get_merge_many_buffs_cost_fast(ha_rows num_rows, ha_rows num_keys_per_buffer, uint elem_size) { ha_rows num_buffers= num_rows / num_keys_per_buffer; ha_rows last_n_elems= num_rows % num_keys_per_buffer; double total_cost; // 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) ) * ROWID_COMPARE_COST; // Simulate behavior of merge_many_buff(). while (num_buffers >= MERGEBUFF2) { // Calculate # of calls to merge_buffers(). const ha_rows loop_limit= num_buffers - MERGEBUFF*3/2; const ha_rows num_merge_calls= 1 + loop_limit/MERGEBUFF; const ha_rows num_remaining_buffs= num_buffers - num_merge_calls * MERGEBUFF; // Cost of merge sort 'num_merge_calls'. total_cost+= num_merge_calls * get_merge_cost(num_keys_per_buffer * MERGEBUFF, MERGEBUFF, elem_size); // # of records in remaining buffers. last_n_elems+= num_remaining_buffs * num_keys_per_buffer; // Cost of merge sort of remaining buffers. total_cost+= get_merge_cost(last_n_elems, 1 + num_remaining_buffs, elem_size); num_buffers= num_merge_calls; num_keys_per_buffer*= MERGEBUFF; } // Simulate final merge_buff call. last_n_elems+= num_keys_per_buffer * num_buffers; total_cost+= get_merge_cost(last_n_elems, 1 + num_buffers, elem_size); return total_cost; } uchar **Filesort_buffer::alloc_sort_buffer(uint num_records, uint record_length) { DBUG_ENTER("alloc_sort_buffer"); DBUG_EXECUTE_IF("alloc_sort_buffer_fail", DBUG_SET("+d,simulate_out_of_memory");); /* For subqueries we try to re-use the buffer, in order to save expensive malloc/free calls. Both of the sizing parameters may change: - num_records due to e.g. different statistics from the engine. - record_length due to different buffer usage: a heap table may be flushed to myisam, which allows us to sort by <key, addon fields> rather than <key, rowid> If we already have a buffer, but with wrong size, we simply delete it. */ if (!m_idx_array.is_null()) { if (num_records != m_idx_array.size() || record_length != m_record_length) free_sort_buffer(); } if (m_idx_array.is_null()) { uchar **sort_keys= (uchar**) my_malloc(num_records * (record_length + sizeof(uchar*)), MYF(0)); m_idx_array= Idx_array(sort_keys, num_records); m_record_length= record_length; uchar **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()); } void Filesort_buffer::free_sort_buffer() { my_free(m_idx_array.array()); m_idx_array= Idx_array(); m_record_length= 0; m_start_of_data= NULL; } namespace { /* An inline function which does memcmp(). This one turns out to be pretty fast on all platforms, except sparc. See the accompanying unit tests, which measure various implementations. */ inline bool my_mem_compare(const uchar *s1, const uchar *s2, size_t len) { DBUG_ASSERT(len > 0); DBUG_ASSERT(s1 != NULL); DBUG_ASSERT(s2 != NULL); do { if (*s1++ != *s2++) return *--s1 < *--s2; } while (--len != 0); return false; } class Mem_compare : public std::binary_function<const uchar*, const uchar*, bool> { public: Mem_compare(size_t n) : m_size(n) {} bool operator()(const uchar *s1, const uchar *s2) const { #ifdef __sun // Usually faster on SUN, see comment for native_compare() return memcmp(s1, s2, m_size) < 0; #else return my_mem_compare(s1, s2, m_size);
Subscribe to:
Post Comments (Atom)
|
No comments:
Post a Comment