My Project
bounded_queue.h
00001 /* Copyright (c) 2010, 2011, 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 Street, Fifth Floor, Boston, MA 02110-1301, USA */
00015 
00016 #ifndef BOUNDED_QUEUE_INCLUDED
00017 #define BOUNDED_QUEUE_INCLUDED
00018 
00019 #include <string.h>
00020 #include "my_global.h"
00021 #include "my_base.h"
00022 #include "my_sys.h"
00023 #include "queues.h"
00024 
00025 class Sort_param;
00026 
00041 template<typename Element_type, typename Key_type>
00042 class Bounded_queue
00043 {
00044 public:
00045   Bounded_queue()
00046   {
00047     memset(&m_queue, 0, sizeof(m_queue));
00048   }
00049 
00050   ~Bounded_queue()
00051   {
00052     delete_queue(&m_queue);
00053   }
00054 
00061   typedef void (*keymaker_function)(Sort_param *param,
00062                                     Key_type *to,
00063                                     Element_type *from);
00064 
00073   typedef int (*compare_function)(size_t *n, Key_type **a, Key_type **b);
00074 
00095   int init(ha_rows max_elements, bool max_at_top,
00096            compare_function compare, size_t compare_length,
00097            keymaker_function keymaker, Sort_param *sort_param,
00098            Key_type **sort_keys);
00099 
00107   void push(Element_type *element);
00108 
00118   Key_type **pop()
00119   {
00120     // Don't return the extra element to the client code.
00121     if (queue_is_full((&m_queue)))
00122       queue_remove(&m_queue, 0);
00123     DBUG_ASSERT(m_queue.elements > 0);
00124     if (m_queue.elements == 0)
00125       return NULL;
00126     return reinterpret_cast<Key_type**>(queue_remove(&m_queue, 0));
00127   }
00128 
00132   uint num_elements() const { return m_queue.elements; }
00133 
00137   bool is_initialized() const { return m_queue.max_elements > 0; }
00138 
00139 private:
00140   Key_type         **m_sort_keys;
00141   size_t             m_compare_length;
00142   keymaker_function  m_keymaker;
00143   Sort_param        *m_sort_param;
00144   st_queue           m_queue;
00145 };
00146 
00147 
00148 template<typename Element_type, typename Key_type>
00149 int Bounded_queue<Element_type, Key_type>::init(ha_rows max_elements,
00150                                                 bool max_at_top,
00151                                                 compare_function compare,
00152                                                 size_t compare_length,
00153                                                 keymaker_function keymaker,
00154                                                 Sort_param *sort_param,
00155                                                 Key_type **sort_keys)
00156 {
00157   DBUG_ASSERT(sort_keys != NULL);
00158 
00159   m_sort_keys=      sort_keys;
00160   m_compare_length= compare_length;
00161   m_keymaker=       keymaker;
00162   m_sort_param=     sort_param;
00163   // init_queue() takes an uint, and also does (max_elements + 1)
00164   if (max_elements >= (UINT_MAX - 1))
00165     return 1;
00166   if (compare == NULL)
00167     compare=
00168       reinterpret_cast<compare_function>(get_ptr_compare(compare_length));
00169 
00170   DBUG_EXECUTE_IF("bounded_queue_init_fail",
00171                   DBUG_SET("+d,simulate_out_of_memory"););
00172 
00173   // We allocate space for one extra element, for replace when queue is full.
00174   return init_queue(&m_queue, (uint) max_elements + 1,
00175                     0, max_at_top,
00176                     reinterpret_cast<queue_compare>(compare),
00177                     &m_compare_length);
00178 }
00179 
00180 
00181 template<typename Element_type, typename Key_type>
00182 void Bounded_queue<Element_type, Key_type>::push(Element_type *element)
00183 {
00184   DBUG_ASSERT(is_initialized());
00185   if (queue_is_full((&m_queue)))
00186   {
00187     // Replace top element with new key, and re-order the queue.
00188     Key_type **pq_top= reinterpret_cast<Key_type **>(queue_top(&m_queue));
00189     (*m_keymaker)(m_sort_param, *pq_top, element);
00190     queue_replaced(&m_queue);
00191   } else {
00192     // Insert new key into the queue.
00193     (*m_keymaker)(m_sort_param, m_sort_keys[m_queue.elements], element);
00194     queue_insert(&m_queue,
00195                  reinterpret_cast<uchar*>(&m_sort_keys[m_queue.elements]));
00196   }
00197 }
00198 
00199 #endif  // BOUNDED_QUEUE_INCLUDED
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines