MySQL 8.0.39
Source Code Documentation
compressor.h
Go to the documentation of this file.
1/* Copyright (c) 2019, 2024, Oracle and/or its affiliates.
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, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef LIBBINLOGEVENTS_COMPRESSION_COMPRESSOR_H_INCLUDED
25#define LIBBINLOGEVENTS_COMPRESSION_COMPRESSOR_H_INCLUDED
26
27#include <tuple>
28#include "base.h" // type
29#include "libbinlogevents/include/buffer/grow_constraint.h" // Grow_constraint
30#include "libbinlogevents/include/buffer/managed_buffer_sequence.h" // Managed_buffer_sequence
31#include "libbinlogevents/include/nodiscard.h" // NODISCARD
32
33#include <limits> // std::numeric_limits
34
36
38
39/// Abstract base class for compressors.
40///
41/// Each subclass normally corresponds to a compression algorithm, and
42/// maintains the algorithm-specific state for it.
43///
44/// An instance of this class can be reused to compress several
45/// *frames*. A frame is a self-contained segment of data, in the
46/// sense that it can be decompressed without knowing about other
47/// frames, and compression does not take advantage of patterns that
48/// repeat between frames.
49///
50/// Input for a frame can be provided in pieces. All pieces for a
51/// frame will be compressed together; the decompressor will take
52/// advantage of patterns across in different pieces within the frame.
53/// Providing a frame in pieces is useful when not all input is known
54/// at once.
55///
56/// To compress one frame, use the API as follows:
57///
58/// 1. Repeat as many times as needed:
59/// 1.1. Call @c feed to provide a piece of input.
60/// 1.2. Call @c compress to consume the piece of input and possibly
61/// produce a prefix of the output.
62/// 2. Choose one of the following:
63/// 2.1. Call @c finish to produce the remainder of the output for this
64/// frame.
65/// 2.2. Call @c reset to abort this frame.
66///
67/// @note After 1.2, although the compression library has read all
68/// input given so far, it may not have produced all corresponding
69/// output. It usually holds some data in internal buffers, since it
70/// may be more compressible when more data has been given. Therefore,
71/// step 2.1 is always necessary in order to complete the frame.
72///
73/// @note To reuse the compressor object for another input, repeat the
74/// above procedure as many times as needed.
75///
76/// This class requires that the user provides a @c
77/// mysqlns::buffer::Managed_buffer_sequence to store output.
79 public:
85 std::numeric_limits<Size_t>::max();
86
87 Compressor() = default;
88 Compressor(const Compressor &other) = delete;
89 Compressor(Compressor &&other) = delete;
90 Compressor &operator=(const Compressor &other) = delete;
91 Compressor &operator=(Compressor &&other) = delete;
92
93 virtual ~Compressor() = default;
94
95 /// @return the compression type.
96 type get_type_code() const;
97
98 /// Reset the frame.
99 ///
100 /// This cancels the current frame and starts a new one.
101 ///
102 /// This is allowed but unnecessary if the current frame has been
103 /// reset by @c finish or by an out_of_memory error from @c
104 /// compress.
105 void reset();
106
107 /// Submit data to be compressed.
108 ///
109 /// This will not consume any of the input; it should be followed by
110 /// a call to @c compress or @c finish.
111 ///
112 /// @note This object will not copy the input; the caller must
113 /// ensure that the input lives until it has been consumed or the
114 /// frame has been reset.
115 ///
116 /// @note Must not be called when there is still non-consumed input
117 /// left after a previous call to @c feed.
118 ///
119 /// @param input_data Data to be compressed. This object will keep a
120 /// shallow copy of the data and use it in subsequent calls to @c
121 /// compress or @c finish.
122 ///
123 /// @param input_size Size of data to be compressed.
124 template <class Input_char_t>
125 void feed(const Input_char_t *input_data, Size_t input_size) {
126 feed_char_t(reinterpret_cast<const Char_t *>(input_data), input_size);
127 }
128
129 /// Consume all input previously given in the feed function.
130 ///
131 /// This will consume the input, but may not produce all output;
132 /// there may be output still in compression library buffers. Use
133 /// the @c finish function to flush the output and end the frame.
134 ///
135 /// @param out Storage for compressed bytes. This may grow, if
136 /// needed.
137 ///
138 /// @retval success All input was consumed.
139 ///
140 /// @retval out_of_memory The operation failed due to an out of
141 /// memory error. The frame has been reset.
142 ///
143 /// @retval exceeds_max_size The @c out buffer was already at its
144 /// max capacity, and filled, and there were more bytes left to
145 /// produce. The frame has not been reset and it is not guaranteed
146 /// that all input has been consumed. The caller may resume
147 /// compression e.g. after increasing the capacity, or resetting
148 /// the output buffer (perhaps after moving existing data
149 /// elsewhere), or using a different output buffer, or similar.
151
152 /// Consume all input, produce all output, and end the frame.
153 ///
154 /// This will consume all input previously given by @c feed (it
155 /// internally calls @c compress). Then it ends the frame and
156 /// flushes the output, ensuring that all data that may reside in
157 /// the compression library's internal buffers gets compressed and
158 /// written to the output.
159 ///
160 /// The next call to @c feed will start a new frame.
161 ///
162 /// @param out Storage for compressed bytes. This may grow, if
163 /// needed.
164 ///
165 /// @retval success All input was consumed, all output was produced,
166 /// and the frame was reset.
167 ///
168 /// @retval out_of_memory The operation failed due to an out of
169 /// memory error, and the frame has been reset.
170 ///
171 /// @retval exceeds_max_size The @c out buffer was already at its
172 /// max capacity, and filled, and there were more bytes left to
173 /// produce. The frame has not been reset and it is not guaranteed
174 /// that all input has been consumed. The caller may resume
175 /// compression e.g. after increasing the capacity, or resetting
176 /// the output buffer (perhaps after moving existing data
177 /// elsewhere), or using a different output buffer, or similar.
179
180 /// Return a `Grow_constraint` that may be used with the
181 /// Managed_buffer_sequence storing the output, in order to
182 /// optimize memory usage for a particular compression algorithm.
183 ///
184 /// This may be implemented by subclasses such that it depends on
185 /// the pledged input size. Therefore, for the most optimal grow
186 /// constraint, call this after set_pledged_input_size.
188
189 /// Declare that the input size will be exactly as given.
190 ///
191 /// This may allow compressors and decompressors to use memory more
192 /// efficiently.
193 ///
194 /// This function may only be called if `feed` has never been
195 /// called, or if the compressor has been reset since the last call
196 /// to `feed`. The pledged size will be set back to
197 /// pledged_input_size_unset next time this compressor is reset.
198 ///
199 /// It is required that the total number of bytes passed to `feed`
200 /// before the call to `finish` matches the pledged number.
201 /// Otherwise, the behavior of `finish` is undefined.
203
204 /// Return the size previously provided to `set_pledged_input_size`,
205 /// or `pledged_input_size_unset` if no pledged size has been set.
207
208 private:
209 /// Worker function for @c feed, requiring the correct Char_t type.
210 ///
211 /// @see feed.
212 void feed_char_t(const Char_t *input_data, Size_t input_size);
213
214 /// implement @c get_type_code.
215 virtual type do_get_type_code() const = 0;
216
217 /// Implement @c reset.
218 virtual void do_reset() = 0;
219
220 /// Implement @c feed.
221 ///
222 /// This differs from @c feed in that it does not have to reset the
223 /// frame when returning out_of_memory; the caller does that.
224 virtual void do_feed(const Char_t *input_data, Size_t input_size) = 0;
225
226 /// Implement @c compress.
227 ///
228 /// This differs from @c compress in that it does not have to reset
229 /// the frame when returning out_of_memory; the caller does that.
232
233 /// Implement @c finish.
234 ///
235 /// This differs from @c finish in that it does not have to reset
236 /// the frame when returning out_of_memory; the caller does that.
237 ///
238 /// Implementations may assume that @c compress has been called,
239 /// since @c finish does that.
242
243 /// Implement @c get_grow_constraint_hint.
244 ///
245 /// In this base class, the function returns a default-constructed
246 /// Grow_constraint, i.e., one which does not limit the
247 /// Grow_calculator.
249
250 /// Implement @c set_pledged_input_size
251 ///
252 /// By default, this does nothing.
253 virtual void do_set_pledged_input_size([[maybe_unused]] Size_t size);
254
255 /// True when user has provided input that has not yet been consumed.
256 bool m_pending_input = false;
257
258 /// True when user has not provided any input since the last reset.
259 bool m_empty = true;
260
261 /// The number of bytes
263};
264
265} // namespace binary_log::transaction::compression
266
267#endif // ifndef LIBBINLOGEVENTS_COMPRESSION_COMPRESSOR_H_INCLUDED
Abstract base class for compressors.
Definition: compressor.h:78
void feed(const Input_char_t *input_data, Size_t input_size)
Submit data to be compressed.
Definition: compressor.h:125
virtual Grow_constraint_t do_get_grow_constraint_hint() const
Implement get_grow_constraint_hint.
Definition: compressor.cpp:75
Grow_constraint_t get_grow_constraint_hint() const
Return a Grow_constraint that may be used with the Managed_buffer_sequence storing the output,...
Definition: compressor.cpp:71
void set_pledged_input_size(Size_t size)
Declare that the input size will be exactly as given.
Definition: compressor.cpp:79
bool m_empty
True when user has not provided any input since the last reset.
Definition: compressor.h:259
virtual Compress_status do_finish(Managed_buffer_sequence_t &out)=0
Implement finish.
Size_t m_pledged_input_size
The number of bytes.
Definition: compressor.h:262
virtual type do_get_type_code() const =0
implement get_type_code.
Managed_buffer_sequence_t::Size_t Size_t
Definition: compressor.h:82
virtual void do_set_pledged_input_size(Size_t size)
Implement set_pledged_input_size.
Definition: compressor.cpp:89
void reset()
Reset the frame.
Definition: compressor.cpp:30
mysqlns::buffer::Grow_constraint Grow_constraint_t
Definition: compressor.h:83
Compress_status compress(Managed_buffer_sequence_t &out)
Consume all input previously given in the feed function.
Definition: compressor.cpp:47
virtual Compress_status do_compress(Managed_buffer_sequence_t &out)=0
Implement compress.
Compress_status finish(Managed_buffer_sequence_t &out)
Consume all input, produce all output, and end the frame.
Definition: compressor.cpp:56
mysqlns::buffer::Managed_buffer_sequence<> Managed_buffer_sequence_t
Definition: compressor.h:80
bool m_pending_input
True when user has provided input that has not yet been consumed.
Definition: compressor.h:256
Compressor & operator=(Compressor &&other)=delete
static constexpr Size_t pledged_input_size_unset
Definition: compressor.h:84
virtual void do_feed(const Char_t *input_data, Size_t input_size)=0
Implement feed.
type get_type_code() const
Definition: compressor.cpp:28
Compressor(const Compressor &other)=delete
Compressor & operator=(const Compressor &other)=delete
void feed_char_t(const Char_t *input_data, Size_t input_size)
Worker function for feed, requiring the correct Char_t type.
Definition: compressor.cpp:38
Size_t get_pledged_input_size() const
Return the size previously provided to set_pledged_input_size, or pledged_input_size_unset if no pled...
Definition: compressor.cpp:85
virtual void do_reset()=0
Implement reset.
Managed_buffer_sequence_t::Char_t Char_t
Definition: compressor.h:81
Description of a heuristic to determine how much memory to allocate.
Definition: grow_constraint.h:67
Owned, non-contiguous, growable memory buffer.
Definition: managed_buffer_sequence.h:114
typename Buffer_sequence_view_t::Char_t Char_t
Definition: rw_buffer_sequence.h:109
typename Buffer_sequence_view_t::Size_t Size_t
Definition: rw_buffer_sequence.h:110
Container class that provides a sequence of buffers to the caller.
Grow_status
Error statuses for classes that use Grow_calculator.
Definition: grow_status.h:37
#define NODISCARD
The function attribute [[NODISCARD]] is a replacement for [[nodiscard]] to workaround a gcc bug.
Definition: nodiscard.h:47