1 /***************************************************************************** 2 3 Copyright (c) 2013, 2019, Oracle and/or its affiliates. All Rights Reserved. 4 5 This program is free software; you can redistribute it and/or modify it under 6 the terms of the GNU General Public License, version 2.0, as published by the 7 Free Software Foundation. 8 9 This program is also distributed with certain software (including but not 10 limited to OpenSSL) that is licensed under separate terms, as designated in a 11 particular file or component or in included license documentation. The authors 12 of MySQL hereby grant you an additional permission to link the program and 13 your derivative works with the separately licensed software that they have 14 included with MySQL. 15 16 This program is distributed in the hope that it will be useful, but WITHOUT 17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 18 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, 19 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 St, Fifth Floor, Boston, MA 02110-1301 USA 24 25 *****************************************************************************/ 26 27 /** @file include/page0size.h 28 A class describing a page size. 29 30 Created Nov 14, 2013 Vasil Dimov 31 *******************************************************/ 32 33 #ifndef page0size_t 34 #define page0size_t 35 36 #include "fsp0types.h" 37 38 constexpr size_t FIELD_REF_SIZE = 20; 39 40 /** A BLOB field reference full of zero, for use in assertions and 41 tests.Initially, BLOB field references are set to zero, in 42 dtuple_convert_big_rec(). */ 43 extern const byte field_ref_zero[FIELD_REF_SIZE]; 44 45 constexpr size_t PAGE_SIZE_T_SIZE_BITS = 17; 46 47 /** Page size descriptor. Contains the physical and logical page size, as well 48 as whether the page is compressed or not. */ 49 class page_size_t { 50 public: 51 /** Constructor from (physical, logical, is_compressed). 52 @param[in] physical physical (on-disk/zipped) page size 53 @param[in] logical logical (in-memory/unzipped) page size 54 @param[in] is_compressed whether the page is compressed */ page_size_t(uint32_t physical,uint32_t logical,bool is_compressed)55 page_size_t(uint32_t physical, uint32_t logical, bool is_compressed) { 56 if (physical == 0) { 57 physical = UNIV_PAGE_SIZE_ORIG; 58 } 59 if (logical == 0) { 60 logical = UNIV_PAGE_SIZE_ORIG; 61 } 62 63 m_physical = static_cast<unsigned>(physical); 64 m_logical = static_cast<unsigned>(logical); 65 m_is_compressed = static_cast<unsigned>(is_compressed); 66 67 ut_ad(physical <= (1 << PAGE_SIZE_T_SIZE_BITS)); 68 ut_ad(logical <= (1 << PAGE_SIZE_T_SIZE_BITS)); 69 70 ut_ad(ut_is_2pow(physical)); 71 ut_ad(ut_is_2pow(logical)); 72 73 ut_ad(logical <= UNIV_PAGE_SIZE_MAX); 74 ut_ad(logical >= physical); 75 ut_ad(!is_compressed || physical <= UNIV_ZIP_SIZE_MAX); 76 } 77 78 /** Constructor from (fsp_flags). 79 @param[in] fsp_flags filespace flags */ page_size_t(uint32_t fsp_flags)80 explicit page_size_t(uint32_t fsp_flags) { 81 uint32_t ssize = FSP_FLAGS_GET_PAGE_SSIZE(fsp_flags); 82 83 /* If the logical page size is zero in fsp_flags, then use the 84 legacy 16k page size. */ 85 ssize = (0 == ssize) ? UNIV_PAGE_SSIZE_ORIG : ssize; 86 87 /* Convert from a 'log2 minus 9' to a page size in bytes. */ 88 const ulint size = ((UNIV_ZIP_SIZE_MIN >> 1) << ssize); 89 90 ut_ad(size <= UNIV_PAGE_SIZE_MAX); 91 ut_ad(size <= (1 << PAGE_SIZE_T_SIZE_BITS)); 92 93 m_logical = size; 94 95 ssize = FSP_FLAGS_GET_ZIP_SSIZE(fsp_flags); 96 97 /* If the fsp_flags have zero in the zip_ssize field, then 98 it means that the tablespace does not have compressed pages 99 and the physical page size is the same as the logical page 100 size. */ 101 if (ssize == 0) { 102 m_is_compressed = false; 103 m_physical = m_logical; 104 } else { 105 m_is_compressed = true; 106 107 /* Convert from a 'log2 minus 9' to a page size 108 in bytes. */ 109 const ulint phy = ((UNIV_ZIP_SIZE_MIN >> 1) << ssize); 110 111 ut_ad(phy <= UNIV_ZIP_SIZE_MAX); 112 ut_ad(phy <= (1 << PAGE_SIZE_T_SIZE_BITS)); 113 114 m_physical = phy; 115 } 116 } 117 118 /** Retrieve the physical page size (on-disk). 119 @return physical page size in bytes */ physical()120 inline size_t physical() const { 121 ut_ad(m_physical > 0); 122 123 return (m_physical); 124 } 125 126 /** Retrieve the logical page size (in-memory). 127 @return logical page size in bytes */ logical()128 inline size_t logical() const { 129 ut_ad(m_logical > 0); 130 return (m_logical); 131 } 132 extent_size()133 page_no_t extent_size() const { 134 page_no_t size = 0; 135 switch (m_physical) { 136 case 4096: 137 size = 256; 138 break; 139 case 8192: 140 size = 128; 141 break; 142 case 16384: 143 case 32768: 144 case 65536: 145 size = 64; 146 break; 147 default: 148 ut_ad(0); 149 } 150 return (size); 151 } 152 extents_per_xdes()153 size_t extents_per_xdes() const { return (m_physical / extent_size()); } 154 155 /** Check whether the page is compressed on disk. 156 @return true if compressed */ is_compressed()157 inline bool is_compressed() const { return (m_is_compressed); } 158 159 /** Copy the values from a given page_size_t object. 160 @param[in] src page size object whose values to fetch */ copy_from(const page_size_t & src)161 inline void copy_from(const page_size_t &src) { 162 m_physical = src.physical(); 163 m_logical = src.logical(); 164 m_is_compressed = src.is_compressed(); 165 } 166 167 /** Check if a given page_size_t object is equal to the current one. 168 @param[in] a page_size_t object to compare 169 @return true if equal */ equals_to(const page_size_t & a)170 inline bool equals_to(const page_size_t &a) const { 171 return (a.physical() == m_physical && a.logical() == m_logical && 172 a.is_compressed() == m_is_compressed); 173 } 174 set_flag(uint32_t fsp_flags)175 inline void set_flag(uint32_t fsp_flags) { 176 uint32_t ssize = FSP_FLAGS_GET_PAGE_SSIZE(fsp_flags); 177 178 /* If the logical page size is zero in fsp_flags, then 179 use the legacy 16k page size. */ 180 ssize = (0 == ssize) ? UNIV_PAGE_SSIZE_ORIG : ssize; 181 182 /* Convert from a 'log2 minus 9' to a page size in bytes. */ 183 const uint32_t size = ((UNIV_ZIP_SIZE_MIN >> 1) << ssize); 184 185 ut_ad(size <= UNIV_PAGE_SIZE_MAX); 186 ut_ad(size <= (1 << PAGE_SIZE_T_SIZE_BITS)); 187 188 m_logical = size; 189 190 ssize = FSP_FLAGS_GET_ZIP_SSIZE(fsp_flags); 191 192 /* If the fsp_flags have zero in the zip_ssize field, 193 then it means that the tablespace does not have 194 compressed pages and the physical page size is the same 195 as the logical page size. */ 196 if (ssize == 0) { 197 m_is_compressed = false; 198 m_physical = m_logical; 199 } else { 200 m_is_compressed = true; 201 202 /* Convert from a 'log2 minus 9' to a page size 203 in bytes. */ 204 const ulint phy = ((UNIV_ZIP_SIZE_MIN >> 1) << ssize); 205 206 ut_ad(phy <= UNIV_ZIP_SIZE_MAX); 207 ut_ad(phy <= (1 << PAGE_SIZE_T_SIZE_BITS)); 208 209 m_physical = phy; 210 } 211 } 212 213 /* Disable implicit copying. */ 214 void operator=(const page_size_t &) = delete; 215 216 page_size_t(const page_size_t &) = default; 217 218 private: 219 /* For non compressed tablespaces, physical page size is equal to 220 the logical page size and the data is stored in buf_page_t::frame 221 (and is also always equal to univ_page_size (--innodb-page-size=)). 222 223 For compressed tablespaces, physical page size is the compressed 224 page size as stored on disk and in buf_page_t::zip::data. The logical 225 page size is the uncompressed page size in memory - the size of 226 buf_page_t::frame (currently also always equal to univ_page_size 227 (--innodb-page-size=)). */ 228 229 /** Physical page size. */ 230 unsigned m_physical : PAGE_SIZE_T_SIZE_BITS; 231 232 /** Logical page size. */ 233 unsigned m_logical : PAGE_SIZE_T_SIZE_BITS; 234 235 /** Flag designating whether the physical page is compressed, which is 236 true IFF the whole tablespace where the page belongs is compressed. */ 237 unsigned m_is_compressed : 1; 238 }; 239 240 /* Overloading the global output operator to conveniently print an object 241 of type the page_size_t. 242 @param[in,out] out the output stream 243 @param[in] obj an object of type page_size_t to be printed 244 @retval the output stream */ 245 inline std::ostream &operator<<(std::ostream &out, const page_size_t &obj) { 246 out << "[page size: physical=" << obj.physical() 247 << ", logical=" << obj.logical() << ", compressed=" << obj.is_compressed() 248 << "]"; 249 return (out); 250 } 251 252 extern page_size_t univ_page_size; 253 254 #endif /* page0size_t */ 255