summaryrefslogtreecommitdiff
path: root/storage/xtradb/include/fsp0fsp.ic
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb/include/fsp0fsp.ic')
-rw-r--r--storage/xtradb/include/fsp0fsp.ic314
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 */