Skip to content

Commit 06b0623

Browse files
committed
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.
1 parent c5856b0 commit 06b0623

File tree

6 files changed

+78
-149
lines changed

6 files changed

+78
-149
lines changed

storage/innobase/ha/ha0ha.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*****************************************************************************
22
33
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
4-
Copyright (c) 2017, MariaDB Corporation.
4+
Copyright (c) 2017, 2020, MariaDB Corporation.
55
66
This program is free software; you can redistribute it and/or modify it under
77
the terms of the GNU General Public License as published by the Free Software
@@ -337,7 +337,7 @@ ha_delete_hash_node(
337337
ut_ad(btr_search_enabled);
338338
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
339339
if (table->adaptive) {
340-
ut_a(del_node->block->frame = page_align(del_node->data));
340+
ut_a(del_node->block->frame == page_align(del_node->data));
341341
ut_a(del_node->block->n_pointers-- < MAX_N_POINTERS);
342342
}
343343
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */

storage/innobase/include/fsp0fsp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ void fil_block_reset_type(const buf_block_t& block, ulint type, mtr_t* mtr);
580580
@return page type */
581581
inline uint16_t fil_page_get_type(const byte* page)
582582
{
583-
return mach_read_from_2(page + FIL_PAGE_TYPE);
583+
return mach_read_from_2(my_assume_aligned<2>(page + FIL_PAGE_TYPE));
584584
}
585585

586586
/** Check (and if needed, reset) the page type.

storage/innobase/include/page0page.h

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ constexpr uint16_t PAGE_NO_DIRECTION= 5;
171171
*/
172172

173173
typedef byte page_dir_slot_t;
174-
typedef page_dir_slot_t page_dir_t;
175174

176175
/* Offset of the directory start down from the page end. We call the
177176
slot with the highest file address directory start, as it points to
@@ -198,11 +197,14 @@ extern my_bool srv_immediate_scrub_data_uncompressed;
198197
@param[in] ptr pointer within a page frame
199198
@return start of the page frame */
200199
MY_ATTRIBUTE((const))
201-
inline
202-
page_t*
203-
page_align(const void* ptr)
200+
inline page_t* page_align(void *ptr)
204201
{
205-
return(static_cast<page_t*>(ut_align_down(ptr, srv_page_size)));
202+
return my_assume_aligned<UNIV_PAGE_SIZE_MIN>
203+
(reinterpret_cast<page_t*>(ut_align_down(ptr, srv_page_size)));
204+
}
205+
inline const page_t *page_align(const void *ptr)
206+
{
207+
return page_align(const_cast<void*>(ptr));
206208
}
207209

208210
/** Gets the byte offset within a page frame.
@@ -395,8 +397,10 @@ page_rec_is_infimum(const rec_t* rec);
395397
/** Read PAGE_MAX_TRX_ID.
396398
@param[in] page index page
397399
@return the value of PAGE_MAX_TRX_ID or PAGE_ROOT_AUTO_INC */
400+
MY_ATTRIBUTE((nonnull, warn_unused_result))
398401
inline trx_id_t page_get_max_trx_id(const page_t *page)
399402
{
403+
ut_ad(fil_page_index_page_check(page));
400404
static_assert((PAGE_HEADER + PAGE_MAX_TRX_ID) % 8 == 0, "alignment");
401405
const auto *p= my_assume_aligned<8>(page + PAGE_HEADER + PAGE_MAX_TRX_ID);
402406
return mach_read_from_8(p);
@@ -439,14 +443,6 @@ page_set_autoinc(
439443
bool reset)
440444
MY_ATTRIBUTE((nonnull));
441445

442-
/** Read the AUTO_INCREMENT value from a clustered index root page.
443-
@param[in] page clustered index root page
444-
@return the persisted AUTO_INCREMENT value */
445-
MY_ATTRIBUTE((nonnull, warn_unused_result))
446-
UNIV_INLINE
447-
ib_uint64_t
448-
page_get_autoinc(const page_t* page);
449-
450446
/*************************************************************//**
451447
Returns the RTREE SPLIT SEQUENCE NUMBER (FIL_RTREE_SPLIT_SEQ_NUM).
452448
@return SPLIT SEQUENCE NUMBER */
@@ -468,14 +464,13 @@ page_set_ssn_id(
468464
mtr_t* mtr); /*!< in/out: mini-transaction */
469465

470466
#endif /* !UNIV_INNOCHECKSUM */
471-
/*************************************************************//**
472-
Reads the given header field. */
473-
UNIV_INLINE
474-
uint16_t
475-
page_header_get_field(
476-
/*==================*/
477-
const page_t* page, /*!< in: page */
478-
ulint field); /*!< in: PAGE_N_DIR_SLOTS, ... */
467+
/** Read a page header field. */
468+
inline uint16_t page_header_get_field(const page_t *page, ulint field)
469+
{
470+
ut_ad(field <= PAGE_INDEX_ID);
471+
ut_ad(!(field & 1));
472+
return mach_read_from_2(my_assume_aligned<2>(PAGE_HEADER + field + page));
473+
}
479474

480475
#ifndef UNIV_INNOCHECKSUM
481476
/*************************************************************//**
@@ -635,21 +630,20 @@ page_dir_set_n_slots(
635630
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
636631
uncompressed part will be updated, or NULL */
637632
ulint n_slots);/*!< in: number of slots */
638-
#ifdef UNIV_DEBUG
639-
/*************************************************************//**
640-
Gets pointer to nth directory slot.
641-
@return pointer to dir slot */
642-
UNIV_INLINE
643-
page_dir_slot_t*
644-
page_dir_get_nth_slot(
645-
/*==================*/
646-
const page_t* page, /*!< in: index page */
647-
ulint n); /*!< in: position */
648-
#else /* UNIV_DEBUG */
649-
# define page_dir_get_nth_slot(page, n) \
650-
((page) + (srv_page_size - PAGE_DIR \
651-
- (n + 1) * PAGE_DIR_SLOT_SIZE))
652-
#endif /* UNIV_DEBUG */
633+
634+
/** Gets the pointer to a directory slot.
635+
@param n sparse directory slot number
636+
@return pointer to the sparse directory slot */
637+
inline page_dir_slot_t *page_dir_get_nth_slot(page_t *page, ulint n)
638+
{
639+
ut_ad(page_dir_get_n_slots(page) > n);
640+
static_assert(PAGE_DIR_SLOT_SIZE == 2, "compatibility");
641+
return my_assume_aligned<2>(page + srv_page_size - (PAGE_DIR + 2) - n * 2);
642+
}
643+
inline const page_dir_slot_t *page_dir_get_nth_slot(const page_t *page,ulint n)
644+
{
645+
return page_dir_get_nth_slot(const_cast<page_t*>(page), n);
646+
}
653647
/**************************************************************//**
654648
Used to check the consistency of a record on a page.
655649
@return TRUE if succeed */
@@ -750,6 +744,19 @@ inline bool page_has_next(const page_t* page)
750744
!= FIL_NULL;
751745
}
752746

