/***************************************************************************** Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2013, 2017, MariaDB Corporation. 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); } /********************************************************************//** 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 /********************************************************************//** 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); } } #endif /* !UNIV_INNOCHECKSUM */ /**********************************************************************//** 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)); } #ifndef UNIV_INNOCHECKSUM /********************************************************************//** 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 */