diff options
Diffstat (limited to 'storage/innobase/include/ut0byte.ic')
-rw-r--r-- | storage/innobase/include/ut0byte.ic | 411 |
1 files changed, 411 insertions, 0 deletions
diff --git a/storage/innobase/include/ut0byte.ic b/storage/innobase/include/ut0byte.ic new file mode 100644 index 00000000000..e3beed65138 --- /dev/null +++ b/storage/innobase/include/ut0byte.ic @@ -0,0 +1,411 @@ +/***************************************************************************** + +Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; version 2 of the License. + +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 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., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +/**************************************************************//** +@file include/ut0byte.ic +Utilities for byte operations + +Created 5/30/1994 Heikki Tuuri +*******************************************************************/ + +/*******************************************************//** +Creates a 64-bit dulint out of two ulints. +@return created dulint */ +UNIV_INLINE +dulint +ut_dulint_create( +/*=============*/ + ulint high, /*!< in: high-order 32 bits */ + ulint low) /*!< in: low-order 32 bits */ +{ + dulint res; + + ut_ad(high <= 0xFFFFFFFF); + ut_ad(low <= 0xFFFFFFFF); + + res.high = high; + res.low = low; + + return(res); +} + +/*******************************************************//** +Gets the high-order 32 bits of a dulint. +@return 32 bits in ulint */ +UNIV_INLINE +ulint +ut_dulint_get_high( +/*===============*/ + dulint d) /*!< in: dulint */ +{ + return(d.high); +} + +/*******************************************************//** +Gets the low-order 32 bits of a dulint. +@return 32 bits in ulint */ +UNIV_INLINE +ulint +ut_dulint_get_low( +/*==============*/ + dulint d) /*!< in: dulint */ +{ + return(d.low); +} + +/*******************************************************//** +Converts a dulint (a struct of 2 ulints) to ib_int64_t, which is a 64-bit +integer type. +@return value in ib_int64_t type */ +UNIV_INLINE +ib_int64_t +ut_conv_dulint_to_longlong( +/*=======================*/ + dulint d) /*!< in: dulint */ +{ + return((ib_int64_t)d.low + + (((ib_int64_t)d.high) << 32)); +} + +/*******************************************************//** +Tests if a dulint is zero. +@return TRUE if zero */ +UNIV_INLINE +ibool +ut_dulint_is_zero( +/*==============*/ + dulint a) /*!< in: dulint */ +{ + if ((a.low == 0) && (a.high == 0)) { + + return(TRUE); + } + + return(FALSE); +} + +/*******************************************************//** +Compares two dulints. +@return -1 if a < b, 0 if a == b, 1 if a > b */ +UNIV_INLINE +int +ut_dulint_cmp( +/*==========*/ + dulint a, /*!< in: dulint */ + dulint b) /*!< in: dulint */ +{ + if (a.high > b.high) { + return(1); + } else if (a.high < b.high) { + return(-1); + } else if (a.low > b.low) { + return(1); + } else if (a.low < b.low) { + return(-1); + } else { + return(0); + } +} + +/*******************************************************//** +Calculates the max of two dulints. +@return max(a, b) */ +UNIV_INLINE +dulint +ut_dulint_get_max( +/*==============*/ + dulint a, /*!< in: dulint */ + dulint b) /*!< in: dulint */ +{ + if (ut_dulint_cmp(a, b) > 0) { + + return(a); + } + + return(b); +} + +/*******************************************************//** +Calculates the min of two dulints. +@return min(a, b) */ +UNIV_INLINE +dulint +ut_dulint_get_min( +/*==============*/ + dulint a, /*!< in: dulint */ + dulint b) /*!< in: dulint */ +{ + if (ut_dulint_cmp(a, b) > 0) { + + return(b); + } + + return(a); +} + +/*******************************************************//** +Adds a ulint to a dulint. +@return sum a + b */ +UNIV_INLINE +dulint +ut_dulint_add( +/*==========*/ + dulint a, /*!< in: dulint */ + ulint b) /*!< in: ulint */ +{ + if (0xFFFFFFFFUL - b >= a.low) { + a.low += b; + + return(a); + } + + a.low = a.low - (0xFFFFFFFFUL - b) - 1; + + a.high++; + + return(a); +} + +/*******************************************************//** +Subtracts a ulint from a dulint. +@return a - b */ +UNIV_INLINE +dulint +ut_dulint_subtract( +/*===============*/ + dulint a, /*!< in: dulint */ + ulint b) /*!< in: ulint, b <= a */ +{ + if (a.low >= b) { + a.low -= b; + + return(a); + } + + b -= a.low + 1; + + a.low = 0xFFFFFFFFUL - b; + + ut_ad(a.high > 0); + + a.high--; + + return(a); +} + +/*******************************************************//** +Subtracts a dulint from another. NOTE that the difference must be positive +and smaller that 4G. +@return a - b */ +UNIV_INLINE +ulint +ut_dulint_minus( +/*============*/ + dulint a, /*!< in: dulint; NOTE a must be >= b and at most + 2 to power 32 - 1 greater */ + dulint b) /*!< in: dulint */ +{ + ulint diff; + + if (a.high == b.high) { + ut_ad(a.low >= b.low); + + return(a.low - b.low); + } + + ut_ad(a.high == b.high + 1); + + diff = (ulint)(0xFFFFFFFFUL - b.low); + diff += 1 + a.low; + + ut_ad(diff > a.low); + + return(diff); +} + +/********************************************************//** +Rounds a dulint downward to a multiple of a power of 2. +@return rounded value */ +UNIV_INLINE +dulint +ut_dulint_align_down( +/*=================*/ + dulint n, /*!< in: number to be rounded */ + ulint align_no) /*!< in: align by this number which must be a + power of 2 */ +{ + ulint low, high; + + ut_ad(align_no > 0); + ut_ad(((align_no - 1) & align_no) == 0); + + low = ut_dulint_get_low(n); + high = ut_dulint_get_high(n); + + low = low & ~(align_no - 1); + + return(ut_dulint_create(high, low)); +} + +/********************************************************//** +Rounds a dulint upward to a multiple of a power of 2. +@return rounded value */ +UNIV_INLINE +dulint +ut_dulint_align_up( +/*===============*/ + dulint n, /*!< in: number to be rounded */ + ulint align_no) /*!< in: align by this number which must be a + power of 2 */ +{ + return(ut_dulint_align_down(ut_dulint_add(n, align_no - 1), align_no)); +} + +/********************************************************//** +Rounds ib_uint64_t downward to a multiple of a power of 2. +@return rounded value */ +UNIV_INLINE +ib_uint64_t +ut_uint64_align_down( +/*=================*/ + ib_uint64_t n, /*!< in: number to be rounded */ + ulint align_no) /*!< in: align by this number + which must be a power of 2 */ +{ + ut_ad(align_no > 0); + ut_ad(ut_is_2pow(align_no)); + + return(n & ~((ib_uint64_t) align_no - 1)); +} + +/********************************************************//** +Rounds ib_uint64_t upward to a multiple of a power of 2. +@return rounded value */ +UNIV_INLINE +ib_uint64_t +ut_uint64_align_up( +/*===============*/ + ib_uint64_t n, /*!< in: number to be rounded */ + ulint align_no) /*!< in: align by this number + which must be a power of 2 */ +{ + ib_uint64_t align_1 = (ib_uint64_t) align_no - 1; + + ut_ad(align_no > 0); + ut_ad(ut_is_2pow(align_no)); + + return((n + align_1) & ~align_1); +} + +/*********************************************************//** +The following function rounds up a pointer to the nearest aligned address. +@return aligned pointer */ +UNIV_INLINE +void* +ut_align( +/*=====*/ + void* ptr, /*!< in: pointer */ + ulint align_no) /*!< in: align by this number */ +{ + ut_ad(align_no > 0); + ut_ad(((align_no - 1) & align_no) == 0); + ut_ad(ptr); + + ut_ad(sizeof(void*) == sizeof(ulint)); + + return((void*)((((ulint)ptr) + align_no - 1) & ~(align_no - 1))); +} + +/*********************************************************//** +The following function rounds down a pointer to the nearest +aligned address. +@return aligned pointer */ +UNIV_INLINE +void* +ut_align_down( +/*==========*/ + const void* ptr, /*!< in: pointer */ + ulint align_no) /*!< in: align by this number */ +{ + ut_ad(align_no > 0); + ut_ad(((align_no - 1) & align_no) == 0); + ut_ad(ptr); + + ut_ad(sizeof(void*) == sizeof(ulint)); + + return((void*)((((ulint)ptr)) & ~(align_no - 1))); +} + +/*********************************************************//** +The following function computes the offset of a pointer from the nearest +aligned address. +@return distance from aligned pointer */ +UNIV_INLINE +ulint +ut_align_offset( +/*============*/ + const void* ptr, /*!< in: pointer */ + ulint align_no) /*!< in: align by this number */ +{ + ut_ad(align_no > 0); + ut_ad(((align_no - 1) & align_no) == 0); + ut_ad(ptr); + + ut_ad(sizeof(void*) == sizeof(ulint)); + + return(((ulint)ptr) & (align_no - 1)); +} + +/*****************************************************************//** +Gets the nth bit of a ulint. +@return TRUE if nth bit is 1; 0th bit is defined to be the least significant */ +UNIV_INLINE +ibool +ut_bit_get_nth( +/*===========*/ + ulint a, /*!< in: ulint */ + ulint n) /*!< in: nth bit requested */ +{ + ut_ad(n < 8 * sizeof(ulint)); +#if TRUE != 1 +# error "TRUE != 1" +#endif + return(1 & (a >> n)); +} + +/*****************************************************************//** +Sets the nth bit of a ulint. +@return the ulint with the bit set as requested */ +UNIV_INLINE +ulint +ut_bit_set_nth( +/*===========*/ + ulint a, /*!< in: ulint */ + ulint n, /*!< in: nth bit requested */ + ibool val) /*!< in: value for the bit to set */ +{ + ut_ad(n < 8 * sizeof(ulint)); +#if TRUE != 1 +# error "TRUE != 1" +#endif + if (val) { + return(((ulint) 1 << n) | a); + } else { + return(~((ulint) 1 << n) & a); + } +} |