-
Notifications
You must be signed in to change notification settings - Fork 4k
/
Copy pathrecord_buffer.h
158 lines (135 loc) · 5.53 KB
/
record_buffer.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#ifndef RECORD_BUFFER_INCLUDED
#define RECORD_BUFFER_INCLUDED
/*
Copyright (c) 2016, 2024, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is designed to work with certain software (including
but not limited to OpenSSL) that is licensed under separate terms,
as designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have either included with
the program or referenced in the documentation.
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, version 2.0, 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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <assert.h>
#include "my_base.h" // ha_rows
/**
This class represents a buffer that can be used for multi-row reads. It is
allocated by the executor and given to the storage engine through the
handler, using handler::ha_set_record_buffer(), so that the storage engine
can fill the buffer with multiple rows in a single read call.
For now, the record buffer is only used internally by the storage engine as
a prefetch cache. The storage engine fills the record buffer when the
executor requests the first record, but it returns a single record only to
the executor. If the executor wants to access the records in the buffer, it
has to call a handler function such as handler::ha_index_next() or
handler::ha_rnd_next(). Then the storage engine will copy the next record
from the record buffer to the memory area specified in the arguments of the
handler function, typically TABLE::record[0].
*/
class Record_buffer {
/// The maximum number of records that can be stored in the buffer.
ha_rows m_max_records;
/// The number of bytes available for each record.
size_t m_record_size;
/// The number of records currently stored in the buffer.
ha_rows m_count = 0;
/// The @c uchar buffer that holds the records.
uchar *m_buffer;
/// Tells if end-of-range was found while filling the buffer.
bool m_out_of_range = false;
public:
/**
Create a new record buffer with the specified size.
@param records the number of records that can be stored in the buffer
@param record_size the size of each record
@param buffer the @c uchar buffer that will hold the records (its
size should be at least
`Record_buffer::buffer_size(records, record_size)`)
*/
Record_buffer(ha_rows records, size_t record_size, uchar *buffer)
: m_max_records(records), m_record_size(record_size), m_buffer(buffer) {}
/**
This function calculates how big the @c uchar buffer provided to
Record_buffer's constructor must be, given a number of records and
the record size.
@param records the maximum number of records in the buffer
@param record_size the size of each record
@return the total number of bytes needed for all the records
*/
static constexpr size_t buffer_size(ha_rows records, size_t record_size) {
return static_cast<size_t>(records * record_size);
}
/**
Get the number of records that can be stored in the buffer.
@return the maximum number of records in the buffer
*/
ha_rows max_records() const { return m_max_records; }
/**
Get the amount of space allocated for each record in the buffer.
@return the record size
*/
size_t record_size() const { return m_record_size; }
/**
Get the number of records currently stored in the buffer.
@return the number of records stored in the buffer
*/
ha_rows records() const { return m_count; }
/**
Get the buffer that holds the record on position @a pos.
@param pos the record number (must be smaller than records())
@return the @c uchar buffer that holds the specified record
*/
uchar *record(ha_rows pos) const {
assert(pos < max_records());
return m_buffer + m_record_size * pos;
}
/**
Add a new record at the end of the buffer.
@return the @c uchar buffer of the added record
*/
uchar *add_record() {
assert(m_count < max_records());
return record(m_count++);
}
/**
Remove the record that was last added to the buffer.
*/
void remove_last() {
assert(m_count > 0);
--m_count;
}
/**
Clear the buffer. Remove all the records. The end-of-range flag is
preserved.
*/
void clear() { m_count = 0; }
/**
Reset the buffer. Remove all records and clear the end-of-range flag.
*/
void reset() {
m_count = 0;
set_out_of_range(false);
}
/**
Set whether the end of the range was reached while filling the buffer.
@param val true if end of range was reached, false if still within range
*/
void set_out_of_range(bool val) { m_out_of_range = val; }
/**
Check if the end of the range was reached while filling the buffer.
@retval true if the end range was reached
@retval false if the scan is still within the range
*/
bool is_out_of_range() const { return m_out_of_range; }
};
#endif /* RECORD_BUFFER_INCLUDED */