Commit 06b0623a authored by Marko Mäkelä's avatar Marko Mäkelä

Cleanup: Aligned InnoDB index page header access

ut_align_down(): Preserve the const qualifier. Use C++ casts.

ha_delete_hash_node(): Correct an assertion expression.

fil_page_get_type(): Perform an assumed-aligned read.

page_align(): Preserve the const qualifier. Assume (some) alignment.

page_get_max_trx_id(): Check the index page type.

page_header_get_field(): Perform an assumed-aligned read.

page_get_autoinc(): Perform an assumed-aligned read.

page_dir_get_nth_slot(): Perform an assumed-aligned read.
Preserve the const qualifier.
parent c5856b0a
/***************************************************************************** /*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, MariaDB Corporation. Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -337,7 +337,7 @@ ha_delete_hash_node( ...@@ -337,7 +337,7 @@ ha_delete_hash_node(
ut_ad(btr_search_enabled); ut_ad(btr_search_enabled);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
if (table->adaptive) { if (table->adaptive) {
ut_a(del_node->block->frame = page_align(del_node->data)); ut_a(del_node->block->frame == page_align(del_node->data));
ut_a(del_node->block->n_pointers-- < MAX_N_POINTERS); ut_a(del_node->block->n_pointers-- < MAX_N_POINTERS);
} }
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
......
...@@ -580,7 +580,7 @@ void fil_block_reset_type(const buf_block_t& block, ulint type, mtr_t* mtr); ...@@ -580,7 +580,7 @@ void fil_block_reset_type(const buf_block_t& block, ulint type, mtr_t* mtr);
@return page type */ @return page type */
inline uint16_t fil_page_get_type(const byte* page) inline uint16_t fil_page_get_type(const byte* page)
{ {
return mach_read_from_2(page + FIL_PAGE_TYPE); return mach_read_from_2(my_assume_aligned<2>(page + FIL_PAGE_TYPE));
} }
/** Check (and if needed, reset) the page type. /** Check (and if needed, reset) the page type.
......
...@@ -171,7 +171,6 @@ constexpr uint16_t PAGE_NO_DIRECTION= 5; ...@@ -171,7 +171,6 @@ constexpr uint16_t PAGE_NO_DIRECTION= 5;
*/ */
typedef byte page_dir_slot_t; typedef byte page_dir_slot_t;
typedef page_dir_slot_t page_dir_t;
/* Offset of the directory start down from the page end. We call the /* Offset of the directory start down from the page end. We call the
slot with the highest file address directory start, as it points to slot with the highest file address directory start, as it points to
...@@ -198,11 +197,14 @@ extern my_bool srv_immediate_scrub_data_uncompressed; ...@@ -198,11 +197,14 @@ extern my_bool srv_immediate_scrub_data_uncompressed;
@param[in] ptr pointer within a page frame @param[in] ptr pointer within a page frame
@return start of the page frame */ @return start of the page frame */
MY_ATTRIBUTE((const)) MY_ATTRIBUTE((const))
inline inline page_t* page_align(void *ptr)
page_t*
page_align(const void* ptr)
{ {
return(static_cast<page_t*>(ut_align_down(ptr, srv_page_size))); return my_assume_aligned<UNIV_PAGE_SIZE_MIN>
(reinterpret_cast<page_t*>(ut_align_down(ptr, srv_page_size)));
}
inline const page_t *page_align(const void *ptr)
{
return page_align(const_cast<void*>(ptr));
} }
/** Gets the byte offset within a page frame. /** Gets the byte offset within a page frame.
...@@ -395,8 +397,10 @@ page_rec_is_infimum(const rec_t* rec); ...@@ -395,8 +397,10 @@ page_rec_is_infimum(const rec_t* rec);
/** Read PAGE_MAX_TRX_ID. /** Read PAGE_MAX_TRX_ID.
@param[in] page index page @param[in] page index page
@return the value of PAGE_MAX_TRX_ID or PAGE_ROOT_AUTO_INC */ @return the value of PAGE_MAX_TRX_ID or PAGE_ROOT_AUTO_INC */
MY_ATTRIBUTE((nonnull, warn_unused_result))
inline trx_id_t page_get_max_trx_id(const page_t *page) inline trx_id_t page_get_max_trx_id(const page_t *page)
{ {
ut_ad(fil_page_index_page_check(page));
static_assert((PAGE_HEADER + PAGE_MAX_TRX_ID) % 8 == 0, "alignment"); static_assert((PAGE_HEADER + PAGE_MAX_TRX_ID) % 8 == 0, "alignment");
const auto *p= my_assume_aligned<8>(page + PAGE_HEADER + PAGE_MAX_TRX_ID); const auto *p= my_assume_aligned<8>(page + PAGE_HEADER + PAGE_MAX_TRX_ID);
return mach_read_from_8(p); return mach_read_from_8(p);
...@@ -439,14 +443,6 @@ page_set_autoinc( ...@@ -439,14 +443,6 @@ page_set_autoinc(
bool reset) bool reset)
MY_ATTRIBUTE((nonnull)); MY_ATTRIBUTE((nonnull));
/** Read the AUTO_INCREMENT value from a clustered index root page.
@param[in] page clustered index root page
@return the persisted AUTO_INCREMENT value */
MY_ATTRIBUTE((nonnull, warn_unused_result))
UNIV_INLINE
ib_uint64_t
page_get_autoinc(const page_t* page);
/*************************************************************//** /*************************************************************//**
Returns the RTREE SPLIT SEQUENCE NUMBER (FIL_RTREE_SPLIT_SEQ_NUM). Returns the RTREE SPLIT SEQUENCE NUMBER (FIL_RTREE_SPLIT_SEQ_NUM).
@return SPLIT SEQUENCE NUMBER */ @return SPLIT SEQUENCE NUMBER */
...@@ -468,14 +464,13 @@ page_set_ssn_id( ...@@ -468,14 +464,13 @@ page_set_ssn_id(
mtr_t* mtr); /*!< in/out: mini-transaction */ mtr_t* mtr); /*!< in/out: mini-transaction */
#endif /* !UNIV_INNOCHECKSUM */ #endif /* !UNIV_INNOCHECKSUM */
/*************************************************************//** /** Read a page header field. */
Reads the given header field. */ inline uint16_t page_header_get_field(const page_t *page, ulint field)
UNIV_INLINE {
uint16_t ut_ad(field <= PAGE_INDEX_ID);
page_header_get_field( ut_ad(!(field & 1));
/*==================*/ return mach_read_from_2(my_assume_aligned<2>(PAGE_HEADER + field + page));
const page_t* page, /*!< in: page */ }
ulint field); /*!< in: PAGE_N_DIR_SLOTS, ... */
#ifndef UNIV_INNOCHECKSUM #ifndef UNIV_INNOCHECKSUM
/*************************************************************//** /*************************************************************//**
...@@ -635,21 +630,20 @@ page_dir_set_n_slots( ...@@ -635,21 +630,20 @@ page_dir_set_n_slots(
page_zip_des_t* page_zip,/*!< in/out: compressed page whose page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be updated, or NULL */ uncompressed part will be updated, or NULL */
ulint n_slots);/*!< in: number of slots */ ulint n_slots);/*!< in: number of slots */
#ifdef UNIV_DEBUG
/*************************************************************//** /** Gets the pointer to a directory slot.
Gets pointer to nth directory slot. @param n sparse directory slot number
@return pointer to dir slot */ @return pointer to the sparse directory slot */
UNIV_INLINE inline page_dir_slot_t *page_dir_get_nth_slot(page_t *page, ulint n)
page_dir_slot_t* {
page_dir_get_nth_slot( ut_ad(page_dir_get_n_slots(page) > n);
/*==================*/ static_assert(PAGE_DIR_SLOT_SIZE == 2, "compatibility");
const page_t* page, /*!< in: index page */ return my_assume_aligned<2>(page + srv_page_size - (PAGE_DIR + 2) - n * 2);
ulint n); /*!< in: position */ }
#else /* UNIV_DEBUG */ inline const page_dir_slot_t *page_dir_get_nth_slot(const page_t *page,ulint n)
# define page_dir_get_nth_slot(page, n) \ {
((page) + (srv_page_size - PAGE_DIR \ return page_dir_get_nth_slot(const_cast<page_t*>(page), n);
- (n + 1) * PAGE_DIR_SLOT_SIZE)) }
#endif /* UNIV_DEBUG */
/**************************************************************//** /**************************************************************//**
Used to check the consistency of a record on a page. Used to check the consistency of a record on a page.
@return TRUE if succeed */ @return TRUE if succeed */
...@@ -750,6 +744,19 @@ inline bool page_has_next(const page_t* page) ...@@ -750,6 +744,19 @@ inline bool page_has_next(const page_t* page)
!= FIL_NULL; != FIL_NULL;
} }
/** Read the AUTO_INCREMENT value from a clustered index root page.
@param[in] page clustered index root page
@return the persisted AUTO_INCREMENT value */
MY_ATTRIBUTE((nonnull, warn_unused_result))
inline uint64_t page_get_autoinc(const page_t *page)
{
ut_d(uint16_t page_type= fil_page_get_type(page));
ut_ad(page_type == FIL_PAGE_INDEX || page_type == FIL_PAGE_TYPE_INSTANT);
ut_ad(!page_has_siblings(page));
const auto *p= my_assume_aligned<8>(page + PAGE_HEADER + PAGE_ROOT_AUTO_INC);
return mach_read_from_8(p);
}
/************************************************************//** /************************************************************//**
Gets the pointer to the next record on the page. Gets the pointer to the next record on the page.
@return pointer to next record */ @return pointer to next record */
......
...@@ -62,18 +62,6 @@ page_update_max_trx_id( ...@@ -62,18 +62,6 @@ page_update_max_trx_id(
} }
} }
/** Read the AUTO_INCREMENT value from a clustered index root page.
@param[in] page clustered index root page
@return the persisted AUTO_INCREMENT value */
UNIV_INLINE
ib_uint64_t
page_get_autoinc(const page_t* page)
{
ut_ad(fil_page_index_page_check(page));
ut_ad(!page_has_siblings(page));
return(mach_read_from_8(PAGE_HEADER + PAGE_ROOT_AUTO_INC + page));
}
/*************************************************************//** /*************************************************************//**
Returns the RTREE SPLIT SEQUENCE NUMBER (FIL_RTREE_SPLIT_SEQ_NUM). Returns the RTREE SPLIT SEQUENCE NUMBER (FIL_RTREE_SPLIT_SEQ_NUM).
@return SPLIT SEQUENCE NUMBER */ @return SPLIT SEQUENCE NUMBER */
...@@ -116,21 +104,6 @@ page_set_ssn_id( ...@@ -116,21 +104,6 @@ page_set_ssn_id(
#endif /* !UNIV_INNOCHECKSUM */ #endif /* !UNIV_INNOCHECKSUM */
/*************************************************************//**
Reads the given header field. */
UNIV_INLINE
uint16_t
page_header_get_field(
/*==================*/
const page_t* page, /*!< in: page */
ulint field) /*!< in: PAGE_LEVEL, ... */
{
ut_ad(page);
ut_ad(field <= PAGE_INDEX_ID);
return(mach_read_from_2(page + PAGE_HEADER + field));
}
#ifndef UNIV_INNOCHECKSUM #ifndef UNIV_INNOCHECKSUM
/*************************************************************//** /*************************************************************//**
Sets the given header field. */ Sets the given header field. */
...@@ -495,25 +468,6 @@ page_dir_set_n_heap( ...@@ -495,25 +468,6 @@ page_dir_set_n_heap(
& page_header_get_field(page, PAGE_N_HEAP))); & page_header_get_field(page, PAGE_N_HEAP)));
} }
#ifdef UNIV_DEBUG
/*************************************************************//**
Gets pointer to nth directory slot.
@return pointer to dir slot */
UNIV_INLINE
page_dir_slot_t*
page_dir_get_nth_slot(
/*==================*/
const page_t* page, /*!< in: index page */
ulint n) /*!< in: position */
{
ut_ad(page_dir_get_n_slots(page) > n);
return((page_dir_slot_t*)
page + srv_page_size - PAGE_DIR
- (n + 1) * PAGE_DIR_SLOT_SIZE);
}
#endif /* UNIV_DEBUG */
/**************************************************************//** /**************************************************************//**
Used to check the consistency of a record on a page. Used to check the consistency of a record on a page.
@return TRUE if succeed */ @return TRUE if succeed */
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2019, MariaDB Corporation. Copyright (c) 2019, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -27,8 +27,6 @@ Created 1/20/1994 Heikki Tuuri ...@@ -27,8 +27,6 @@ Created 1/20/1994 Heikki Tuuri
#ifndef ut0byte_h #ifndef ut0byte_h
#define ut0byte_h #define ut0byte_h
#include "univ.i" #include "univ.i"
/*******************************************************//** /*******************************************************//**
...@@ -62,28 +60,38 @@ ut_uint64_align_up( ...@@ -62,28 +60,38 @@ ut_uint64_align_up(
ib_uint64_t n, /*!< in: number to be rounded */ ib_uint64_t n, /*!< in: number to be rounded */
ulint align_no); /*!< in: align by this number ulint align_no); /*!< in: align by this number
which must be a power of 2 */ which must be a power of 2 */
/*********************************************************//** /** Round down a pointer to the nearest aligned address.
The following function rounds down a pointer to the nearest @param ptr pointer
aligned address. @param alignment a power of 2
@return aligned pointer */ @return aligned pointer */
UNIV_INLINE static inline void *ut_align_down(void *ptr, size_t alignment)
void* {
ut_align_down( ut_ad(alignment > 0);
/*==========*/ ut_ad(ut_is_2pow(alignment));
const void* ptr, /*!< in: pointer */ ut_ad(ptr);
ulint align_no) /*!< in: align by this number */ static_assert(sizeof ptr == sizeof(size_t), "compatibility");
MY_ATTRIBUTE((const));
/*********************************************************//** return reinterpret_cast<void*>(reinterpret_cast<size_t>(ptr) &
The following function computes the offset of a pointer from the nearest ~(alignment - 1));
aligned address. }
static inline const void *ut_align_down(const void *ptr, size_t alignment)
{
return ut_align_down(const_cast<void*>(ptr), alignment);
}
/** Compute the offset of a pointer from the nearest aligned address.
@param ptr pointer
@param alignment a power of 2
@return distance from aligned pointer */ @return distance from aligned pointer */
UNIV_INLINE inline size_t ut_align_offset(const void *ptr, size_t alignment)
ulint {
ut_align_offset( ut_ad(alignment > 0);
/*============*/ ut_ad(ut_is_2pow(alignment));
const void* ptr, /*!< in: pointer */ ut_ad(ptr);
ulint align_no) /*!< in: align by this number */ return reinterpret_cast<size_t>(ptr) & (alignment - 1);
MY_ATTRIBUTE((const)); }
/*****************************************************************//** /*****************************************************************//**
Gets the nth bit of a ulint. Gets the nth bit of a ulint.
@return TRUE if nth bit is 1; 0th bit is defined to be the least significant */ @return TRUE if nth bit is 1; 0th bit is defined to be the least significant */
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2019, MariaDB Corporation. Copyright (c) 2019, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -75,46 +75,6 @@ ut_uint64_align_up( ...@@ -75,46 +75,6 @@ ut_uint64_align_up(
return((n + align_1) & ~align_1); return((n + align_1) & ~align_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. Gets the nth bit of a ulint.
@return TRUE if nth bit is 1; 0th bit is defined to be the least significant */ @return TRUE if nth bit is 1; 0th bit is defined to be the least significant */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment