MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
bounded_queue.h
1 /* Copyright (c) 2010, 2011, 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 Street, Fifth Floor, Boston, MA 02110-1301, USA */
15 
16 #ifndef BOUNDED_QUEUE_INCLUDED
17 #define BOUNDED_QUEUE_INCLUDED
18 
19 #include <string.h>
20 #include "my_global.h"
21 #include "my_base.h"
22 #include "my_sys.h"
23 #include "queues.h"
24 
25 class Sort_param;
26 
41 template<typename Element_type, typename Key_type>
43 {
44 public:
46  {
47  memset(&m_queue, 0, sizeof(m_queue));
48  }
49 
50  ~Bounded_queue()
51  {
52  delete_queue(&m_queue);
53  }
54 
61  typedef void (*keymaker_function)(Sort_param *param,
62  Key_type *to,
63  Element_type *from);
64 
73  typedef int (*compare_function)(size_t *n, Key_type **a, Key_type **b);
74 
95  int init(ha_rows max_elements, bool max_at_top,
96  compare_function compare, size_t compare_length,
97  keymaker_function keymaker, Sort_param *sort_param,
98  Key_type **sort_keys);
99 
107  void push(Element_type *element);
108 
118  Key_type **pop()
119  {
120  // Don't return the extra element to the client code.
121  if (queue_is_full((&m_queue)))
122  queue_remove(&m_queue, 0);
123  DBUG_ASSERT(m_queue.elements > 0);
124  if (m_queue.elements == 0)
125  return NULL;
126  return reinterpret_cast<Key_type**>(queue_remove(&m_queue, 0));
127  }
128 
132  uint num_elements() const { return m_queue.elements; }
133 
137  bool is_initialized() const { return m_queue.max_elements > 0; }
138 
139 private:
140  Key_type **m_sort_keys;
141  size_t m_compare_length;
142  keymaker_function m_keymaker;
143  Sort_param *m_sort_param;
144  st_queue m_queue;
145 };
146 
147 
148 template<typename Element_type, typename Key_type>
150  bool max_at_top,
151  compare_function compare,
152  size_t compare_length,
153  keymaker_function keymaker,
154  Sort_param *sort_param,
155  Key_type **sort_keys)
156 {
157  DBUG_ASSERT(sort_keys != NULL);
158 
159  m_sort_keys= sort_keys;
160  m_compare_length= compare_length;
161  m_keymaker= keymaker;
162  m_sort_param= sort_param;
163  // init_queue() takes an uint, and also does (max_elements + 1)
164  if (max_elements >= (UINT_MAX - 1))
165  return 1;
166  if (compare == NULL)
167  compare=
168  reinterpret_cast<compare_function>(get_ptr_compare(compare_length));
169 
170  DBUG_EXECUTE_IF("bounded_queue_init_fail",
171  DBUG_SET("+d,simulate_out_of_memory"););
172 
173  // We allocate space for one extra element, for replace when queue is full.
174  return init_queue(&m_queue, (uint) max_elements + 1,
175  0, max_at_top,
176  reinterpret_cast<queue_compare>(compare),
177  &m_compare_length);
178 }
179 
180 
181 template<typename Element_type, typename Key_type>
183 {
184  DBUG_ASSERT(is_initialized());
185  if (queue_is_full((&m_queue)))
186  {
187  // Replace top element with new key, and re-order the queue.
188  Key_type **pq_top= reinterpret_cast<Key_type **>(queue_top(&m_queue));
189  (*m_keymaker)(m_sort_param, *pq_top, element);
190  queue_replaced(&m_queue);
191  } else {
192  // Insert new key into the queue.
193  (*m_keymaker)(m_sort_param, m_sort_keys[m_queue.elements], element);
194  queue_insert(&m_queue,
195  reinterpret_cast<uchar*>(&m_sort_keys[m_queue.elements]));
196  }
197 }
198 
199 #endif // BOUNDED_QUEUE_INCLUDED