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