747+
/** Read the AUTO_INCREMENT value from a clustered index root page.
748+
@param[in] page clustered index root page
749+
@return the persisted AUTO_INCREMENT value */
750+
MY_ATTRIBUTE((nonnull, warn_unused_result))
751+
inline uint64_t page_get_autoinc(const page_t *page)
752+
{
753+
ut_d(uint16_t page_type= fil_page_get_type(page));
754+
ut_ad(page_type == FIL_PAGE_INDEX || page_type == FIL_PAGE_TYPE_INSTANT);
755+
ut_ad(!page_has_siblings(page));
756+
const auto *p= my_assume_aligned<8>(page + PAGE_HEADER + PAGE_ROOT_AUTO_INC);
757+
return mach_read_from_8(p);
758+
}
759+
753760
/************************************************************//**
754761
Gets the pointer to the next record on the page.
755762
@return pointer to next record */

storage/innobase/include/page0page.ic

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,6 @@ page_update_max_trx_id(
6262
}
6363
}
6464

65-
/** Read the AUTO_INCREMENT value from a clustered index root page.
66-
@param[in] page clustered index root page
67-
@return the persisted AUTO_INCREMENT value */
68-
UNIV_INLINE
69-
ib_uint64_t
70-
page_get_autoinc(const page_t* page)
71-
{
72-
ut_ad(fil_page_index_page_check(page));
73-
ut_ad(!page_has_siblings(page));
74-
return(mach_read_from_8(PAGE_HEADER + PAGE_ROOT_AUTO_INC + page));
75-
}
76-
7765
/*************************************************************//**
7866
Returns the RTREE SPLIT SEQUENCE NUMBER (FIL_RTREE_SPLIT_SEQ_NUM).
7967
@return SPLIT SEQUENCE NUMBER */
@@ -116,21 +104,6 @@ page_set_ssn_id(
116104

117105
#endif /* !UNIV_INNOCHECKSUM */
118106

119-
/*************************************************************//**
120-
Reads the given header field. */
121-
UNIV_INLINE
122-
uint16_t
123-
page_header_get_field(
124-
/*==================*/
125-
const page_t* page, /*!< in: page */
126-
ulint field) /*!< in: PAGE_LEVEL, ... */
127-
{
128-
ut_ad(page);
129-
ut_ad(field <= PAGE_INDEX_ID);
130-
131-
return(mach_read_from_2(page + PAGE_HEADER + field));
132-
}
133-
134107
#ifndef UNIV_INNOCHECKSUM
135108
/*************************************************************//**
136109
Sets the given header field. */
@@ -495,25 +468,6 @@ page_dir_set_n_heap(
495468
& page_header_get_field(page, PAGE_N_HEAP)));
496469
}
497470

