forked from mysql/mysql-server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbounded_queue.h
124 lines (103 loc) · 4.02 KB
/
bounded_queue.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
#ifndef BOUNDED_QUEUE_INCLUDED
#define BOUNDED_QUEUE_INCLUDED
#include "my_global.h"
#include "my_base.h"
#include "my_sys.h"
#include "mysys_err.h"
#include "priority_queue.h"
#include "malloc_allocator.h"
/**
A priority queue with a fixed, limited size.
This is a wrapper on top of Priority_queue.
It keeps the top-N elements which are inserted.
Elements of type Element_type are pushed into the queue.
For each element, we call a user-supplied Key_generator::make_sortkey(),
to generate a key of type Key_type for the element.
Instances of Key_type are compared with the user-supplied Key_compare.
Pointers to the top-N elements are stored in the sort_keys array given
to the init() function below. To access elements in sorted order,
sort the array and access it sequentially.
*/
template<typename Element_type,
typename Key_type,
typename Key_generator,
typename Key_compare = std::less<Key_type>
>
class Bounded_queue
{
public:
typedef Priority_queue<Key_type,
std::vector<Key_type, Malloc_allocator<Key_type> >,
Key_compare> Queue_type;
typedef typename Queue_type::allocator_type allocator_type;
explicit Bounded_queue(const allocator_type
&alloc = allocator_type(PSI_NOT_INSTRUMENTED))
: m_queue(Key_compare(), alloc),
m_sort_keys(NULL),
m_sort_param(NULL)
{}
/**
Initialize the queue.
@param max_elements The size of the queue.
@param sort_param Sort parameters. We call sort_param->make_sortkey()
to generate keys for elements.
@param[in,out] sort_keys Array of keys to sort.
Must be initialized by caller.
Will be filled with pointers to the top-N elements.
@retval false OK, true Could not allocate memory.
We do *not* take ownership of any of the input pointer arguments.
*/
bool init(ha_rows max_elements,
Key_generator *sort_param,
Key_type *sort_keys)
{
m_sort_keys= sort_keys;
m_sort_param= sort_param;
DBUG_EXECUTE_IF("bounded_queue_init_fail",
my_error(EE_OUTOFMEMORY, MYF(ME_FATALERROR), 42);
return true;);
// We allocate space for one extra element, for replace when queue is full.
if (m_queue.reserve(max_elements + 1))
return true;
m_queue.m_compare_length= sort_param->compare_length();
return false;
}
/**
Pushes an element on the queue.
If the queue is already full, we discard one element.
Calls m_sort_param::make_sortkey() to generate a key for the element.
@param element The element to be pushed.
*/
void push(Element_type element)
{
if (m_queue.size() == m_queue.capacity())
{
const Key_type &pq_top= m_queue.top();
m_sort_param->make_sortkey(pq_top, element);
m_queue.update_top();
} else {
m_sort_param->make_sortkey(m_sort_keys[m_queue.size()], element);
m_queue.push(m_sort_keys[m_queue.size()]);
}
}
/**
The number of elements in the queue.
*/
size_t num_elements() const { return m_queue.size(); }
private:
Queue_type m_queue;
Key_type *m_sort_keys;
Key_generator *m_sort_param;
};
#endif // BOUNDED_QUEUE_INCLUDED