summaryrefslogtreecommitdiff
path: root/innobase/include/ut0byte.ic
diff options
context:
space:
mode:
Diffstat (limited to 'innobase/include/ut0byte.ic')
-rw-r--r--innobase/include/ut0byte.ic360
1 files changed, 360 insertions, 0 deletions
diff --git a/innobase/include/ut0byte.ic b/innobase/include/ut0byte.ic
new file mode 100644
index 00000000000..b8170392c8f
--- /dev/null
+++ b/innobase/include/ut0byte.ic
@@ -0,0 +1,360 @@
+/******************************************************************
+Utilities for byte operations
+
+(c) 1994, 1995 Innobase Oy
+
+Created 5/30/1994 Heikki Tuuri
+*******************************************************************/
+
+/***********************************************************
+Creates a 64-bit dulint out of two ulints. */
+UNIV_INLINE
+dulint
+ut_dulint_create(
+/*=============*/
+ /* out: created dulint */
+ 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. */
+UNIV_INLINE
+ulint
+ut_dulint_get_high(
+/*===============*/
+ /* out: 32 bits in ulint */
+ dulint d) /* in: dulint */
+{
+ return(d.high);
+}
+
+/***********************************************************
+Gets the low-order 32 bits of a dulint. */
+UNIV_INLINE
+ulint
+ut_dulint_get_low(
+/*==============*/
+ /* out: 32 bits in ulint */
+ dulint d) /* in: dulint */
+{
+ return(d.low);
+}
+
+/***********************************************************
+Tests if a dulint is zero. */
+UNIV_INLINE
+ibool
+ut_dulint_is_zero(
+/*==============*/
+ /* out: TRUE if zero */
+ dulint a) /* in: dulint */
+{
+ if ((a.low == 0) && (a.high == 0)) {
+
+ return(TRUE);
+ }
+
+ return(FALSE);
+}
+
+/***********************************************************
+Compares two dulints. */
+UNIV_INLINE
+int
+ut_dulint_cmp(
+/*==========*/
+ /* out: -1 if a < b, 0 if a == b,
+ 1 if a > b */
+ 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. */
+UNIV_INLINE
+dulint
+ut_dulint_get_max(
+/*==============*/
+ /* out: max(a, b) */
+ 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. */
+UNIV_INLINE
+dulint
+ut_dulint_get_min(
+/*==============*/
+ /* out: min(a, b) */
+ 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. */
+UNIV_INLINE
+dulint
+ut_dulint_add(
+/*==========*/
+ /* out: sum a + b */
+ dulint a, /* in: dulint */
+ ulint b) /* in: ulint */
+{
+ if (0xFFFFFFFF - b >= a.low) {
+ a.low += b;
+
+ return(a);
+ }
+
+ a.low = a.low - (0xFFFFFFFF - b) - 1;
+
+ a.high++;
+
+ return(a);
+}
+
+/***********************************************************
+Subtracts a ulint from a dulint. */
+UNIV_INLINE
+dulint
+ut_dulint_subtract(
+/*===============*/
+ /* out: a - b */
+ 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 = 0xFFFFFFFF - 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. */
+UNIV_INLINE
+ulint
+ut_dulint_minus(
+/*============*/
+ /* out: a - b */
+ 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)(0xFFFFFFFF - 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. */
+UNIV_INLINE
+dulint
+ut_dulint_align_down(
+/*=================*/
+ /* out: rounded value */
+ 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. */
+UNIV_INLINE
+dulint
+ut_dulint_align_up(
+/*===============*/
+ /* out: rounded value */
+ 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));
+}
+
+/************************************************************
+The following function calculates the value of an integer n rounded
+to the least product of align_no which is >= n. align_no
+has to be a power of 2. */
+UNIV_INLINE
+ulint
+ut_calc_align(
+/*==========*/
+ /* out: rounded value */
+ ulint n, /* in: number to be rounded */
+ ulint align_no) /* in: align by this number */
+{
+ ut_ad(align_no > 0);
+ ut_ad(((align_no - 1) & align_no) == 0);
+
+ return((n + align_no - 1) & ~(align_no - 1));
+}
+
+/*************************************************************
+The following function rounds up a pointer to the nearest aligned address. */
+UNIV_INLINE
+void*
+ut_align(
+/*=====*/
+ /* out: aligned pointer */
+ 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 calculates the value of an integer n rounded
+to the biggest product of align_no which is <= n. align_no has to be a
+power of 2. */
+UNIV_INLINE
+ulint
+ut_calc_align_down(
+/*===============*/
+ /* out: rounded value */
+ ulint n, /* in: number to be rounded */
+ ulint align_no) /* in: align by this number */
+{
+ ut_ad(align_no > 0);
+ ut_ad(((align_no - 1) & align_no) == 0);
+
+ return(n & ~(align_no - 1));
+}
+
+/*************************************************************
+The following function rounds down a pointer to the nearest
+aligned address. */
+UNIV_INLINE
+void*
+ut_align_down(
+/*==========*/
+ /* out: aligned pointer */
+ 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)));
+}
+
+/*********************************************************************
+Gets the nth bit of a ulint. */
+UNIV_INLINE
+ibool
+ut_bit_get_nth(
+/*===========*/
+ /* out: TRUE if nth bit is 1; 0th bit is defined to
+ be the least significant */
+ ulint a, /* in: ulint */
+ ulint n) /* in: nth bit requested */
+{
+ ut_ad(n < 8 * sizeof(ulint));
+ ut_ad(TRUE == 1);
+
+ return(1 & (a >> n));
+}
+
+/*********************************************************************
+Sets the nth bit of a ulint. */
+UNIV_INLINE
+ulint
+ut_bit_set_nth(
+/*===========*/
+ /* out: the ulint with the bit set as requested */
+ 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));
+ ut_ad(TRUE == 1);
+
+ if (val) {
+ return((1 << n) | a);
+ } else {
+ return(~(1 << n) & a);
+ }
+}