My Project
merge_sort.h
Go to the documentation of this file.
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 */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines