1 /*****************************************************************************
2
3 Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
4 Copyright (c) 2019, 2020, MariaDB Corporation.
5
6 This program is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free Software
print_task_type(int id)8 Foundation; version 2 of the License.
9
10 This program is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
17
18 *****************************************************************************/
19
20 /******************************************************************//**
21 @file include/ut0ut.h
22 Various utilities
23
24 Created 1/20/1994 Heikki Tuuri
25 ***********************************************************************/
26
27 #ifndef ut0ut_h
28 #define ut0ut_h
29
30 /* Do not include univ.i because univ.i includes this. */
31
32 #include <ostream>
33 #include <sstream>
34 #include <string.h>
35
36 #ifndef UNIV_INNOCHECKSUM
37
38 #include "db0err.h"
39
40 #include <time.h>
41
42 #ifndef MYSQL_SERVER
43 #include <ctype.h>
44 #endif /* MYSQL_SERVER */
45
46 #include <stdarg.h>
47
48 #include <string>
49 #include <my_atomic.h>
50
51 /** Index name prefix in fast index creation, as a string constant */
52 #define TEMP_INDEX_PREFIX_STR "\377"
53
54 #define ut_max std::max
55 #define ut_min std::min
56
57 /** Calculate the minimum of two pairs.
58 @param[out] min_hi MSB of the minimum pair
59 @param[out] min_lo LSB of the minimum pair
60 @param[in] a_hi MSB of the first pair
61 @param[in] a_lo LSB of the first pair
62 @param[in] b_hi MSB of the second pair
63 @param[in] b_lo LSB of the second pair */
64 UNIV_INLINE
65 void
66 ut_pair_min(
67 ulint* min_hi,
68 ulint* min_lo,
69 ulint a_hi,
70 ulint a_lo,
71 ulint b_hi,
72 ulint b_lo);
73 /******************************************************//**
74 Compares two ulints.
75 @return 1 if a > b, 0 if a == b, -1 if a < b */
76 UNIV_INLINE
77 int
78 ut_ulint_cmp(
79 /*=========*/
80 ulint a, /*!< in: ulint */
81 ulint b); /*!< in: ulint */
82 /** Compare two pairs of integers.
83 @param[in] a_h more significant part of first pair
84 @param[in] a_l less significant part of first pair
85 @param[in] b_h more significant part of second pair
86 @param[in] b_l less significant part of second pair
87 @return comparison result of (a_h,a_l) and (b_h,b_l)
88 @retval -1 if (a_h,a_l) is less than (b_h,b_l)
89 @retval 0 if (a_h,a_l) is equal to (b_h,b_l)
90 @retval 1 if (a_h,a_l) is greater than (b_h,b_l) */
91 UNIV_INLINE
92 int
93 ut_pair_cmp(
94 ulint a_h,
95 ulint a_l,
96 ulint b_h,
97 ulint b_l)
98 MY_ATTRIBUTE((warn_unused_result));
99
100 /*************************************************************//**
101 Calculates fast the remainder of n/m when m is a power of two.
102 @param n in: numerator
103 @param m in: denominator, must be a power of two
104 @return the remainder of n/m */
105 template <typename T> inline T ut_2pow_remainder(T n, T m){return n & (m - 1);}
106 /*************************************************************//**
107 Calculates the biggest multiple of m that is not bigger than n
108 when m is a power of two. In other words, rounds n down to m * k.
109 @param n in: number to round down
110 @param m in: alignment, must be a power of two
111 @return n rounded down to the biggest possible integer multiple of m */
112 template <typename T> inline T ut_2pow_round(T n, T m) { return n & ~(m - 1); }
113 /********************************************************//**
114 Calculates the smallest multiple of m that is not smaller than n
115 when m is a power of two. In other words, rounds n up to m * k.
116 @param n in: number to round up
117 @param m in: alignment, must be a power of two
118 @return n rounded up to the smallest possible integer multiple of m */
119 #define UT_CALC_ALIGN(n, m) ((n + m - 1) & ~(m - 1))
120 template <typename T> inline T ut_calc_align(T n, T m)
121 { return UT_CALC_ALIGN(n, m); }
122
123 /*************************************************************//**
124 Calculates fast the 2-logarithm of a number, rounded upward to an
125 integer.
126 @return logarithm in the base 2, rounded upward */
127 UNIV_INLINE
128 ulint
129 ut_2_log(
130 /*=====*/
131 ulint n); /*!< in: number */
132 /*************************************************************//**
133 Calculates 2 to power n.
134 @return 2 to power n */
135 UNIV_INLINE
136 ulint
137 ut_2_exp(
138 /*=====*/
139 ulint n); /*!< in: number */
140 /*************************************************************//**
141 Calculates fast the number rounded up to the nearest power of 2.
142 @return first power of 2 which is >= n */
143 ulint
144 ut_2_power_up(
145 /*==========*/
146 ulint n) /*!< in: number != 0 */
147 MY_ATTRIBUTE((const));
148
149 /** Determine how many bytes (groups of 8 bits) are needed to
150 store the given number of bits.
151 @param b in: bits
152 @return number of bytes (octets) needed to represent b */
153 #define UT_BITS_IN_BYTES(b) (((b) + 7) / 8)
154
155 /**********************************************************//**
156 Returns the number of milliseconds since some epoch. The
157 value may wrap around. It should only be used for heuristic
158 purposes.
159 @return ms since epoch */
160 ulint
161 ut_time_ms(void);
162 /*============*/
163 #endif /* !UNIV_INNOCHECKSUM */
164
165 /** Determines if a number is zero or a power of two.
166 @param[in] n number
167 @return nonzero if n is zero or a power of two; zero otherwise */
168 #define ut_is_2pow(n) UNIV_LIKELY(!((n) & ((n) - 1)))
169
170 /** Functor that compares two C strings. Can be used as a comparator for
171 e.g. std::map that uses char* as keys. */
172 struct ut_strcmp_functor
173 {
174 bool operator()(
175 const char* a,
176 const char* b) const
177 {
178 return(strcmp(a, b) < 0);
179 }
180 };
181
182 /**********************************************************//**
183 Prints a timestamp to a file. */
184 void
185 ut_print_timestamp(
186 /*===============*/
187 FILE* file) /*!< in: file where to print */
188 ATTRIBUTE_COLD __attribute__((nonnull));
189
190 #ifndef UNIV_INNOCHECKSUM
191
192 /**********************************************************//**
193 Sprintfs a timestamp to a buffer, 13..14 chars plus terminating NUL. */
194 void
195 ut_sprintf_timestamp(
196 /*=================*/
197 char* buf); /*!< in: buffer where to sprintf */
198
199 /*************************************************************//**
200 Prints the contents of a memory buffer in hex and ascii. */
201 void
202 ut_print_buf(
203 /*=========*/
204 FILE* file, /*!< in: file where to print */
205 const void* buf, /*!< in: memory buffer */
206 ulint len); /*!< in: length of the buffer */
207
208 /*************************************************************//**
209 Prints the contents of a memory buffer in hex. */
210 void
211 ut_print_buf_hex(
212 /*=============*/
213 std::ostream& o, /*!< in/out: output stream */
214 const void* buf, /*!< in: memory buffer */
215 ulint len) /*!< in: length of the buffer */
216 MY_ATTRIBUTE((nonnull));
217 /*************************************************************//**
218 Prints the contents of a memory buffer in hex and ascii. */
219 void
220 ut_print_buf(
221 /*=========*/
222 std::ostream& o, /*!< in/out: output stream */
223 const void* buf, /*!< in: memory buffer */
224 ulint len) /*!< in: length of the buffer */
225 MY_ATTRIBUTE((nonnull));
226
227 /* Forward declaration of transaction handle */
228 struct trx_t;
229
230 /** Get a fixed-length string, quoted as an SQL identifier.
231 If the string contains a slash '/', the string will be
232 output as two identifiers separated by a period (.),
233 as in SQL database_name.identifier.
234 @param [in] trx transaction (NULL=no quotes).
235 @param [in] name table name.
236 @retval String quoted as an SQL identifier.
237 */
238 std::string
239 ut_get_name(
240 const trx_t* trx,
241 const char* name);
242
243 /**********************************************************************//**
244 Outputs a fixed-length string, quoted as an SQL identifier.
245 If the string contains a slash '/', the string will be
246 output as two identifiers separated by a period (.),
247 as in SQL database_name.identifier. */
248 void
249 ut_print_name(
250 /*==========*/
251 FILE* ef, /*!< in: stream */
252 const trx_t* trx, /*!< in: transaction */
253 const char* name); /*!< in: table name to print */
254 /** Format a table name, quoted as an SQL identifier.
255 If the name contains a slash '/', the result will contain two
256 identifiers separated by a period (.), as in SQL
257 database_name.table_name.
258 @see table_name_t
259 @param[in] name table or index name
260 @param[out] formatted formatted result, will be NUL-terminated
261 @param[in] formatted_size size of the buffer in bytes
262 @return pointer to 'formatted' */
263 char*
264 ut_format_name(
265 const char* name,
266 char* formatted,
267 ulint formatted_size);
268
269 /**********************************************************************//**
270 Catenate files. */
271 void
272 ut_copy_file(
273 /*=========*/
274 FILE* dest, /*!< in: output file */
275 FILE* src); /*!< in: input file to be appended to output */
276
277 /*************************************************************//**
278 Convert an error number to a human readable text message. The
279 returned string is static and should not be freed or modified.
280 @return string, describing the error */
281 const char*
282 ut_strerr(
283 /*======*/
284 dberr_t num); /*!< in: error number */
285
286 #endif /* !UNIV_INNOCHECKSUM */
287
288 #ifdef UNIV_PFS_MEMORY
289
290 /** Extract the basename of a file without its extension.
291 For example, extract "foo0bar" out of "/path/to/foo0bar.cc".
292 @param[in] file file path, e.g. "/path/to/foo0bar.cc"
293 @param[out] base result, e.g. "foo0bar"
294 @param[in] base_size size of the output buffer 'base', if there
295 is not enough space, then the result will be truncated, but always
296 '\0'-terminated
297 @return number of characters that would have been printed if the size
298 were unlimited (not including the final ‘\0’) */
299 size_t
300 ut_basename_noext(
301 const char* file,
302 char* base,
303 size_t base_size);
304
305 #endif /* UNIV_PFS_MEMORY */
306
307 namespace ib {
308
309 /** This is a wrapper class, used to print any unsigned integer type
310 in hexadecimal format. The main purpose of this data type is to
311 overload the global operator<<, so that we can print the given
312 wrapper value in hex. */
313 struct hex {
314 explicit hex(uintmax_t t): m_val(t) {}
315 const uintmax_t m_val;
316 };
317
318 /** This is an overload of the global operator<< for the user defined type
319 ib::hex. The unsigned value held in the ib::hex wrapper class will be printed
320 into the given output stream in hexadecimal format.
321 @param[in,out] lhs the output stream into which rhs is written.
322 @param[in] rhs the object to be written into lhs.
323 @retval reference to the output stream. */
324 inline
325 std::ostream&
326 operator<<(
327 std::ostream& lhs,
328 const hex& rhs)
329 {
330 std::ios_base::fmtflags ff = lhs.flags();
331 lhs << std::showbase << std::hex << rhs.m_val;
332 lhs.setf(ff);
333 return(lhs);
334 }
335
336 /** The class logger is the base class of all the error log related classes.
337 It contains a std::ostringstream object. The main purpose of this class is
338 to forward operator<< to the underlying std::ostringstream object. Do not
339 use this class directly, instead use one of the derived classes. */
340 class logger
341 {
342 protected:
343 /* This class must not be used directly */
344 ATTRIBUTE_COLD ATTRIBUTE_NOINLINE logger() {}
345 public:
346 template<typename T> ATTRIBUTE_COLD ATTRIBUTE_NOINLINE
347 logger& operator<<(const T& rhs)
348 {
349 m_oss << rhs;
350 return *this;
351 }
352
353 /** Handle a fixed character string in the same way as a pointer to
354 an unknown-length character string, to reduce object code bloat. */
355 template<size_t N> logger& operator<<(const char (&rhs)[N])
356 { return *this << static_cast<const char*>(rhs); }
357
358 /** Output an error code name */
359 ATTRIBUTE_COLD logger& operator<<(dberr_t err);
360
361 /** Append a string.
362 @param buf string buffer
363 @param size buffer size
364 @return the output stream */
365 ATTRIBUTE_COLD __attribute__((noinline))
366 std::ostream &write(const char *buf, std::streamsize size)
367 {
368 return m_oss.write(buf, size);
369 }
370
371 std::ostream &write(const byte *buf, std::streamsize size)
372 { return write(reinterpret_cast<const char*>(buf), size); }
373
374 std::ostringstream m_oss;
375 };
376
377 /** The class info is used to emit informational log messages. It is to be
378 used similar to std::cout. But the log messages will be emitted only when
379 the dtor is called. The preferred usage of this class is to make use of
380 unnamed temporaries as follows:
381
382 info() << "The server started successfully.";
383
384 In the above usage, the temporary object will be destroyed at the end of the
385 statement and hence the log message will be emitted at the end of the
386 statement. If a named object is created, then the log message will be emitted
387 only when it goes out of scope or destroyed. */
388 class info : public logger {
389 public:
390 ATTRIBUTE_COLD
391 ~info();
392 };
393
394 /** The class warn is used to emit warnings. Refer to the documentation of
395 class info for further details. */
396 class warn : public logger {
397 public:
398 ATTRIBUTE_COLD
399 ~warn();
400 };
401
402 /** The class error is used to emit error messages. Refer to the
403 documentation of class info for further details. */
404 class error : public logger {
405 public:
406 ATTRIBUTE_COLD
407 ~error();
408 /** Indicates that error::~error() was invoked. Can be used to
409 determine if error messages were logged during innodb code execution.
410 @return true if there were error messages, false otherwise. */
411 static bool was_logged() { return logged; }
412
413 private:
414 /** true if error::~error() was invoked, false otherwise */
415 static bool logged;
416 };
417
418 /** The class fatal is used to emit an error message and stop the server
419 by crashing it. Use this class when MySQL server needs to be stopped
420 immediately. Refer to the documentation of class info for usage details. */
421 class fatal : public logger {
422 public:
423 ATTRIBUTE_NORETURN
424 ~fatal();
425 };
426
427 /** Emit an error message if the given predicate is true, otherwise emit a
428 warning message */
429 class error_or_warn : public logger {
430 public:
431 ATTRIBUTE_COLD
432 error_or_warn(bool pred)
433 : m_error(pred)
434 {}
435
436 ATTRIBUTE_COLD
437 ~error_or_warn();
438 private:
439 const bool m_error;
440 };
441
442 /** Emit a fatal message if the given predicate is true, otherwise emit a
443 error message. */
444 class fatal_or_error : public logger {
445 public:
446 ATTRIBUTE_COLD
447 fatal_or_error(bool pred)
448 : m_fatal(pred)
449 {}
450
451 ATTRIBUTE_COLD
452 ~fatal_or_error();
453 private:
454 const bool m_fatal;
455 };
456
457 } // namespace ib
458
459 #include "ut0ut.inl"
460
461 #endif
462
463