1 /*****************************************************************************
2 
3 Copyright (c) 2017, 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 #ifndef DICT_SDI_H
28 #define DICT_SDI_H
29 
30 #include <zconf.h>
31 #include <zlib.h>
32 
33 /** Size of sdi_key_t::type */
34 constexpr const uint32_t SDI_TYPE_LEN = 4;
35 
36 /** Size of sdi_key_t::id */
37 constexpr const uint32_t SDI_KEY_LEN = 8;
38 
39 /** Compress SDI using zlib */
40 class Sdi_Compressor {
41  public:
Sdi_Compressor(uint32_t src_len,const void * sdi)42   Sdi_Compressor(uint32_t src_len, const void *sdi)
43       : m_src_len(src_len), m_comp_len(), m_sdi(sdi), m_comp_sdi() {}
44 
~Sdi_Compressor()45   ~Sdi_Compressor() { ut_free(m_comp_sdi); }
46 
47   /** Compress the SDI */
compress()48   inline void compress() {
49     uLongf zlen = compressBound(static_cast<uLong>(m_src_len));
50     auto src = reinterpret_cast<const Bytef *>(m_sdi);
51 
52     m_comp_sdi = static_cast<byte *>(ut_malloc_nokey(zlen));
53     ut_ad(m_comp_sdi != nullptr);
54 
55     switch (
56         compress2(m_comp_sdi, &zlen, src, static_cast<uLong>(m_src_len), 6)) {
57       case Z_BUF_ERROR:
58         ib::fatal(ER_IB_MSG_FAILED_SDI_Z_BUF_ERROR);
59         break;
60 
61       case Z_MEM_ERROR:
62         ib::fatal(ER_IB_MSG_FAILED_SDI_Z_MEM_ERROR);
63         break;
64 
65       case Z_STREAM_ERROR:
66         ib::fatal(ER_IB_MSG_SDI_Z_STREAM_ERROR);
67         break;
68 
69       case Z_OK:
70         m_comp_len = zlen;
71         break;
72 
73       default:
74         ib::fatal(ER_IB_MSG_SDI_Z_UNKNOWN_ERROR);
75         break;
76     }
77   }
78 
79   /** @return compressed SDI record */
get_data()80   const byte *get_data() const { return (m_comp_sdi); }
81 
82   /** @return length of uncompressed SDI */
get_src_len()83   uint32_t get_src_len() const { return (m_src_len); }
84 
85   /** @return length of compressed SDI */
get_comp_len()86   uint32_t get_comp_len() const { return (m_comp_len); }
87 
88  private:
89   /** Length of uncompressed SDI */
90   uint32_t m_src_len;
91   /** Length of compressed SDI */
92   uint32_t m_comp_len;
93   /** Uncompressed SDI */
94   const void *m_sdi;
95   /** Compressed SDI */
96   byte *m_comp_sdi;
97 };
98 
99 /** Create SDI in a tablespace. This API should be used when
100 upgrading a tablespace with no SDI.
101 @param[in,out]	tablespace	tablespace object
102 @retval		false		success
103 @retval		true		failure */
104 bool dict_sdi_create(dd::Tablespace *tablespace);
105 
106 /** Drop SDI in a tablespace. This API should be used only
107 when SDI is corrupted.
108 @param[in,out]	tablespace	tablespace object
109 @retval		false		success
110 @retval		true		failure */
111 bool dict_sdi_drop(dd::Tablespace *tablespace);
112 
113 /** Get the SDI keys in a tablespace into the vector provided.
114 @param[in]	tablespace	tablespace object
115 @param[in,out]	vector		vector to hold SDI keys
116 @retval		false		success
117 @retval		true		failure */
118 bool dict_sdi_get_keys(const dd::Tablespace &tablespace, sdi_vector_t &vector);
119 
120 /** Retrieve SDI from tablespace.
121 @param[in]	tablespace	tablespace object
122 @param[in]	sdi_key		SDI key
123 @param[in,out]	sdi		SDI retrieved from tablespace
124 @param[in,out]	sdi_len		in:  size of memory allocated
125                                 out: actual length of SDI
126 @retval		false		success
127 @retval		true		incase of failures like record not found,
128                                 sdi_len is UINT64MAX_T, else sdi_len is
129                                 actual length of SDI */
130 bool dict_sdi_get(const dd::Tablespace &tablespace, const sdi_key_t *sdi_key,
131                   void *sdi, uint64 *sdi_len);
132 
133 /** Insert/Update SDI in tablespace.
134 @param[in]	hton            handlerton object
135 @param[in]	tablespace	tablespace object
136 @param[in]	table		table object
137 @param[in]	sdi_key		SDI key to uniquely identify the tablespace
138 object
139 @param[in]	sdi		SDI to be stored in tablespace
140 @param[in]	sdi_len		SDI length
141 @retval		false		success
142 @retval		true		failure */
143 bool dict_sdi_set(handlerton *hton, const dd::Tablespace &tablespace,
144                   const dd::Table *table, const sdi_key_t *sdi_key,
145                   const void *sdi, uint64 sdi_len);
146 
147 /** Delete SDI from tablespace.
148 @param[in]	tablespace	tablespace object
149 @param[in]	table		table object
150 @param[in]	sdi_key		SDI key to uniquely identify the tablespace
151                                 object
152 @retval		false		success
153 @retval		true		failure */
154 bool dict_sdi_delete(const dd::Tablespace &tablespace, const dd::Table *table,
155                      const sdi_key_t *sdi_key);
156 #endif
157