1 /***********************************************************************
2 
3 Copyright (c) 2011, 2013, 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
22 with 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 @file innodb_config.h
28 
29 Created 03/15/2011      Jimmy Yang
30 *******************************************************/
31 
32 #ifndef innodb_config_h
33 #define innodb_config_h
34 
35 #include "api0api.h"
36 #include "innodb_utility.h"
37 
38 typedef void*   hash_node_t;
39 
40 /* Database name and table name for our metadata "system" tables for
41 InnoDB memcache. The table names are the same as those for the
42 NDB memcache, to make the memcache setup compatible between the two.
43 There are 3 "system tables":
44 1) containers - main configure table contains row describing which InnoDB
45 		table is used to store/retrieve Memcached key/value if InnoDB
46 		Memcached engine is used
47 2) cache_policies - decide whether to use "Memcached Default Engine" or "InnoDB
48 		    Memcached Engine" to handler the requests
49 3) config_options - for miscellaneous configuration options */
50 #define MCI_CFG_DB_NAME			"innodb_memcache"
51 #define MCI_CFG_CONTAINER_TABLE		"containers"
52 #define MCI_CFG_CACHE_POLICIES		"cache_policies"
53 #define MCI_CFG_CONFIG_OPTIONS		"config_options"
54 
55 /** Max table name length as defined in univ.i */
56 #define MAX_TABLE_NAME_LEN      192
57 #define MAX_DATABASE_NAME_LEN   MAX_TABLE_NAME_LEN
58 #define MAX_FULL_NAME_LEN                               \
59         (MAX_TABLE_NAME_LEN + MAX_DATABASE_NAME_LEN + 14)
60 
61 /** structure describes each column's basic info (name, field_id etc.) */
62 typedef struct meta_column {
63 	char*		col_name;		/*!< column name */
64 	size_t		col_name_len;		/*!< column name length */
65 	int		field_id;		/*!< column field id in
66 						the table */
67 	ib_col_meta_t	col_meta;		/*!< column  meta info */
68 } meta_column_t;
69 
70 /** Following are enums defining column IDs indexing into each of three
71 system tables */
72 
73 /** Columns in the "containers" system table, this maps the Memcached
74 operation to a consistent InnoDB table */
75 typedef enum container {
76 	CONTAINER_NAME,		/*!< name for this mapping */
77 	CONTAINER_DB,		/*!< database name */
78 	CONTAINER_TABLE,	/*!< table name */
79 	CONTAINER_KEY,		/*!< column name for column maps to
80 				memcached "key" */
81 	CONTAINER_VALUE,	/*!< column name for column maps to
82 				memcached "value" */
83 	CONTAINER_FLAG,		/*!< column name for column maps to
84 				memcached "flag" value */
85 	CONTAINER_CAS,		/*!< column name for column maps to
86 				memcached "cas" value */
87 	CONTAINER_EXP,		/*!< column name for column maps to
88 				"expiration" value */
89 	CONTAINER_NUM_COLS	/*!< number of columns */
90 } container_t;
91 
92 /** columns in the "cache_policy" table */
93 typedef enum cache_policy {
94 	CACHE_POLICY_NAME,	/*!< "name" column, for the "cache_policy"
95 				name */
96 	CACHE_POLICY_GET,	/*!< "get" column, specifies the cache policy
97 				for "get" command */
98 	CACHE_POLICY_SET,	/*!< "set" column, specifies the cache policy
99 				for "set" command */
100 	CACHE_POLICY_DEL,	/*!< "delete" column, specifies the cache
101 				policy for "delete" command */
102 	CACHE_POLICY_FLUSH,	/*!< "flush_all" column, specifies the
103 				cache policy for "flush_all" command */
104 	CACHE_POLICY_NUM_COLS	/*!< total 5 columns */
105 } cache_policy_t;
106 
107 /** columns in the "config_options" table */
108 typedef enum config_opt {
109 	CONFIG_OPT_KEY,		/*!< key column in the "config_option" table */
110 	CONFIG_OPT_VALUE,	/*!< value column */
111 	CONFIG_OPT_NUM_COLS	/*!< number of columns (currently 2) in table */
112 } config_opt_t;
113 
114 /** Following are some value defines describes the options that configures
115 the InnoDB Memcached */
116 
117 /** Values to set up "m_use_idx" field of "meta_index_t" structure,
118 indicating whether we will use cluster or secondary index on the
119 "key" column to perform the search. Please note the index must
120 be unique index */
121 typedef enum meta_use_idx {
122 	META_USE_NO_INDEX = 1,	/*!< no cluster or unique secondary index
123 				on the key column. This is an error, will
124 				cause setup to fail */
125 	META_USE_CLUSTER,	/*!< have cluster index on the key column */
126 	META_USE_SECONDARY	/*!< have unique secondary index on the
127 				key column */
128 } meta_use_idx_t;
129 
130 /** Describes the index's name and ID of the index on the "key" column */
131 typedef struct meta_index {
132 	char*		idx_name;	/*!< index name */
133 	int		idx_id;		/*!< index id */
134 	meta_use_idx_t	srch_use_idx;	/*!< use cluster or secondary
135 					index for the search */
136 } meta_index_t;
137 
138 /** Cache options, tells if we will used Memcached default engine or InnoDB
139 Memcached engine to handle the request */
140 typedef enum meta_cache_opt {
141 	META_CACHE_OPT_INNODB = 1,	/*!< Use InnoDB Memcached Engine only */
142 	META_CACHE_OPT_DEFAULT,		/*!< Use Default Memcached Engine
143 					only */
144 	META_CACHE_OPT_MIX,		/*!< Use both, first use default
145 					memcached engine */
146 	META_CACHE_OPT_DISABLE,		/*!< This operation is disabled */
147 	META_CACHE_NUM_OPT		/*!< Number of options */
148 } meta_cache_opt_t;
149 
150 /** The "names" in the "config_option" table to identify possible
151 config options. Both are optional.
152 "COLUMN_SEPARATOR" is the delimiter that separates multiple columns and
153 "TABLE_MAP_SEPARATOR" is the delimiter that separates table map name
154 and key value */
155 #define COLUMN_SEPARATOR        "separator"
156 #define TABLE_MAP_SEPARATOR     "table_map_delimiter"
157 
158 /* list of configure options we support */
159 typedef enum option_id {
160 	OPTION_ID_COL_SEP,		/*!< ID for character(s) separating
161 					multiple column mapping */
162 	OPTION_ID_TBL_MAP_SEP,		/*!< ID for character(s) separating
163 					table map name and key */
164 	OPTION_ID_NUM_OPTIONS		/*!< number of options */
165 } option_id_t;
166 
167 /** Maximum delimiter length */
168 #define MAX_DELIMITER_LEN	32
169 
170 typedef struct option_value {
171 	char		value[MAX_DELIMITER_LEN + 1];
172 					/* option value */
173 	int		value_len;	/* value length */
174 } option_value_t;
175 
176 /** structure to define some default "config_option" option settings */
177 typedef struct option {
178 	option_id_t	id;		/*!< option id as in enum option_id */
179 	const char*	name;		/*!< option name for above option ID,
180 					currently they can be "COLUMN_SEPARATOR"
181 					and "TABLE_MAP_SEPARATOR" */
182 	option_value_t	default_value;	/*!< default value */
183 } option_t;
184 
185 /** Get configure option value. If the value is not configured by
186 user, obtain its default value from "config_option_names"
187 @param meta_info	metadata structure contains configure options
188 @param option		option whose value to get
189 @param val		value to fetch
190 @param val_len		value length */
191 #define GET_OPTION(meta_info, option, val, val_len)			\
192 do {									\
193 	val_len = meta_info->options[option].value_len;			\
194 									\
195 	if (val_len == 0) {						\
196 		val = config_option_names[option].default_value.value;	\
197 		val_len = config_option_names[option].default_value.value_len;\
198 	} else {							\
199 		val = meta_info->options[option].value;			\
200 	}								\
201 } while (0)
202 
203 /** In memory structure contains most necessary metadata info
204 to configure an InnoDB Memcached engine */
205 typedef struct meta_cfg_info {
206 	meta_column_t	col_info[CONTAINER_NUM_COLS]; /*!< column info */
207 	meta_column_t*	extra_col_info;		/*!< additional columns
208 						specified for the value field */
209 	int		n_extra_col;		/*!< number of additional
210 						value columns */
211 	meta_index_t	index_info;		/*!< Index info */
212 	bool		flag_enabled;		/*!< whether flag is enabled */
213 	bool		cas_enabled;		/*!< whether cas is enabled */
214 	bool		exp_enabled;		/*!< whether exp is enabled */
215 	option_value_t	options[OPTION_ID_NUM_OPTIONS];
216 						/*!< configure options, mostly
217 						are configured delimiters */
218 	meta_cache_opt_t set_option;		/*!< cache option for "set" */
219 	meta_cache_opt_t get_option;		/*!< cache option for "get" */
220 	meta_cache_opt_t del_option;		/*!< cache option for
221 						"delete" */
222 	meta_cache_opt_t flush_option;		/*!< cache option for
223 						"delete" */
224 	hash_node_t	name_hash;		/*!< name hash chain node */
225 } meta_cfg_info_t;
226 
227 
228 /**********************************************************************//**
229 This function opens the default configuration table, and find the
230 table and column info that used for InnoDB Memcached, and set up
231 InnoDB Memcached's meta_cfg_info_t structure. If the "name" parameter
232 is not NULL, it will find the specified setting in the "container" table.
233 If "name" field is NULL, it will then look for setting with the name of
234 "default". Otherwise, it returns the setting corresponding to the
235 first row of the configure table.
236 @return meta_cfg_info_t* structure if configure option found, otherwise NULL */
237 meta_cfg_info_t*
238 innodb_config(
239 /*==========*/
240 	const char*		name,		/*!< in: config option name */
241 	size_t			name_len,	/*!< in: option name length */
242 	hash_table_t**		meta_hash);	/*!< in: engine hash table */
243 
244 /**********************************************************************//**
245 This function verifies the table configuration information, and fills
246 in columns used for memcached functionalities (cas, exp etc.)
247 @return true if everything works out fine */
248 bool
249 innodb_verify(
250 /*==========*/
251 	meta_cfg_info_t*	info);		/*!< in: meta info structure */
252 
253 /**********************************************************************//**
254 This function frees meta info structure */
255 void
256 innodb_config_free(
257 /*===============*/
258         meta_cfg_info_t*	item);		/*!< in/own: meta info
259 						structure */
260 
261 /**********************************************************************//**
262 This function opens the "containers" table, reads in all rows
263 and instantiates the metadata hash table.
264 @return the default configuration setting (whose mapping name is "default") */
265 meta_cfg_info_t*
266 innodb_config_meta_hash_init(
267 /*=========================*/
268 	hash_table_t*		meta_hash);	/*!< in/out: InnoDB Memcached
269 						engine */
270 #endif
271