498-
#ifdef UNIV_DEBUG
499-
/*************************************************************//**
500-
Gets pointer to nth directory slot.
501-
@return pointer to dir slot */
502-
UNIV_INLINE
503-
page_dir_slot_t*
504-
page_dir_get_nth_slot(
505-
/*==================*/
506-
const page_t* page, /*!< in: index page */
507-
ulint n) /*!< in: position */
508-
{
509-
ut_ad(page_dir_get_n_slots(page) > n);
510-
511-
return((page_dir_slot_t*)
512-
page + srv_page_size - PAGE_DIR
513-
- (n + 1) * PAGE_DIR_SLOT_SIZE);
514-
}
515-
#endif /* UNIV_DEBUG */
516-
517471
/**************************************************************//**
518472
Used to check the consistency of a record on a page.
519473
@return TRUE if succeed */

storage/innobase/include/ut0byte.h

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*****************************************************************************
22
33
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
4-
Copyright (c) 2019, MariaDB Corporation.
4+
Copyright (c) 2019, 2020, MariaDB Corporation.
55
66
This program is free software; you can redistribute it and/or modify it under
77
the terms of the GNU General Public License as published by the Free Software
@@ -27,8 +27,6 @@ Created 1/20/1994 Heikki Tuuri
2727
#ifndef ut0byte_h
2828
#define ut0byte_h
2929

30-
31-
3230
#include "univ.i"
3331

