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.
This commit is contained in:
parent
c5856b0a68
commit
06b0623adb
@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
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(
|
|||||||
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);
|
|||||||
@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;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
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;
|
|||||||
@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);
|
|||||||
/** 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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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)
|
|||||||
!= 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(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 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(
|
|||||||
|
|
||||||
#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(
|
|||||||
& 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 */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
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
|
|||||||
#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(
|
|||||||
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 */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
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(
|
|||||||
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 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user