My Project
|
00001 /* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; version 2 of the License. 00006 00007 This program is distributed in the hope that it will be useful, 00008 but WITHOUT ANY WARRANTY; without even the implied warranty of 00009 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00010 GNU General Public License for more details. 00011 00012 You should have received a copy of the GNU General Public License 00013 along with this program; if not, write to the Free Software 00014 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00015 */ 00016 00017 #ifndef MERGE_SORT_INCLUDED 00018 #define MERGE_SORT_INCLUDED 00019 00040 #include "sql_select.h" 00041 #include <queue> 00042 00061 template<typename Element_type, typename Comp_func> 00062 void insert_sort(Element_type **first, Element_type **last, Comp_func comp) 00063 { 00064 for (Element_type **high_water_mark= first+1; 00065 high_water_mark < last; 00066 high_water_mark++) 00067 { 00068 for (Element_type **cur= high_water_mark; cur > first ; cur--) 00069 { 00070 if (comp(*(cur-1), *cur)) 00071 break; 00072 00073 Element_type *tmp= *(cur-1); 00074 *(cur-1)= *cur; 00075 *cur= tmp; 00076 } 00077 } 00078 } 00079 00080 00099 template<typename Element_type, typename Comp_func> 00100 void merge_sort(Element_type **first, Element_type **last, Comp_func comp) 00101 { 00102 const uint elements= last - first; 00103 00104 /* 00105 Tests showed that the value 5 was a good number for JOIN_TAB 00106 ordering, which is the primary use case for this function 00107 */ 00108 if (elements < 5) 00109 { 00110 insert_sort(first, last, comp); 00111 return; 00112 } 00113 Element_type **middle= first + (elements)/2; 00114 00115 merge_sort (first, middle, comp); 00116 merge_sort (middle, last, comp); 00117 00118 std::queue<Element_type *> merged; 00119 00120 Element_type **cur1= first; 00121 Element_type **cur2= middle; 00122 00123 for (uint i= 0; i < elements; i++) 00124 { 00125 DBUG_ASSERT (cur1 < middle || cur2 < last); 00126 00127 if (cur1 == middle) 00128 merged.push(*cur2++); 00129 else if (cur2 == last) 00130 merged.push(*cur1++); 00131 else if (comp(*cur1, *cur2)) 00132 merged.push(*cur1++); 00133 else 00134 merged.push(*cur2++); 00135 } 00136 00137 Element_type **result= first; 00138 while (!merged.empty()) 00139 { 00140 *result++= merged.front(); 00141 merged.pop(); 00142 } 00143 } 00144 00145 #endif /* MERGE_SORT_INCLUDED */