MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
merge_sort.h
Go to the documentation of this file.
1 /* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15 */
16 
17 #ifndef MERGE_SORT_INCLUDED
18 #define MERGE_SORT_INCLUDED
19 
40 #include "sql_select.h"
41 #include <queue>
42 
61 template<typename Element_type, typename Comp_func>
62 void insert_sort(Element_type **first, Element_type **last, Comp_func comp)
63 {
64  for (Element_type **high_water_mark= first+1;
65  high_water_mark < last;
66  high_water_mark++)
67  {
68  for (Element_type **cur= high_water_mark; cur > first ; cur--)
69  {
70  if (comp(*(cur-1), *cur))
71  break;
72 
73  Element_type *tmp= *(cur-1);
74  *(cur-1)= *cur;
75  *cur= tmp;
76  }
77  }
78 }
79 
80 
99 template<typename Element_type, typename Comp_func>
100 void merge_sort(Element_type **first, Element_type **last, Comp_func comp)
101 {
102  const uint elements= last - first;
103 
104  /*
105  Tests showed that the value 5 was a good number for JOIN_TAB
106  ordering, which is the primary use case for this function
107  */
108  if (elements < 5)
109  {
110  insert_sort(first, last, comp);
111  return;
112  }
113  Element_type **middle= first + (elements)/2;
114 
115  merge_sort (first, middle, comp);
116  merge_sort (middle, last, comp);
117 
118  std::queue<Element_type *> merged;
119 
120  Element_type **cur1= first;
121  Element_type **cur2= middle;
122 
123  for (uint i= 0; i < elements; i++)
124  {
125  DBUG_ASSERT (cur1 < middle || cur2 < last);
126 
127  if (cur1 == middle)
128  merged.push(*cur2++);
129  else if (cur2 == last)
130  merged.push(*cur1++);
131  else if (comp(*cur1, *cur2))
132  merged.push(*cur1++);
133  else
134  merged.push(*cur2++);
135  }
136 
137  Element_type **result= first;
138  while (!merged.empty())
139  {
140  *result++= merged.front();
141  merged.pop();
142  }
143 }
144 
145 #endif /* MERGE_SORT_INCLUDED */