1/*****************************************************************************
2
3Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License as published by the Free Software
7Foundation; version 2 of the License.
8
9This program is distributed in the hope that it will be useful, but WITHOUT
10ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
13You should have received a copy of the GNU General Public License along with
14this program; if not, write to the Free Software Foundation, Inc.,
1551 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
16
17*****************************************************************************/
18
19/**************************************************//**
20@file include/page0types.h
21Index page routines
22
23Created 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 */
39typedef byte page_t;
40#ifndef UNIV_INNOCHECKSUM
41/** Index page cursor */
42struct page_cur_t;
43
44/** Compressed index page */
45typedef byte page_zip_t;
46
47/* The following definitions would better belong to page0zip.h,
48but we cannot include page0zip.h from rem0rec.ic, because
49page0*.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
59ssize, 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! */
65enum 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
90TRUNCATE log record during recovery */
91struct 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 */
101struct 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 */
123struct 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 */
147typedef 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 */
155extern page_zip_stat_t page_zip_stat[PAGE_ZIP_SSIZE_MAX];
156/** Statistics on compression, indexed by dict_index_t::id */
157extern page_zip_stat_per_index_t page_zip_stat_per_index;
158
159/**********************************************************************//**
160Write the "deleted" flag of a record on a compressed page. The flag must
161already have been written on the uncompressed page. */
162void
163page_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/**********************************************************************//**
171Write the "owned" flag of a record on a compressed page. The n_owned field
172must already have been written on the uncompressed page. */
173void
174page_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/**********************************************************************//**
182Shift the dense page directory when a record is deleted. */
183void
184page_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/**********************************************************************//**
194Add a slot to the dense page directory. */
195void
196page_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