1/* Copyright (c) 2010, 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#ifndef FILESORT_UTILS_INCLUDED
17#define FILESORT_UTILS_INCLUDED
18
19#include "my_base.h"
20#include "sql_array.h"
21
22class Sort_param;
23/*
24 Calculate cost of merge sort
25
26 @param num_rows Total number of rows.
27 @param num_keys_per_buffer Number of keys per buffer.
28 @param elem_size Size of each element.
29
30 Calculates cost of merge sort by simulating call to merge_many_buff().
31
32 @retval
33 Computed cost of merge sort in disk seeks.
34
35 @note
36 Declared here in order to be able to unit test it,
37 since library dependencies have not been sorted out yet.
38
39 See also comments get_merge_many_buffs_cost().
40*/
41
42double get_merge_many_buffs_cost_fast(ha_rows num_rows,
43 ha_rows num_keys_per_buffer,
44 uint elem_size);
45
46
47/**
48 A wrapper class around the buffer used by filesort().
49 The buffer is a contiguous chunk of memory,
50 where the first part is <num_records> pointers to the actual data.
51
52 We wrap the buffer in order to be able to do lazy initialization of the
53 pointers: the buffer is often much larger than what we actually need.
54
55 The buffer must be kept available for multiple executions of the
56 same sort operation, so we have explicit allocate and free functions,
57 rather than doing alloc/free in CTOR/DTOR.
58*/
59class Filesort_buffer
60{
61public:
62 Filesort_buffer()
63 : m_idx_array(), m_start_of_data(NULL), allocated_size(0)
64 {}
65
66 ~Filesort_buffer()
67 {
68 my_free(m_idx_array.array());
69 }
70
71 bool is_allocated()
72 {
73 return m_idx_array.array() != 0;
74 }
75 void reset()
76 {
77 m_idx_array.reset();
78 }
79
80 /** Sort me... */
81 void sort_buffer(const Sort_param *param, uint count);
82
83 /// Initializes a record pointer.
84 uchar *get_record_buffer(uint idx)
85 {
86 m_idx_array[idx]= m_start_of_data + (idx * m_record_length);
87 return m_idx_array[idx];
88 }
89
90 /// Initializes all the record pointers.
91 void init_record_pointers()
92 {
93 for (uint ix= 0; ix < m_idx_array.size(); ++ix)
94 (void) get_record_buffer(ix);
95 }
96
97 /// Returns total size: pointer array + record buffers.
98 size_t sort_buffer_size() const
99 {
100 return allocated_size;
101 }
102
103 /// Allocates the buffer, but does *not* initialize pointers.
104 uchar **alloc_sort_buffer(uint num_records, uint record_length);
105
106 /// Frees the buffer.
107 void free_sort_buffer();
108
109 /// Getter, for calling routines which still use the uchar** interface.
110 uchar **get_sort_keys() { return m_idx_array.array(); }
111
112 /**
113 We need an assignment operator, see filesort().
114 This happens to have the same semantics as the one that would be
115 generated by the compiler. We still implement it here, to show shallow
116 assignment explicitly: we have two objects sharing the same array.
117 */
118 Filesort_buffer &operator=(const Filesort_buffer &rhs)
119 {
120 m_idx_array= rhs.m_idx_array;
121 m_record_length= rhs.m_record_length;
122 m_start_of_data= rhs.m_start_of_data;
123 allocated_size= rhs.allocated_size;
124 return *this;
125 }
126
127private:
128 typedef Bounds_checked_array<uchar*> Idx_array;
129
130 Idx_array m_idx_array; /* Pointers to key data */
131 uint m_record_length;
132 uchar *m_start_of_data; /* Start of key data */
133 size_t allocated_size;
134};
135
136#endif // FILESORT_UTILS_INCLUDED
137