diff options
author | unknown <marko@hundin.mysql.fi> | 2005-04-25 10:14:35 +0300 |
---|---|---|
committer | unknown <marko@hundin.mysql.fi> | 2005-04-25 10:14:35 +0300 |
commit | 4a3a46af13ae0703f590ac058fc1df61aeb946b6 (patch) | |
tree | 4840b10eed2c1bb2f0170e733698fa1cc219e077 /innobase/include | |
parent | f51eb30b5a9f769ebe1af8cbd56fc6f3183d4bb3 (diff) | |
download | mariadb-git-4a3a46af13ae0703f590ac058fc1df61aeb946b6.tar.gz |
InnoDB: Performance optimizations based on OProfile analysis
innobase/btr/btr0btr.c:
Eliminate some buf_frame_align() calls.
Make use of the page_rec_is_infimum(), page_rec_is_supremum()
and page_rec_is_user_rec() functions.
Replace some index->table->comp with page_is_comp().
Eliminate some variables to reduce register spilling on x86.
Note that page_is_comp() may return nonzero instead of TRUE.
Note that rec_offs_comp() may return nonzero instead of TRUE.
innobase/btr/btr0cur.c:
Eliminate some buf_frame_align() calls.
Replace some index->table->comp with
page_is_comp() or rec_offs_comp().
Eliminate some variables to reduce register spilling on x86.
Note that page_is_comp() may return nonzero instead of TRUE.
Note that rec_offs_comp() may return nonzero instead of TRUE.
Remove an extra mem_heap_create() call from btr_cur_update_in_place().
Add "page" parameter to lock_rec_store_on_page_infimum().
Add some UNIV_LIKELY() and UNIV_UNLIKELY() hints.
btr_estimate_number_of_different_key_vals(): Rename the
offsets_* variables to be more descriptive and eliminate one
rec_get_offsets() and one page_rec_get_next() call in the loop.
innobase/btr/btr0pcur.c:
Eliminate some buf_frame_align() calls.
Make use of the page_rec_is_infimum(), page_rec_is_supremum()
and page_rec_is_user_rec() functions.
Replace some index->table->comp with page_is_comp().
Eliminate some variables to reduce register spilling on x86.
Note that page_is_comp() may return nonzero instead of TRUE.
Make some ut_a() assertions ut_ad() ones to improve performance.
Add some UNIV_LIKELY() and UNIV_UNLIKELY() hints.
innobase/btr/btr0sea.c:
Make use of page_rec_is_infimum() and page_rec_is_supremum().
Eliminate some buf_frame_align() calls.
Add some UNIV_UNLIKELY and UNIV_LIKELY hints.
Turn some assertions into debug assertions.
innobase/dict/dict0crea.c:
Replace FALSE/TRUE ibool comp with zero/nonzero ulint comp
innobase/ibuf/ibuf0ibuf.c:
Make use of page_rec_is_infimum() and page_rec_is_supremum().
Add some UNIV_UNLIKELY and UNIV_LIKELY hints.
ibuf_get_merge_page_nos(): Rename parameter "first_rec" to "rec"
and eliminate local variable "rec".
innobase/include/btr0btr.h:
Replace FALSE/TRUE ibool comp with zero/nonzero ulint comp
innobase/include/buf0buf.h:
Rename buf_frame_get_modify_clock()
to buf_block_get_modify_clock().
innobase/include/buf0buf.ic:
Rename buf_frame_get_modify_clock()
to buf_block_get_modify_clock() and
remove the buf_block_align() call.
innobase/include/lock0lock.h:
lock_rec_store_on_page_infimum(): Add parameter "page"
innobase/include/mach0data.h:
Add mach_encode_2() and mach_decode_2().
innobase/include/mach0data.ic:
Add mach_encode_2() and mach_decode_2().
innobase/include/page0cur.h:
Add const qualifier to page_cur_is_before_first()
and page_cur_is_after_last().
innobase/include/page0cur.ic:
Make use of page_rec_is_infimum() and page_rec_is_supremum().
innobase/include/page0page.h:
Remove page_rec_is_first_user_rec() and page_rec_is_last_user_rec().
Add page_rec_is_infimum() and page_rec_is_supremum().
Replace FALSE/TRUE ibool comp with zero/nonzero ulint comp.
innobase/include/page0page.ic:
Remove page_rec_is_first_user_rec() and page_rec_is_last_user_rec().
Add page_rec_is_infimum() and page_rec_is_supremum().
Replace FALSE/TRUE ibool comp with zero/nonzero ulint comp.
Add UNIV_UNLIKELY, UNIV_LIKELY and UNIV_EXPECT hints.
Reduce the number of buf_frame_align() calls.
innobase/include/rem0rec.ic:
rec_offs_comp(): Return zero or nonzero instead of FALSE or TRUE.
innobase/include/row0mysql.h:
Replace FALSE/TRUE ibool comp with zero/nonzero ulint comp.
innobase/lock/lock0lock.c:
Replace FALSE/TRUE ibool comp with zero/nonzero ulint comp.
Remove parameter "comp" from lock_rec_get_next(),
lock_rec_has_expl() and lock_rec_other_has_expl_req().
Add parameter "page" to lock_rec_store_on_page_infimum().
Add UNIV_UNLIKELY hints.
Reduce the number of buf_frame_align() calls.
Make use of page_rec_is_infimum(), page_rec_is_supremum() and
page_rec_is_user_rec().
Move the "comp" flag outside some loops.
innobase/mtr/mtr0log.c:
Replace index->table->comp with page_rec_is_comp().
innobase/page/page0cur.c:
Replace index->table->comp with page_is_comp() or page_rec_is_comp().
Eliminate some buf_frame_align() calls.
Add some debug assertions.
innobase/page/page0page.c:
Optimize page_dir_find_owner_slot(). Compare the record offset
16 bits at a time, because that seems to be the only way to avoid
register spilling on x86.
Replace FALSE/TRUE ibool comp with zero/nonzero ulint comp.
Remove parameter "page" of page_delete_rec_list_write_log().
Make use of page_rec_is_infimum().
innobase/rem/rem0cmp.c:
Replace FALSE/TRUE ibool comp with zero/nonzero ulint comp.
innobase/row/row0ins.c:
Make use of page_rec_is_infimum() and page_rec_is_supremum().
Reduce the amount of buf_frame_align() calls.
row_ins_index_entry_low(): Disable assertion about column count
unless #ifdef UNIV_DEBUG.
innobase/row/row0mysql.c:
Replace FALSE/TRUE ibool comp with zero/nonzero ulint comp.
innobase/row/row0row.c:
Eliminate some buf_frame_align() calls.
Make use of page_rec_is_infimum().
innobase/row/row0sel.c:
Make use of page_rec_is_supremum() and page_rec_is_infimum().
Turn some assertions into debug assertions.
Add UNIV_LIKELY and UNIV_UNLIKELY hints.
row_search_for_mysql(): Eliminate local variables "moved",
"cons_read_requires_clust_rec", "was_lock_wait", "shortcut",
"success" and "comp". Replace some of them with goto's.
Disable variable "cnt" unless #ifdef UNIV_SEARCH_DEBUG.
innobase/row/row0vers.c:
Replace FALSE/TRUE ibool comp with zero/nonzero ulint comp.
Replace index->table->comp with page_rec_is_comp().
Eliminate some buf_frame_align() calls.
Diffstat (limited to 'innobase/include')
-rw-r--r-- | innobase/include/btr0btr.h | 6 | ||||
-rw-r--r-- | innobase/include/buf0buf.h | 4 | ||||
-rw-r--r-- | innobase/include/buf0buf.ic | 10 | ||||
-rw-r--r-- | innobase/include/lock0lock.h | 1 | ||||
-rw-r--r-- | innobase/include/mach0data.h | 21 | ||||
-rw-r--r-- | innobase/include/mach0data.ic | 31 | ||||
-rw-r--r-- | innobase/include/page0cur.h | 8 | ||||
-rw-r--r-- | innobase/include/page0cur.ic | 22 | ||||
-rw-r--r-- | innobase/include/page0page.h | 68 | ||||
-rw-r--r-- | innobase/include/page0page.ic | 268 | ||||
-rw-r--r-- | innobase/include/rem0rec.ic | 6 | ||||
-rw-r--r-- | innobase/include/row0mysql.h | 2 |
12 files changed, 259 insertions, 188 deletions
diff --git a/innobase/include/btr0btr.h b/innobase/include/btr0btr.h index 23116d24288..1f3a32fa70c 100644 --- a/innobase/include/btr0btr.h +++ b/innobase/include/btr0btr.h @@ -168,7 +168,7 @@ btr_create( ulint type, /* in: type of the index */ ulint space, /* in: space where created */ dulint index_id,/* in: index id */ - ibool comp, /* in: TRUE=compact page format */ + ulint comp, /* in: nonzero=compact page format */ mtr_t* mtr); /* in: mini-transaction handle */ /**************************************************************** Frees a B-tree except the root page, which MUST be freed after this @@ -276,7 +276,7 @@ void btr_set_min_rec_mark( /*=================*/ rec_t* rec, /* in: record */ - ibool comp, /* in: TRUE=compact page format */ + ulint comp, /* in: nonzero=compact page format */ mtr_t* mtr); /* in: mtr */ /***************************************************************** Deletes on the upper level the node pointer to a page. */ @@ -336,7 +336,7 @@ btr_parse_set_min_rec_mark( /* out: end of log record or NULL */ byte* ptr, /* in: buffer */ byte* end_ptr,/* in: buffer end */ - ibool comp, /* in: TRUE=compact page format */ + ulint comp, /* in: nonzero=compact page format */ page_t* page, /* in: page or NULL */ mtr_t* mtr); /* in: mtr or NULL */ /*************************************************************** diff --git a/innobase/include/buf0buf.h b/innobase/include/buf0buf.h index 5ee323f1b1e..7b8e1b7bb09 100644 --- a/innobase/include/buf0buf.h +++ b/innobase/include/buf0buf.h @@ -382,10 +382,10 @@ Returns the value of the modify clock. The caller must have an s-lock or x-lock on the block. */ UNIV_INLINE dulint -buf_frame_get_modify_clock( +buf_block_get_modify_clock( /*=======================*/ /* out: value */ - buf_frame_t* frame); /* in: pointer to a frame */ + buf_block_t* block); /* in: block */ /************************************************************************ Calculates a page checksum which is stored to the page when it is written to a file. Note that we must be careful to calculate the same value diff --git a/innobase/include/buf0buf.ic b/innobase/include/buf0buf.ic index 803b20560bf..9044c3251a4 100644 --- a/innobase/include/buf0buf.ic +++ b/innobase/include/buf0buf.ic @@ -481,17 +481,11 @@ Returns the value of the modify clock. The caller must have an s-lock or x-lock on the block. */ UNIV_INLINE dulint -buf_frame_get_modify_clock( +buf_block_get_modify_clock( /*=======================*/ /* out: value */ - buf_frame_t* frame) /* in: pointer to a frame */ + buf_block_t* block) /* in: block */ { - buf_block_t* block; - - ut_ad(frame); - - block = buf_block_align(frame); - #ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED) || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE)); diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h index 710c945375c..9830c8abfc6 100644 --- a/innobase/include/lock0lock.h +++ b/innobase/include/lock0lock.h @@ -216,6 +216,7 @@ actual record is being moved. */ void lock_rec_store_on_page_infimum( /*===========================*/ + page_t* page, /* in: page containing the record */ rec_t* rec); /* in: record whose lock state is stored on the infimum record of the same page; lock bits are reset on the record */ diff --git a/innobase/include/mach0data.h b/innobase/include/mach0data.h index 7ad760cd60f..f9a3ff521d5 100644 --- a/innobase/include/mach0data.h +++ b/innobase/include/mach0data.h @@ -52,6 +52,27 @@ mach_read_from_2( /*=============*/ /* out: ulint integer, >= 0, < 64k */ byte* b); /* in: pointer to two bytes */ + +/************************************************************ +The following function is used to convert a 16-bit data item +to the canonical format, for fast bytewise equality test +against memory. */ +UNIV_INLINE +uint16 +mach_encode_2( +/*==========*/ + /* out: 16-bit integer in canonical format */ + ulint n); /* in: integer in machine-dependent format */ +/************************************************************ +The following function is used to convert a 16-bit data item +from the canonical format, for fast bytewise equality test +against memory. */ +UNIV_INLINE +ulint +mach_decode_2( +/*==========*/ + /* out: integer in machine-dependent format */ + uint16 n); /* in: 16-bit integer in canonical format */ /*********************************************************** The following function is used to store data in 3 consecutive bytes. We store the most significant byte to the lowest address. */ diff --git a/innobase/include/mach0data.ic b/innobase/include/mach0data.ic index 3ffb9baa344..888f3f743e4 100644 --- a/innobase/include/mach0data.ic +++ b/innobase/include/mach0data.ic @@ -68,6 +68,37 @@ mach_read_from_2( ); } +/************************************************************ +The following function is used to convert a 16-bit data item +to the canonical format, for fast bytewise equality test +against memory. */ +UNIV_INLINE +uint16 +mach_encode_2( +/*==========*/ + /* out: 16-bit integer in canonical format */ + ulint n) /* in: integer in machine-dependent format */ +{ + uint16 ret; + ut_ad(2 == sizeof ret); + mach_write_to_2((byte*) &ret, n); + return(ret); +} +/************************************************************ +The following function is used to convert a 16-bit data item +from the canonical format, for fast bytewise equality test +against memory. */ +UNIV_INLINE +ulint +mach_decode_2( +/*==========*/ + /* out: integer in machine-dependent format */ + uint16 n) /* in: 16-bit integer in canonical format */ +{ + ut_ad(2 == sizeof n); + return(mach_read_from_2((byte*) &n)); +} + /*********************************************************** The following function is used to store data in 3 consecutive bytes. We store the most significant byte to the lowest address. */ diff --git a/innobase/include/page0cur.h b/innobase/include/page0cur.h index 4fc62f37db7..e89e740e775 100644 --- a/innobase/include/page0cur.h +++ b/innobase/include/page0cur.h @@ -78,16 +78,16 @@ UNIV_INLINE ibool page_cur_is_before_first( /*=====================*/ - /* out: TRUE if at start */ - page_cur_t* cur); /* in: cursor */ + /* out: TRUE if at start */ + const page_cur_t* cur); /* in: cursor */ /************************************************************* Returns TRUE if the cursor is after last user record. */ UNIV_INLINE ibool page_cur_is_after_last( /*===================*/ - /* out: TRUE if at end */ - page_cur_t* cur); /* in: cursor */ + /* out: TRUE if at end */ + const page_cur_t* cur); /* in: cursor */ /************************************************************** Positions the cursor on the given record. */ UNIV_INLINE diff --git a/innobase/include/page0cur.ic b/innobase/include/page0cur.ic index e99d799b372..f8346819e84 100644 --- a/innobase/include/page0cur.ic +++ b/innobase/include/page0cur.ic @@ -69,15 +69,10 @@ UNIV_INLINE ibool page_cur_is_before_first( /*=====================*/ - /* out: TRUE if at start */ - page_cur_t* cur) /* in: cursor */ + /* out: TRUE if at start */ + const page_cur_t* cur) /* in: cursor */ { - if (page_get_infimum_rec(page_cur_get_page(cur)) == cur->rec) { - - return(TRUE); - } - - return(FALSE); + return(page_rec_is_infimum(cur->rec)); } /************************************************************* @@ -86,15 +81,10 @@ UNIV_INLINE ibool page_cur_is_after_last( /*===================*/ - /* out: TRUE if at end */ - page_cur_t* cur) /* in: cursor */ + /* out: TRUE if at end */ + const page_cur_t* cur) /* in: cursor */ { - if (page_get_supremum_rec(page_cur_get_page(cur)) == cur->rec) { - - return(TRUE); - } - - return(FALSE); + return(page_rec_is_supremum(cur->rec)); } /************************************************************** diff --git a/innobase/include/page0page.h b/innobase/include/page0page.h index 144c297b811..c4ffa39d3ac 100644 --- a/innobase/include/page0page.h +++ b/innobase/include/page0page.h @@ -373,13 +373,21 @@ page_dir_find_owner_slot( /**************************************************************** Determine whether the page is in new-style compact format. */ UNIV_INLINE -ibool +ulint page_is_comp( /*=========*/ - /* out: TRUE if the page is in compact format - FALSE if it is in old-style format */ + /* out: nonzero if the page is in compact + format, zero if it is in old-style format */ page_t* page); /* in: index page */ /**************************************************************** +TRUE if the record is on a page in compact format. */ +UNIV_INLINE +ulint +page_rec_is_comp( +/*=============*/ + /* out: nonzero if in compact format */ + const rec_t* rec); /* in: record */ +/**************************************************************** Gets the pointer to the next record on the page. */ UNIV_INLINE rec_t* @@ -407,47 +415,55 @@ page_rec_get_prev( /* out: pointer to previous record */ rec_t* rec); /* in: pointer to record, must not be page infimum */ - /**************************************************************** TRUE if the record is a user record on the page. */ UNIV_INLINE ibool -page_rec_is_user_rec( -/*=================*/ +page_rec_is_user_rec_low( +/*=====================*/ /* out: TRUE if a user record */ - rec_t* rec); /* in: record */ + ulint offset);/* in: record offset on page */ /**************************************************************** TRUE if the record is the supremum record on a page. */ UNIV_INLINE ibool -page_rec_is_supremum( -/*=================*/ +page_rec_is_supremum_low( +/*=====================*/ /* out: TRUE if the supremum record */ - rec_t* rec); /* in: record */ + ulint offset);/* in: record offset on page */ /**************************************************************** TRUE if the record is the infimum record on a page. */ UNIV_INLINE ibool -page_rec_is_infimum( -/*================*/ +page_rec_is_infimum_low( +/*=====================*/ /* out: TRUE if the infimum record */ - rec_t* rec); /* in: record */ + ulint offset);/* in: record offset on page */ + /**************************************************************** -TRUE if the record is the first user record on the page. */ +TRUE if the record is a user record on the page. */ UNIV_INLINE ibool -page_rec_is_first_user_rec( -/*=======================*/ - /* out: TRUE if first user record */ - rec_t* rec); /* in: record */ +page_rec_is_user_rec( +/*=================*/ + /* out: TRUE if a user record */ + const rec_t* rec); /* in: record */ /**************************************************************** -TRUE if the record is the last user record on the page. */ +TRUE if the record is the supremum record on a page. */ UNIV_INLINE ibool -page_rec_is_last_user_rec( -/*======================*/ - /* out: TRUE if last user record */ - rec_t* rec); /* in: record */ +page_rec_is_supremum( +/*=================*/ + /* out: TRUE if the supremum record */ + const rec_t* rec); /* in: record */ +/**************************************************************** +TRUE if the record is the infimum record on a page. */ +UNIV_INLINE +ibool +page_rec_is_infimum( +/*================*/ + /* out: TRUE if the infimum record */ + const rec_t* rec); /* in: record */ /******************************************************************* Looks for the record which owns the given record. */ UNIV_INLINE @@ -495,7 +511,7 @@ ulint page_get_free_space_of_empty( /*=========================*/ /* out: free space */ - ibool comp) /* in: TRUE=compact page format */ + ulint comp) /* in: nonzero=compact page format */ __attribute__((const)); /**************************************************************** Returns the sum of the sizes of the records in the record list @@ -539,7 +555,7 @@ page_create( buf_frame_t* frame, /* in: a buffer frame where the page is created */ mtr_t* mtr, /* in: mini-transaction handle */ - ibool comp); /* in: TRUE=compact page format */ + ulint comp); /* in: nonzero=compact page format */ /***************************************************************** Differs from page_copy_rec_list_end, because this function does not touch the lock table and max trx id on page. */ @@ -673,7 +689,7 @@ page_parse_create( /* out: end of log record or NULL */ byte* ptr, /* in: buffer */ byte* end_ptr,/* in: buffer end */ - ibool comp, /* in: TRUE=compact page format */ + ulint comp, /* in: nonzero=compact page format */ page_t* page, /* in: page or NULL */ mtr_t* mtr); /* in: mtr or NULL */ /**************************************************************** diff --git a/innobase/include/page0page.ic b/innobase/include/page0page.ic index bc0805ca30c..8299d160b28 100644 --- a/innobase/include/page0page.ic +++ b/innobase/include/page0page.ic @@ -155,14 +155,27 @@ page_header_reset_last_insert( /**************************************************************** Determine whether the page is in new-style compact format. */ UNIV_INLINE -ibool +ulint page_is_comp( /*=========*/ - /* out: TRUE if the page is in compact format - FALSE if it is in old-style format */ - page_t* page) /* in: index page */ + /* out: nonzero if the page is in compact + format, zero if it is in old-style format */ + page_t* page) /* in: index page */ +{ + return(UNIV_EXPECT(page_header_get_field(page, PAGE_N_HEAP) & 0x8000, + 0x8000)); +} + +/**************************************************************** +TRUE if the record is on a page in compact format. */ +UNIV_INLINE +ulint +page_rec_is_comp( +/*=============*/ + /* out: nonzero if in compact format */ + const rec_t* rec) /* in: record */ { - return(!!(page_header_get_field(page, PAGE_N_HEAP) & 0x8000)); + return(page_is_comp(ut_align_down((rec_t*) rec, UNIV_PAGE_SIZE))); } /**************************************************************** @@ -205,112 +218,107 @@ page_get_supremum_rec( TRUE if the record is a user record on the page. */ UNIV_INLINE ibool -page_rec_is_user_rec( -/*=================*/ +page_rec_is_user_rec_low( +/*=====================*/ /* out: TRUE if a user record */ - rec_t* rec) /* in: record */ + ulint offset) /* in: record offset on page */ { - ut_ad(rec); - - if (rec == page_get_supremum_rec(buf_frame_align(rec))) { - - return(FALSE); - } - - if (rec == page_get_infimum_rec(buf_frame_align(rec))) { - - return(FALSE); - } + ut_ad(offset >= PAGE_NEW_INFIMUM); +#if PAGE_OLD_INFIMUM < PAGE_NEW_INFIMUM +# error "PAGE_OLD_INFIMUM < PAGE_NEW_INFIMUM" +#endif +#if PAGE_OLD_SUPREMUM < PAGE_NEW_SUPREMUM +# error "PAGE_OLD_SUPREMUM < PAGE_NEW_SUPREMUM" +#endif +#if PAGE_NEW_INFIMUM > PAGE_OLD_SUPREMUM +# error "PAGE_NEW_INFIMUM > PAGE_OLD_SUPREMUM" +#endif +#if PAGE_OLD_INFIMUM > PAGE_NEW_SUPREMUM +# error "PAGE_OLD_INFIMUM > PAGE_NEW_SUPREMUM" +#endif +#if PAGE_NEW_SUPREMUM > PAGE_OLD_SUPREMUM_END +# error "PAGE_NEW_SUPREMUM > PAGE_OLD_SUPREMUM_END" +#endif +#if PAGE_OLD_SUPREMUM > PAGE_NEW_SUPREMUM_END +# error "PAGE_OLD_SUPREMUM > PAGE_NEW_SUPREMUM_END" +#endif + ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START); - return(TRUE); + return(UNIV_LIKELY(offset != PAGE_NEW_SUPREMUM) + && UNIV_LIKELY(offset != PAGE_NEW_INFIMUM) + && UNIV_LIKELY(offset != PAGE_OLD_INFIMUM) + && UNIV_LIKELY(offset != PAGE_OLD_SUPREMUM)); } /**************************************************************** TRUE if the record is the supremum record on a page. */ UNIV_INLINE ibool -page_rec_is_supremum( -/*=================*/ +page_rec_is_supremum_low( +/*=====================*/ /* out: TRUE if the supremum record */ - rec_t* rec) /* in: record */ + ulint offset) /* in: record offset on page */ { - ut_ad(rec); + ut_ad(offset >= PAGE_NEW_INFIMUM); + ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START); - if (rec == page_get_supremum_rec(buf_frame_align(rec))) { - - return(TRUE); - } - - return(FALSE); + return(UNIV_UNLIKELY(offset == PAGE_NEW_SUPREMUM) + || UNIV_UNLIKELY(offset == PAGE_OLD_SUPREMUM)); } /**************************************************************** TRUE if the record is the infimum record on a page. */ UNIV_INLINE ibool -page_rec_is_infimum( -/*================*/ +page_rec_is_infimum_low( +/*=====================*/ /* out: TRUE if the infimum record */ - rec_t* rec) /* in: record */ + ulint offset) /* in: record offset on page */ { - ut_ad(rec); - - if (rec == page_get_infimum_rec(buf_frame_align(rec))) { - - return(TRUE); - } + ut_ad(offset >= PAGE_NEW_INFIMUM); + ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START); - return(FALSE); + return(UNIV_UNLIKELY(offset == PAGE_NEW_INFIMUM) + || UNIV_UNLIKELY(offset == PAGE_OLD_INFIMUM)); } /**************************************************************** -TRUE if the record is the first user record on the page. */ +TRUE if the record is a user record on the page. */ UNIV_INLINE ibool -page_rec_is_first_user_rec( -/*=======================*/ - /* out: TRUE if first user record */ - rec_t* rec) /* in: record */ +page_rec_is_user_rec( +/*=================*/ + /* out: TRUE if a user record */ + const rec_t* rec) /* in: record */ { - ut_ad(rec); - - if (rec == page_get_supremum_rec(buf_frame_align(rec))) { - - return(FALSE); - } - - if (rec == page_rec_get_next( - page_get_infimum_rec(buf_frame_align(rec)))) { - - return(TRUE); - } - - return(FALSE); + return(page_rec_is_user_rec_low( + ut_align_offset(rec, UNIV_PAGE_SIZE))); } /**************************************************************** -TRUE if the record is the last user record on the page. */ +TRUE if the record is the supremum record on a page. */ UNIV_INLINE ibool -page_rec_is_last_user_rec( -/*======================*/ - /* out: TRUE if last user record */ - rec_t* rec) /* in: record */ +page_rec_is_supremum( +/*=================*/ + /* out: TRUE if the supremum record */ + const rec_t* rec) /* in: record */ { - ut_ad(rec); - - if (rec == page_get_supremum_rec(buf_frame_align(rec))) { - - return(FALSE); - } - - if (page_rec_get_next(rec) - == page_get_supremum_rec(buf_frame_align(rec))) { - - return(TRUE); - } + return(page_rec_is_supremum_low( + ut_align_offset(rec, UNIV_PAGE_SIZE))); +} - return(FALSE); +/**************************************************************** +TRUE if the record is the infimum record on a page. */ +UNIV_INLINE +ibool +page_rec_is_infimum( +/*================*/ + /* out: TRUE if the infimum record */ + const rec_t* rec) /* in: record */ +{ + return(page_rec_is_infimum_low( + ut_align_offset(rec, UNIV_PAGE_SIZE))); } /***************************************************************** @@ -340,22 +348,26 @@ page_cmp_dtuple_rec_with_match( matched; when function returns contains the value for current comparison */ { - page_t* page; + ulint rec_offset; ut_ad(dtuple_check_typed(dtuple)); ut_ad(rec_offs_validate(rec, NULL, offsets)); + ut_ad(!rec_offs_comp(offsets) == !page_rec_is_comp(rec)); - page = buf_frame_align(rec); + rec_offset = ut_align_offset(rec, UNIV_PAGE_SIZE); - if (rec == page_get_infimum_rec(page)) { + if (UNIV_UNLIKELY(rec_offset == PAGE_NEW_INFIMUM) + || UNIV_UNLIKELY(rec_offset == PAGE_OLD_INFIMUM)) { return(1); - } else if (rec == page_get_supremum_rec(page)) { + } + if (UNIV_UNLIKELY(rec_offset == PAGE_NEW_SUPREMUM) + || UNIV_UNLIKELY(rec_offset == PAGE_OLD_SUPREMUM)) { return(-1); - } else { - return(cmp_dtuple_rec_with_match(dtuple, rec, offsets, + } + + return(cmp_dtuple_rec_with_match(dtuple, rec, offsets, matched_fields, matched_bytes)); - } } /***************************************************************** @@ -482,7 +494,7 @@ page_dir_slot_set_rec( { ut_ad(page_rec_check(rec)); - mach_write_to_2(slot, rec - buf_frame_align(rec)); + mach_write_to_2(slot, ut_align_offset(rec, UNIV_PAGE_SIZE)); } /******************************************************************* @@ -494,8 +506,8 @@ page_dir_slot_get_n_owned( /* out: number of records */ page_dir_slot_t* slot) /* in: page directory slot */ { - return(rec_get_n_owned(page_dir_slot_get_rec(slot), - page_is_comp(buf_frame_align(slot)))); + rec_t* rec = page_dir_slot_get_rec(slot); + return(rec_get_n_owned(rec, page_rec_is_comp(rec))); } /******************************************************************* @@ -508,8 +520,8 @@ page_dir_slot_set_n_owned( ulint n) /* in: number of records owned by the slot */ { - rec_set_n_owned(page_dir_slot_get_rec(slot), - page_is_comp(buf_frame_align(slot)), n); + rec_t* rec = page_dir_slot_get_rec(slot); + rec_set_n_owned(rec, page_rec_is_comp(rec), n); } /**************************************************************** @@ -540,26 +552,25 @@ page_rec_get_next( ut_ad(page_rec_check(rec)); - page = buf_frame_align(rec); + page = ut_align_down(rec, UNIV_PAGE_SIZE); offs = rec_get_next_offs(rec, page_is_comp(page)); - if (offs >= UNIV_PAGE_SIZE) { + if (UNIV_UNLIKELY(offs >= UNIV_PAGE_SIZE)) { fprintf(stderr, -"InnoDB: Next record offset is nonsensical %lu in record at offset %lu\n", - (ulong)offs, (ulong)(rec - page)); - fprintf(stderr, -"\nInnoDB: rec address %p, first buffer frame %p\n" +"InnoDB: Next record offset is nonsensical %lu in record at offset %lu\n" +"InnoDB: rec address %p, first buffer frame %p\n" "InnoDB: buffer pool high end %p, buf fix count %lu\n", + (ulong)offs, (ulong)(rec - page), rec, buf_pool->frame_zero, buf_pool->high_end, (ulong)buf_block_align(rec)->buf_fix_count); buf_page_print(page); - ut_a(0); + ut_error; } - if (offs == 0) { + if (UNIV_UNLIKELY(offs == 0)) { return(NULL); } @@ -581,15 +592,12 @@ page_rec_set_next( ulint offs; ut_ad(page_rec_check(rec)); - ut_a((next == NULL) - || (buf_frame_align(rec) == buf_frame_align(next))); - - page = buf_frame_align(rec); - - ut_ad(rec != page_get_supremum_rec(page)); - ut_ad(next != page_get_infimum_rec(page)); + ut_ad(!page_rec_is_supremum(rec)); + ut_ad(!page_rec_is_infimum(next)); + page = ut_align_down(rec, UNIV_PAGE_SIZE); if (next) { + ut_a(page == ut_align_down(next, UNIV_PAGE_SIZE)); offs = (ulint) (next - page); } else { offs = 0; @@ -613,13 +621,12 @@ page_rec_get_prev( rec_t* rec2; rec_t* prev_rec = NULL; page_t* page; - ibool comp; ut_ad(page_rec_check(rec)); page = buf_frame_align(rec); - ut_ad(rec != page_get_infimum_rec(page)); + ut_ad(!page_rec_is_infimum(rec)); slot_no = page_dir_find_owner_slot(rec); @@ -628,7 +635,6 @@ page_rec_get_prev( slot = page_dir_get_nth_slot(page, slot_no - 1); rec2 = page_dir_slot_get_rec(slot); - comp = page_is_comp(page); while (rec != rec2) { prev_rec = rec2; @@ -649,13 +655,16 @@ page_rec_find_owner_rec( /* out: the owner record */ rec_t* rec) /* in: the physical record */ { - ibool comp; - ut_ad(page_rec_check(rec)); - comp = page_is_comp(buf_frame_align(rec)); - while (rec_get_n_owned(rec, comp) == 0) { - rec = page_rec_get_next(rec); + if (page_rec_is_comp(rec)) { + while (rec_get_n_owned(rec, TRUE) == 0) { + rec = page_rec_get_next(rec); + } + } else { + while (rec_get_n_owned(rec, FALSE) == 0) { + rec = page_rec_get_next(rec); + } } return(rec); @@ -691,10 +700,17 @@ ulint page_get_free_space_of_empty( /*=========================*/ /* out: free space */ - ibool comp) /* in: TRUE=compact page layout */ + ulint comp) /* in: nonzero=compact page layout */ { + if (UNIV_LIKELY(comp)) { + return((ulint)(UNIV_PAGE_SIZE + - PAGE_NEW_SUPREMUM_END + - PAGE_DIR + - 2 * PAGE_DIR_SLOT_SIZE)); + } + return((ulint)(UNIV_PAGE_SIZE - - (comp ? PAGE_NEW_SUPREMUM_END : PAGE_OLD_SUPREMUM_END) + - PAGE_OLD_SUPREMUM_END - PAGE_DIR - 2 * PAGE_DIR_SLOT_SIZE)); } @@ -716,17 +732,21 @@ page_get_max_insert_size( { ulint occupied; ulint free_space; - ibool comp; - comp = page_is_comp(page); + if (page_is_comp(page)) { + occupied = page_header_get_field(page, PAGE_HEAP_TOP) + - PAGE_NEW_SUPREMUM_END + page_dir_calc_reserved_space( + n_recs + page_dir_get_n_heap(page) - 2); - occupied = page_header_get_field(page, PAGE_HEAP_TOP) - - (comp ? PAGE_NEW_SUPREMUM_END : PAGE_OLD_SUPREMUM_END) - + page_dir_calc_reserved_space( + free_space = page_get_free_space_of_empty(TRUE); + } else { + occupied = page_header_get_field(page, PAGE_HEAP_TOP) + - PAGE_OLD_SUPREMUM_END + page_dir_calc_reserved_space( n_recs + page_dir_get_n_heap(page) - 2); - free_space = page_get_free_space_of_empty(comp); - + free_space = page_get_free_space_of_empty(FALSE); + } + /* Above the 'n_recs +' part reserves directory space for the new inserted records; the '- 2' excludes page infimum and supremum records */ @@ -752,14 +772,11 @@ page_get_max_insert_size_after_reorganize( { ulint occupied; ulint free_space; - ibool comp; - comp = page_is_comp(page); - occupied = page_get_data_size(page) + page_dir_calc_reserved_space(n_recs + page_get_n_recs(page)); - free_space = page_get_free_space_of_empty(comp); + free_space = page_get_free_space_of_empty(page_is_comp(page)); if (occupied > free_space) { @@ -783,6 +800,7 @@ page_mem_free( ulint garbage; ut_ad(rec_offs_validate(rec, NULL, offsets)); + ut_ad(!rec_offs_comp(offsets) == !page_rec_is_comp(rec)); free = page_header_get_ptr(page, PAGE_FREE); page_rec_set_next(rec, free); diff --git a/innobase/include/rem0rec.ic b/innobase/include/rem0rec.ic index cd742aef6a6..85e196bbcf8 100644 --- a/innobase/include/rem0rec.ic +++ b/innobase/include/rem0rec.ic @@ -929,14 +929,14 @@ rec_get_nth_field( Determine if the offsets are for a record in the new compact format. */ UNIV_INLINE -ibool +ulint rec_offs_comp( /*==========*/ - /* out: TRUE if compact format */ + /* out: nonzero if compact format */ const ulint* offsets)/* in: array returned by rec_get_offsets() */ { ut_ad(rec_offs_validate(NULL, NULL, offsets)); - return((*rec_offs_base(offsets) & REC_OFFS_COMPACT) != 0); + return(*rec_offs_base(offsets) & REC_OFFS_COMPACT); } /********************************************************** diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index 277089430d4..28e94fad68f 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -110,7 +110,7 @@ row_mysql_store_col_in_innobase_format( necessarily the length of the actual payload data; if the column is a true VARCHAR then this is irrelevant */ - ibool comp); /* in: TRUE = compact format */ + ulint comp); /* in: nonzero=compact format */ /******************************************************************** Handles user errors and lock waits detected by the database engine. */ |