1 /***************************************************************************** 2 3 Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License, version 2.0, 7 as published by the Free Software Foundation. 8 9 This program is also distributed with certain software (including 10 but not limited to OpenSSL) that is licensed under separate terms, 11 as designated in a particular file or component or in included license 12 documentation. The authors of MySQL hereby grant you an additional 13 permission to link the program and your derivative works with the 14 separately licensed software that they have included with MySQL. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License, version 2.0, for more details. 20 21 You should have received a copy of the GNU General Public License along with 22 this program; if not, write to the Free Software Foundation, Inc., 23 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA 24 25 *****************************************************************************/ 26 27 /**************************************************//** 28 @file include/page0types.h 29 Index page routines 30 31 Created 2/2/1994 Heikki Tuuri 32 *******************************************************/ 33 34 #ifndef page0types_h 35 #define page0types_h 36 37 using namespace std; 38 39 #include <map> 40 41 #include "univ.i" 42 #include "dict0types.h" 43 #include "mtr0types.h" 44 45 /** Eliminates a name collision on HP-UX */ 46 #define page_t ib_page_t 47 /** Type of the index page */ 48 typedef byte page_t; 49 /** Index page cursor */ 50 struct page_cur_t; 51 52 /** Compressed index page */ 53 typedef byte page_zip_t; 54 55 /* The following definitions would better belong to page0zip.h, 56 but we cannot include page0zip.h from rem0rec.ic, because 57 page0*.h includes rem0rec.h and may include rem0rec.ic. */ 58 59 /** Number of bits needed for representing different compressed page sizes */ 60 #define PAGE_ZIP_SSIZE_BITS 3 61 62 /** Maximum compressed page shift size */ 63 #define PAGE_ZIP_SSIZE_MAX \ 64 (UNIV_ZIP_SIZE_SHIFT_MAX - UNIV_ZIP_SIZE_SHIFT_MIN + 1) 65 66 /* Make sure there are enough bits available to store the maximum zip 67 ssize, which is the number of shifts from 512. */ 68 #if PAGE_ZIP_SSIZE_MAX >= (1 << PAGE_ZIP_SSIZE_BITS) 69 # error "PAGE_ZIP_SSIZE_MAX >= (1 << PAGE_ZIP_SSIZE_BITS)" 70 #endif 71 72 /** Compressed page descriptor */ 73 struct page_zip_des_t 74 { 75 page_zip_t* data; /*!< compressed page data */ 76 77 #ifdef UNIV_DEBUG 78 unsigned m_start:16; /*!< start offset of modification log */ 79 bool m_external; /*!< Allocated externally, not from the 80 buffer pool */ 81 #endif /* UNIV_DEBUG */ 82 unsigned m_end:16; /*!< end offset of modification log */ 83 unsigned m_nonempty:1; /*!< TRUE if the modification log 84 is not empty */ 85 unsigned n_blobs:12; /*!< number of externally stored 86 columns on the page; the maximum 87 is 744 on a 16 KiB page */ 88 unsigned ssize:PAGE_ZIP_SSIZE_BITS; 89 /*!< 0 or compressed page shift size; 90 the size in bytes is 91 (UNIV_ZIP_SIZE_MIN >> 1) << ssize. */ 92 }; 93 94 /** Compression statistics for a given page size */ 95 struct page_zip_stat_t { 96 /** Number of page compressions */ 97 ulint compressed; 98 /** Number of successful page compressions */ 99 ulint compressed_ok; 100 /** Number of page decompressions */ 101 ulint decompressed; 102 /** Duration of page compressions in microseconds */ 103 ib_uint64_t compressed_usec; 104 /** Duration of page decompressions in microseconds */ 105 ib_uint64_t decompressed_usec; page_zip_stat_tpage_zip_stat_t106 page_zip_stat_t() : 107 /* Initialize members to 0 so that when we do 108 stlmap[key].compressed++ and element with "key" does not 109 exist it gets inserted with zeroed members. */ 110 compressed(0), 111 compressed_ok(0), 112 decompressed(0), 113 compressed_usec(0), 114 decompressed_usec(0) 115 { } 116 }; 117 118 #ifndef UNIV_INNOCHECKSUM 119 120 /** Compression statistics types */ 121 typedef map<index_id_t, page_zip_stat_t> page_zip_stat_per_index_t; 122 123 /** Statistics on compression, indexed by page_zip_des_t::ssize - 1 */ 124 extern page_zip_stat_t page_zip_stat[PAGE_ZIP_SSIZE_MAX]; 125 /** Statistics on compression, indexed by dict_index_t::id */ 126 extern page_zip_stat_per_index_t page_zip_stat_per_index; 127 extern ib_mutex_t page_zip_stat_per_index_mutex; 128 #ifdef HAVE_PSI_INTERFACE 129 extern mysql_pfs_key_t page_zip_stat_per_index_mutex_key; 130 #endif /* HAVE_PSI_INTERFACE */ 131 132 #endif /* !UNIV_INNOCHECKSUM */ 133 134 /**********************************************************************//** 135 Write the "deleted" flag of a record on a compressed page. The flag must 136 already have been written on the uncompressed page. */ 137 UNIV_INTERN 138 void 139 page_zip_rec_set_deleted( 140 /*=====================*/ 141 page_zip_des_t* page_zip,/*!< in/out: compressed page */ 142 const byte* rec, /*!< in: record on the uncompressed page */ 143 ulint flag) /*!< in: the deleted flag (nonzero=TRUE) */ 144 MY_ATTRIBUTE((nonnull)); 145 146 /**********************************************************************//** 147 Write the "owned" flag of a record on a compressed page. The n_owned field 148 must already have been written on the uncompressed page. */ 149 UNIV_INTERN 150 void 151 page_zip_rec_set_owned( 152 /*===================*/ 153 page_zip_des_t* page_zip,/*!< in/out: compressed page */ 154 const byte* rec, /*!< in: record on the uncompressed page */ 155 ulint flag) /*!< in: the owned flag (nonzero=TRUE) */ 156 MY_ATTRIBUTE((nonnull)); 157 158 /**********************************************************************//** 159 Shift the dense page directory when a record is deleted. */ 160 UNIV_INTERN 161 void 162 page_zip_dir_delete( 163 /*================*/ 164 page_zip_des_t* page_zip,/*!< in/out: compressed page */ 165 byte* rec, /*!< in: deleted record */ 166 dict_index_t* index, /*!< in: index of rec */ 167 const ulint* offsets,/*!< in: rec_get_offsets(rec) */ 168 const byte* free) /*!< in: previous start of the free list */ 169 MY_ATTRIBUTE((nonnull(1,2,3,4))); 170 171 /**********************************************************************//** 172 Add a slot to the dense page directory. */ 173 UNIV_INTERN 174 void 175 page_zip_dir_add_slot( 176 /*==================*/ 177 page_zip_des_t* page_zip, /*!< in/out: compressed page */ 178 ulint is_clustered) /*!< in: nonzero for clustered index, 179 zero for others */ 180 MY_ATTRIBUTE((nonnull)); 181 #endif 182