diff options
Diffstat (limited to 'storage/xtradb/include/fsp0fsp.ic')
-rw-r--r-- | storage/xtradb/include/fsp0fsp.ic | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/storage/xtradb/include/fsp0fsp.ic b/storage/xtradb/include/fsp0fsp.ic new file mode 100644 index 00000000000..0d81e817cc9 --- /dev/null +++ b/storage/xtradb/include/fsp0fsp.ic @@ -0,0 +1,314 @@ +/***************************************************************************** + +Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved. + +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 +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA + +*****************************************************************************/ + +/**************************************************//** +@file include/fsp0fsp.ic +File space management + +Created 12/18/1995 Heikki Tuuri +*******************************************************/ + +#ifndef UNIV_INNOCHECKSUM + +/***********************************************************************//** +Checks if a page address is an extent descriptor page address. +@return TRUE if a descriptor page */ +UNIV_INLINE +ibool +fsp_descr_page( +/*===========*/ + ulint zip_size,/*!< in: compressed page size in bytes; + 0 for uncompressed pages */ + ulint page_no)/*!< in: page number */ +{ + ut_ad(ut_is_2pow(zip_size)); + + if (!zip_size) { + return((page_no & (UNIV_PAGE_SIZE - 1)) == FSP_XDES_OFFSET); + } + + return((page_no & (zip_size - 1)) == FSP_XDES_OFFSET); +} + +/********************************************************************//** +Validate and return the tablespace flags, which are stored in the +tablespace header at offset FSP_SPACE_FLAGS. They should be 0 for +ROW_FORMAT=COMPACT and ROW_FORMAT=REDUNDANT. The newer row formats, +COMPRESSED and DYNAMIC, use a file format > Antelope so they should +have a file format number plus the DICT_TF_COMPACT bit set. +@return true if check ok */ +UNIV_INLINE +bool +fsp_flags_is_valid( +/*===============*/ + ulint flags) /*!< in: tablespace flags */ +{ + ulint post_antelope = FSP_FLAGS_GET_POST_ANTELOPE(flags); + ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(flags); + ulint atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(flags); + ulint page_ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags); + ulint unused = FSP_FLAGS_GET_UNUSED(flags); + + DBUG_EXECUTE_IF("fsp_flags_is_valid_failure", return(false);); + + /* fsp_flags is zero unless atomic_blobs is set. */ + /* Make sure there are no bits that we do not know about. */ + if (unused != 0 || flags == 1) { + return(false); + } else if (post_antelope) { + /* The Antelope row formats REDUNDANT and COMPACT did + not use tablespace flags, so this flag and the entire + 4-byte field is zero for Antelope row formats. */ + + if (!atomic_blobs) { + return(false); + } + } + + if (!atomic_blobs) { + /* Barracuda row formats COMPRESSED and DYNAMIC build on + the page structure introduced for the COMPACT row format + by allowing long fields to be broken into prefix and + externally stored parts. */ + + if (post_antelope || zip_ssize != 0) { + return(false); + } + + } else if (!post_antelope || zip_ssize > PAGE_ZIP_SSIZE_MAX) { + return(false); + } else if (page_ssize > UNIV_PAGE_SSIZE_MAX) { + + /* The page size field can be used for any row type, or it may + be zero for an original 16k page size. + Validate the page shift size is within allowed range. */ + + return(false); + + } else if (UNIV_PAGE_SIZE != UNIV_PAGE_SIZE_ORIG && !page_ssize) { + return(false); + } + +#if UNIV_FORMAT_MAX != UNIV_FORMAT_B +# error "UNIV_FORMAT_MAX != UNIV_FORMAT_B, Add more validations." +#endif + + /* The DATA_DIR field can be used for any row type so there is + nothing here to validate. */ + + return(true); +} + +/********************************************************************//** +Determine if the tablespace is compressed from dict_table_t::flags. +@return TRUE if compressed, FALSE if not compressed */ +UNIV_INLINE +ibool +fsp_flags_is_compressed( +/*====================*/ + ulint flags) /*!< in: tablespace flags */ +{ + return(FSP_FLAGS_GET_ZIP_SSIZE(flags) != 0); +} + +#endif /* !UNIV_INNOCHECKSUM */ + +/********************************************************************//** +Extract the zip size from tablespace flags. +@return compressed page size of the file-per-table tablespace in bytes, +or zero if the table is not compressed. */ +UNIV_INLINE +ulint +fsp_flags_get_zip_size( +/*===================*/ + ulint flags) /*!< in: tablespace flags */ +{ + ulint zip_size = 0; + ulint ssize = FSP_FLAGS_GET_ZIP_SSIZE(flags); + + /* Convert from a 'log2 minus 9' to a page size in bytes. */ + if (ssize) { + zip_size = ((UNIV_ZIP_SIZE_MIN >> 1) << ssize); + + ut_ad(zip_size <= UNIV_ZIP_SIZE_MAX); + } + + return(zip_size); +} + +/********************************************************************//** +Extract the page size from tablespace flags. +@return page size of the tablespace in bytes */ +UNIV_INLINE +ulint +fsp_flags_get_page_size( +/*====================*/ + ulint flags) /*!< in: tablespace flags */ +{ + ulint page_size = 0; + ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags); + + /* Convert from a 'log2 minus 9' to a page size in bytes. */ + if (UNIV_UNLIKELY(ssize)) { + page_size = ((UNIV_ZIP_SIZE_MIN >> 1) << ssize); + + ut_ad(page_size <= UNIV_PAGE_SIZE_MAX); + } else { + /* If the page size was not stored, then it is the + original 16k. */ + page_size = UNIV_PAGE_SIZE_ORIG; + } + + return(page_size); +} + +#ifndef UNIV_INNOCHECKSUM + +/********************************************************************//** +Add the page size to the tablespace flags. +@return tablespace flags after page size is added */ +UNIV_INLINE +ulint +fsp_flags_set_page_size( +/*====================*/ + ulint flags, /*!< in: tablespace flags */ + ulint page_size) /*!< in: page size in bytes */ +{ + ulint ssize = 0; + ulint shift; + + /* Page size should be > UNIV_PAGE_SIZE_MIN */ + ut_ad(page_size >= UNIV_PAGE_SIZE_MIN); + ut_ad(page_size <= UNIV_PAGE_SIZE_MAX); + + if (page_size == UNIV_PAGE_SIZE_ORIG) { + ut_ad(0 == FSP_FLAGS_GET_PAGE_SSIZE(flags)); + return(flags); + } + + for (shift = UNIV_PAGE_SIZE_SHIFT_MAX; + shift >= UNIV_PAGE_SIZE_SHIFT_MIN; + shift--) { + ulint mask = (1 << shift); + if (page_size & mask) { + ut_ad(!(page_size & ~mask)); + ssize = shift - UNIV_ZIP_SIZE_SHIFT_MIN + 1; + break; + } + } + + ut_ad(ssize); + ut_ad(ssize <= UNIV_PAGE_SSIZE_MAX); + + flags = FSP_FLAGS_SET_PAGE_SSIZE(flags, ssize); + + ut_ad(fsp_flags_is_valid(flags)); + + return(flags); +} + +/********************************************************************//** +Calculates the descriptor index within a descriptor page. +@return descriptor index */ +UNIV_INLINE +ulint +xdes_calc_descriptor_index( +/*=======================*/ + ulint zip_size, /*!< in: compressed page size in bytes; + 0 for uncompressed pages */ + ulint offset) /*!< in: page offset */ +{ + ut_ad(ut_is_2pow(zip_size)); + + if (zip_size == 0) { + return(ut_2pow_remainder(offset, UNIV_PAGE_SIZE) + / FSP_EXTENT_SIZE); + } else { + return(ut_2pow_remainder(offset, zip_size) / FSP_EXTENT_SIZE); + } +} + +/**********************************************************************//** +Gets a descriptor bit of a page. +@return TRUE if free */ +UNIV_INLINE +ibool +xdes_get_bit( +/*=========*/ + const xdes_t* descr, /*!< in: descriptor */ + ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */ + ulint offset) /*!< in: page offset within extent: + 0 ... FSP_EXTENT_SIZE - 1 */ +{ + ut_ad(offset < FSP_EXTENT_SIZE); + ut_ad(bit == XDES_FREE_BIT || bit == XDES_CLEAN_BIT); + + ulint index = bit + XDES_BITS_PER_PAGE * offset; + + ulint bit_index = index % 8; + ulint byte_index = index / 8; + + return(ut_bit_get_nth( + mach_read_ulint(descr + XDES_BITMAP + byte_index, + MLOG_1BYTE), + bit_index)); +} + +/********************************************************************//** +Calculates the page where the descriptor of a page resides. +@return descriptor page offset */ +UNIV_INLINE +ulint +xdes_calc_descriptor_page( +/*======================*/ + ulint zip_size, /*!< in: compressed page size in bytes; + 0 for uncompressed pages */ + ulint offset) /*!< in: page offset */ +{ +#ifndef DOXYGEN /* Doxygen gets confused by these */ +# if UNIV_PAGE_SIZE_MAX <= XDES_ARR_OFFSET \ + + (UNIV_PAGE_SIZE_MAX / FSP_EXTENT_SIZE_MAX) \ + * XDES_SIZE_MAX +# error +# endif +# if UNIV_ZIP_SIZE_MIN <= XDES_ARR_OFFSET \ + + (UNIV_ZIP_SIZE_MIN / FSP_EXTENT_SIZE_MIN) \ + * XDES_SIZE_MIN +# error +# endif +#endif /* !DOXYGEN */ + + ut_ad(UNIV_PAGE_SIZE > XDES_ARR_OFFSET + + (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE) + * XDES_SIZE); + ut_ad(UNIV_ZIP_SIZE_MIN > XDES_ARR_OFFSET + + (UNIV_ZIP_SIZE_MIN / FSP_EXTENT_SIZE) + * XDES_SIZE); + + ut_ad(ut_is_2pow(zip_size)); + + if (zip_size == 0) { + return(ut_2pow_round(offset, UNIV_PAGE_SIZE)); + } else { + ut_ad(zip_size > XDES_ARR_OFFSET + + (zip_size / FSP_EXTENT_SIZE) * XDES_SIZE); + return(ut_2pow_round(offset, zip_size)); + } +} + +#endif /* !UNIV_INNOCHECKSUM */ |