3432
/*******************************************************//**
@@ -62,28 +60,38 @@ ut_uint64_align_up(
6260
ib_uint64_t n, /*!< in: number to be rounded */
6361
ulint align_no); /*!< in: align by this number
6462
which must be a power of 2 */
65-
/*********************************************************//**
66-
The following function rounds down a pointer to the nearest
67-
aligned address.
63+
/** Round down a pointer to the nearest aligned address.
64+
@param ptr pointer
65+
@param alignment a power of 2
6866
@return aligned pointer */
69-
UNIV_INLINE
70-
void*
71-
ut_align_down(
72-
/*==========*/
73-
const void* ptr, /*!< in: pointer */
74-
ulint align_no) /*!< in: align by this number */
75-
MY_ATTRIBUTE((const));
76-
/*********************************************************//**
77-
The following function computes the offset of a pointer from the nearest
78-
aligned address.
67+
static inline void *ut_align_down(void *ptr, size_t alignment)
68+
{
69+
ut_ad(alignment > 0);
70+
ut_ad(ut_is_2pow(alignment));
71+
ut_ad(ptr);
72+
static_assert(sizeof ptr == sizeof(size_t), "compatibility");
73+
74+
return reinterpret_cast<void*>(reinterpret_cast<size_t>(ptr) &
75+
~(alignment - 1));
76+
}
77+
78+
static inline const void *ut_align_down(const void *ptr, size_t alignment)
79+
{
80+
return ut_align_down(const_cast<void*>(ptr), alignment);
81+
}
82+
83+
/** Compute the offset of a pointer from the nearest aligned address.
84+
@param ptr pointer
85+
@param alignment a power of 2
7986
@return distance from aligned pointer */
80-
UNIV_INLINE
81-
ulint
82-
ut_align_offset(
83-
/*============*/
84-
const void* ptr, /*!< in: pointer */
85-
ulint align_no) /*!< in: align by this number */
86-
MY_ATTRIBUTE((const));
87+
inline size_t ut_align_offset(const void *ptr, size_t alignment)
88+
{
89+
ut_ad(alignment > 0);
90+
ut_ad(ut_is_2pow(alignment));
91+
ut_ad(ptr);
92+
return reinterpret_cast<size_t>(ptr) & (alignment - 1);
93+
}
94+
8795
/*****************************************************************//**
8896
Gets the nth bit of a ulint.
8997
@return TRUE if nth bit is 1; 0th bit is defined to be the least significant */

storage/innobase/include/ut0byte.ic

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*****************************************************************************
22

33
Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved.
4-
Copyright (c) 2019, MariaDB Corporation.
4+
Copyright (c) 2019, 2020, MariaDB Corporation.
55

66
This program is free software; you can redistribute it and/or modify it under
77
the terms of the GNU General Public License as published by the Free Software
@@ -75,46 +75,6 @@ ut_uint64_align_up(
7575
return((n + align_1) & ~align_1);
7676
}
7777

78-
/*********************************************************//**
79-
The following function rounds down a pointer to the nearest
80-
aligned address.
81-
@return aligned pointer */
82-
UNIV_INLINE
83-
void*
84-
ut_align_down(
85-
/*==========*/
86-
const void* ptr, /*!< in: pointer */
87-
ulint align_no) /*!< in: align by this number */
88-
{
89-
ut_ad(align_no > 0);
90-
ut_ad(((align_no - 1) & align_no) == 0);
91-
ut_ad(ptr);
92-
93-
ut_ad(sizeof(void*) == sizeof(ulint));
94-
95-
return((void*)(((ulint) ptr) & ~(align_no - 1)));
96-
}
97-
98-
/*********************************************************//**
99-
The following function computes the offset of a pointer from the nearest
100-
aligned address.
101-
@return distance from aligned pointer */
102-
UNIV_INLINE
103-
ulint
104-
ut_align_offset(
105-
/*============*/
106-
const void* ptr, /*!< in: pointer */
107-
ulint align_no) /*!< in: align by this number */
108-
{
109-
ut_ad(align_no > 0);
110-
ut_ad(((align_no - 1) & align_no) == 0);
111-
ut_ad(ptr);
112-
113-
ut_ad(sizeof(void*) == sizeof(ulint));
114-
115-
return(((ulint) ptr) & (align_no - 1));
116-
}
117-
11878
/*****************************************************************//**
11979
Gets the nth bit of a ulint.
12080
@return TRUE if nth bit is 1; 0th bit is defined to be the least significant */

0 commit comments

Comments
 (0)