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 it under |
6 | the terms of the GNU General Public License as published by the Free Software |
7 | Foundation; version 2 of the License. |
8 | |
9 | This program is distributed in the hope that it will be useful, but WITHOUT |
10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU General Public License along with |
14 | this program; if not, write to the Free Software Foundation, Inc., |
15 | 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
16 | |
17 | *****************************************************************************/ |
18 | |
19 | /**************************************************//** |
20 | @file include/page0types.h |
21 | Index page routines |
22 | |
23 | Created 2/2/1994 Heikki Tuuri |
24 | *******************************************************/ |
25 | |
26 | #ifndef page0types_h |
27 | #define page0types_h |
28 | |
29 | #include "univ.i" |
30 | #include "dict0types.h" |
31 | #include "mtr0types.h" |
32 | #include "ut0new.h" |
33 | |
34 | #include <map> |
35 | |
36 | /** Eliminates a name collision on HP-UX */ |
37 | #define page_t ib_page_t |
38 | /** Type of the index page */ |
39 | typedef byte page_t; |
40 | #ifndef UNIV_INNOCHECKSUM |
41 | /** Index page cursor */ |
42 | struct page_cur_t; |
43 | |
44 | /** Compressed index page */ |
45 | typedef byte page_zip_t; |
46 | |
47 | /* The following definitions would better belong to page0zip.h, |
48 | but we cannot include page0zip.h from rem0rec.ic, because |
49 | page0*.h includes rem0rec.h and may include rem0rec.ic. */ |
50 | |
51 | /** Number of bits needed for representing different compressed page sizes */ |
52 | #define PAGE_ZIP_SSIZE_BITS 3 |
53 | |
54 | /** Maximum compressed page shift size */ |
55 | #define PAGE_ZIP_SSIZE_MAX \ |
56 | (UNIV_ZIP_SIZE_SHIFT_MAX - UNIV_ZIP_SIZE_SHIFT_MIN + 1) |
57 | |
58 | /* Make sure there are enough bits available to store the maximum zip |
59 | ssize, which is the number of shifts from 512. */ |
60 | #if PAGE_ZIP_SSIZE_MAX >= (1 << PAGE_ZIP_SSIZE_BITS) |
61 | # error "PAGE_ZIP_SSIZE_MAX >= (1 << PAGE_ZIP_SSIZE_BITS)" |
62 | #endif |
63 | |
64 | /* Page cursor search modes; the values must be in this order! */ |
65 | enum page_cur_mode_t { |
66 | PAGE_CUR_UNSUPP = 0, |
67 | PAGE_CUR_G = 1, |
68 | PAGE_CUR_GE = 2, |
69 | PAGE_CUR_L = 3, |
70 | PAGE_CUR_LE = 4, |
71 | |
72 | /* PAGE_CUR_LE_OR_EXTENDS = 5,*/ /* This is a search mode used in |
73 | "column LIKE 'abc%' ORDER BY column DESC"; |
74 | we have to find strings which are <= 'abc' or |
75 | which extend it */ |
76 | |
77 | /* These search mode is for search R-tree index. */ |
78 | PAGE_CUR_CONTAIN = 7, |
79 | PAGE_CUR_INTERSECT = 8, |
80 | PAGE_CUR_WITHIN = 9, |
81 | PAGE_CUR_DISJOINT = 10, |
82 | PAGE_CUR_MBR_EQUAL = 11, |
83 | PAGE_CUR_RTREE_INSERT = 12, |
84 | PAGE_CUR_RTREE_LOCATE = 13, |
85 | PAGE_CUR_RTREE_GET_FATHER = 14 |
86 | }; |
87 | |
88 | |
89 | /** The information used for compressing a page when applying |
90 | TRUNCATE log record during recovery */ |
91 | struct redo_page_compress_t { |
92 | ulint type; /*!< index type */ |
93 | index_id_t index_id; /*!< index id */ |
94 | ulint n_fields; /*!< number of index fields */ |
95 | ulint field_len; /*!< the length of index field */ |
96 | const byte* fields; /*!< index field information */ |
97 | ulint trx_id_pos; /*!< position of trx-id column. */ |
98 | }; |
99 | |
100 | /** Compressed page descriptor */ |
101 | struct page_zip_des_t |
102 | { |
103 | page_zip_t* data; /*!< compressed page data */ |
104 | |
105 | #ifdef UNIV_DEBUG |
106 | unsigned m_start:16; /*!< start offset of modification log */ |
107 | bool m_external; /*!< Allocated externally, not from the |
108 | buffer pool */ |
109 | #endif /* UNIV_DEBUG */ |
110 | unsigned m_end:16; /*!< end offset of modification log */ |
111 | unsigned m_nonempty:1; /*!< TRUE if the modification log |
112 | is not empty */ |
113 | unsigned n_blobs:12; /*!< number of externally stored |
114 | columns on the page; the maximum |
115 | is 744 on a 16 KiB page */ |
116 | unsigned ssize:PAGE_ZIP_SSIZE_BITS; |
117 | /*!< 0 or compressed page shift size; |
118 | the size in bytes is |
119 | (UNIV_ZIP_SIZE_MIN >> 1) << ssize. */ |
120 | }; |
121 | |
122 | /** Compression statistics for a given page size */ |
123 | struct page_zip_stat_t { |
124 | /** Number of page compressions */ |
125 | ulint compressed; |
126 | /** Number of successful page compressions */ |
127 | ulint compressed_ok; |
128 | /** Number of page decompressions */ |
129 | ulint decompressed; |
130 | /** Duration of page compressions in microseconds */ |
131 | ib_uint64_t compressed_usec; |
132 | /** Duration of page decompressions in microseconds */ |
133 | ib_uint64_t decompressed_usec; |
134 | page_zip_stat_t() : |
135 | /* Initialize members to 0 so that when we do |
136 | stlmap[key].compressed++ and element with "key" does not |
137 | exist it gets inserted with zeroed members. */ |
138 | compressed(0), |
139 | compressed_ok(0), |
140 | decompressed(0), |
141 | compressed_usec(0), |
142 | decompressed_usec(0) |
143 | { } |
144 | }; |
145 | |
146 | /** Compression statistics types */ |
147 | typedef std::map< |
148 | index_id_t, |
149 | page_zip_stat_t, |
150 | std::less<index_id_t>, |
151 | ut_allocator<std::pair<const index_id_t, page_zip_stat_t> > > |
152 | page_zip_stat_per_index_t; |
153 | |
154 | /** Statistics on compression, indexed by page_zip_des_t::ssize - 1 */ |
155 | extern page_zip_stat_t page_zip_stat[PAGE_ZIP_SSIZE_MAX]; |
156 | /** Statistics on compression, indexed by dict_index_t::id */ |
157 | extern page_zip_stat_per_index_t page_zip_stat_per_index; |
158 | |
159 | /**********************************************************************//** |
160 | Write the "deleted" flag of a record on a compressed page. The flag must |
161 | already have been written on the uncompressed page. */ |
162 | void |
163 | page_zip_rec_set_deleted( |
164 | /*=====================*/ |
165 | page_zip_des_t* page_zip,/*!< in/out: compressed page */ |
166 | const byte* rec, /*!< in: record on the uncompressed page */ |
167 | ulint flag) /*!< in: the deleted flag (nonzero=TRUE) */ |
168 | MY_ATTRIBUTE((nonnull)); |
169 | |
170 | /**********************************************************************//** |
171 | Write the "owned" flag of a record on a compressed page. The n_owned field |
172 | must already have been written on the uncompressed page. */ |
173 | void |
174 | page_zip_rec_set_owned( |
175 | /*===================*/ |
176 | page_zip_des_t* page_zip,/*!< in/out: compressed page */ |
177 | const byte* rec, /*!< in: record on the uncompressed page */ |
178 | ulint flag) /*!< in: the owned flag (nonzero=TRUE) */ |
179 | MY_ATTRIBUTE((nonnull)); |
180 | |
181 | /**********************************************************************//** |
182 | Shift the dense page directory when a record is deleted. */ |
183 | void |
184 | page_zip_dir_delete( |
185 | /*================*/ |
186 | page_zip_des_t* page_zip,/*!< in/out: compressed page */ |
187 | byte* rec, /*!< in: deleted record */ |
188 | dict_index_t* index, /*!< in: index of rec */ |
189 | const ulint* offsets,/*!< in: rec_get_offsets(rec) */ |
190 | const byte* free) /*!< in: previous start of the free list */ |
191 | MY_ATTRIBUTE((nonnull(1,2,3,4))); |
192 | |
193 | /**********************************************************************//** |
194 | Add a slot to the dense page directory. */ |
195 | void |
196 | page_zip_dir_add_slot( |
197 | /*==================*/ |
198 | page_zip_des_t* page_zip, /*!< in/out: compressed page */ |
199 | ulint is_clustered) /*!< in: nonzero for clustered index, |
200 | zero for others */ |
201 | MY_ATTRIBUTE((nonnull)); |
202 | #endif /* !UNIV_INNOCHECKSUM */ |
203 | #endif |
204 | |