Skip to content

Commit aaace46

Browse files
author
Jimmy Yang
committed
Check in WL #6218 Support multiple table access through InnoDB Memcached
rb://1048 approved by Sunny Bains
1 parent d030e17 commit aaace46

File tree

18 files changed

+910
-261
lines changed

18 files changed

+910
-261
lines changed

plugin/innodb_memcached/daemon_memcached/daemon/memcached.c

+50
Original file line numberDiff line numberDiff line change
@@ -4413,6 +4413,52 @@ static char *process_delete_command(conn *c, token_t *tokens,
44134413
return NULL;
44144414
}
44154415

4416+
static char *process_bind_command(conn *c, token_t *tokens,
4417+
const size_t ntokens) {
4418+
char *name;
4419+
size_t name_len;
4420+
4421+
assert(c != NULL);
4422+
4423+
if (ntokens > 3) {
4424+
out_string(c, "CLIENT_ERROR bad command line format. "
4425+
"Usage: bind <table_id_name>");
4426+
return NULL;
4427+
}
4428+
4429+
name = tokens[KEY_TOKEN].value;
4430+
name_len = tokens[KEY_TOKEN].length;
4431+
4432+
if (name_len > KEY_MAX_LENGTH || name_len == 0) {
4433+
out_string(c, "CLIENT_ERROR bad command line format");
4434+
return NULL;
4435+
}
4436+
4437+
ENGINE_ERROR_CODE ret = c->aiostat;
4438+
c->aiostat = ENGINE_SUCCESS;
4439+
c->ewouldblock = false;
4440+
if (ret == ENGINE_SUCCESS) {
4441+
ret = settings.engine.v1->bind(settings.engine.v0, c,
4442+
name, name_len);
4443+
}
4444+
4445+
/* For some reason the SLAB_INCR tries to access this... */
4446+
item_info info = { .nvalue = 1 };
4447+
switch (ret) {
4448+
case ENGINE_SUCCESS:
4449+
out_string(c, "SUCCEED");
4450+
break;
4451+
case ENGINE_EWOULDBLOCK:
4452+
c->ewouldblock = true;
4453+
return name;
4454+
case ENGINE_TMPFAIL:
4455+
default:
4456+
out_string(c, "NOT_FOUND");
4457+
}
4458+
4459+
return NULL;
4460+
}
4461+
44164462
static void process_verbosity_command(conn *c, token_t *tokens, const size_t ntokens) {
44174463
unsigned int level;
44184464

@@ -4508,6 +4554,10 @@ static char* process_command(conn *c, char *command) {
45084554

45094555
ret = process_delete_command(c, tokens, ntokens);
45104556

4557+
} else if (ntokens == 3 && (strcmp(tokens[COMMAND_TOKEN].value, "bind") == 0)) {
4558+
4559+
ret = process_bind_command(c, tokens, ntokens);
4560+
45114561
} else if (ntokens >= 2 && (strcmp(tokens[COMMAND_TOKEN].value, "stats") == 0)) {
45124562

45134563
ret = process_stat(c, tokens, ntokens);

plugin/innodb_memcached/daemon_memcached/include/memcached/engine.h

+4
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ extern "C" {
288288
uint64_t cas,
289289
uint16_t vbucket);
290290

291+
ENGINE_ERROR_CODE (*bind)(ENGINE_HANDLE* handle,
292+
const void* cookie,
293+
const void* name,
294+
const size_t name_len);
291295
/**
292296
* Indicate that a caller who received an item no longer needs
293297
* it.

plugin/innodb_memcached/innodb_memcache/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_SHARED_LIBRARY_C_FLAGS} -std=gnu99")
3939

4040
SET(INNODB_ENGINE_SOURCES
4141
src/innodb_config.c
42+
src/innodb_utility.c
4243
src/hash_item_util.c
4344
src/innodb_engine.c
4445
src/innodb_api.c

plugin/innodb_memcached/innodb_memcache/include/innodb_api.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,14 @@ column values. And "extra_col_value" and "n_extra_col" is used to support
8080
multiple value columns */
8181
typedef struct mci_item {
8282
mci_column_t col_value[MCI_COL_TO_GET]; /*!< columns in a row */
83-
mci_column_t* extra_col_value; /*!< whether there will be
83+
mci_column_t* extra_col_value; /*!< whether there will be
8484
additional/multiple "values"
8585
to be stored */
8686
int n_extra_col; /*!< number of additional
8787
"value" columns */
8888
} mci_item_t;
8989

90+
9091
/*************************************************************//**
9192
Register InnoDB Callback functions */
9293
void
@@ -116,7 +117,6 @@ Position a row accord to key, and fetch value if needed
116117
ib_err_t
117118
innodb_api_search(
118119
/*==============*/
119-
innodb_engine_t* engine, /*!< in: InnoDB Memcached engine */
120120
innodb_conn_data_t* cursor_data,/*!< in/out: cursor info */
121121
ib_crsr_t* crsr, /*!< in/out: cursor used to seacrh */
122122
const char* key, /*!< in: key to search */

plugin/innodb_memcached/innodb_memcache/include/innodb_cb_api.h

+15
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,13 @@ char*
283283
ib_crsr_t ib_crsr,
284284
ib_ulint_t i);
285285

286+
typedef
287+
char*
288+
(*cb_get_idx_field_name)(
289+
/*=====================*/
290+
ib_crsr_t ib_crsr,
291+
ib_ulint_t i);
292+
286293
typedef
287294
ib_err_t
288295
(*cb_table_truncate_t)(
@@ -296,6 +303,12 @@ ib_err_t
296303
/*=================*/
297304
ib_crsr_t ib_crsr);
298305

306+
typedef
307+
ib_err_t
308+
(*cb_cursor_next_t)(
309+
/*================*/
310+
ib_crsr_t ib_crsr);
311+
299312
typedef
300313
ib_err_t
301314
(*cb_cursor_last_t)(
@@ -389,8 +402,10 @@ cb_cursor_new_trx_t ib_cb_cursor_new_trx;
389402
cb_open_table_by_name_t ib_cb_open_table_by_name;
390403
cb_cursor_reset_t ib_cb_cursor_reset;
391404
cb_col_get_name_t ib_cb_col_get_name;
405+
cb_get_idx_field_name ib_cb_get_idx_field_name;
392406
cb_table_truncate_t ib_cb_table_truncate;
393407
cb_cursor_first_t ib_cb_cursor_first;
408+
cb_cursor_next_t ib_cb_cursor_next;
394409
cb_cursor_last_t ib_cb_cursor_last;
395410
cb_cursor_open_index_using_name_t ib_cb_cursor_open_index_using_name;
396411
cb_close_thd_t ib_cb_close_thd;

plugin/innodb_memcached/innodb_memcache/include/innodb_config.h

+87-9
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ Created 03/15/2011 Jimmy Yang
2626
#define innodb_config_h
2727

2828
#include "api0api.h"
29+
#include "innodb_utility.h"
2930

31+
typedef void* hash_node_t;
3032

3133
/* Database name and table name for our metadata "system" tables for
3234
InnoDB memcache. The table names are the same as those for the
@@ -52,7 +54,7 @@ There are 3 "system tables":
5254
/** structure describes each column's basic info (name, field_id etc.) */
5355
typedef struct meta_column {
5456
char* col_name; /*!< column name */
55-
int col_name_len; /*!< column name length */
57+
size_t col_name_len; /*!< column name length */
5658
int field_id; /*!< column field id in
5759
the table */
5860
ib_col_meta_t col_meta; /*!< column meta info */
@@ -138,6 +140,66 @@ typedef enum meta_cache_opt {
138140
META_CACHE_NUM_OPT /*!< Number of options */
139141
} meta_cache_opt_t;
140142

143+
/** The "names" in the "config_option" table to identify possible
144+
config options. Both are optional.
145+
"COLUMN_SEPARATOR" is the delimiter that separates multiple columns and
146+
"TABLE_MAP_SEPARATOR" is the delimiter that separates table map name
147+
and key value */
148+
#define COLUMN_SEPARATOR "separator"
149+
#define TABLE_MAP_SEPARATOR "table_map_delimiter"
150+
151+
/* list of configure options we support */
152+
typedef enum option_id {
153+
OPTION_ID_COL_SEP, /*!< ID for character(s) separating
154+
multiple column mapping */
155+
OPTION_ID_TBL_MAP_SEP, /*!< ID for character(s) separating
156+
table map name and key */
157+
OPTION_ID_NUM_OPTIONS /*!< number of options */
158+
} option_id_t;
159+
160+
/** Maximum delimiter length */
161+
#define MAX_DELIMITER_LEN 32
162+
163+
typedef struct option_value {
164+
char value[MAX_DELIMITER_LEN + 1];
165+
/* option value */
166+
int value_len; /* value length */
167+
} option_value_t;
168+
169+
/** structure to define some default "config_option" option settings */
170+
typedef struct option {
171+
option_id_t id; /*!< option id as in enum option_id */
172+
const char* name; /*!< option name for above option ID,
173+
currently they can be "COLUMN_SEPARATOR"
174+
and "TABLE_MAP_SEPARATOR" */
175+
option_value_t default_value; /*!< default value */
176+
} option_t;
177+
178+
/** Configure options enum IDs, their "names" and their default value */
179+
static option_t config_option_names[] =
180+
{
181+
{OPTION_ID_COL_SEP, COLUMN_SEPARATOR, {"|", 1}},
182+
{OPTION_ID_TBL_MAP_SEP, TABLE_MAP_SEPARATOR, {".", 1}}
183+
};
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+
141203
/** In memory structure contains most necessary metadata info
142204
to configure an InnoDB Memcached engine */
143205
typedef struct meta_cfg_info {
@@ -150,27 +212,34 @@ typedef struct meta_cfg_info {
150212
bool flag_enabled; /*!< whether flag is enabled */
151213
bool cas_enabled; /*!< whether cas is enabled */
152214
bool exp_enabled; /*!< whether exp is enabled */
153-
char* separator; /*!< separator that separates
154-
incoming "value" string for
155-
multiple columns */
156-
int sep_len; /*!< separator length */
215+
option_value_t options[OPTION_ID_NUM_OPTIONS];
216+
/*!< configure options, mostly
217+
are configured delimiters */
157218
meta_cache_opt_t set_option; /*!< cache option for "set" */
158219
meta_cache_opt_t get_option; /*!< cache option for "get" */
159220
meta_cache_opt_t del_option; /*!< cache option for
160221
"delete" */
161222
meta_cache_opt_t flush_option; /*!< cache option for
162223
"delete" */
224+
hash_node_t name_hash; /*!< name hash chain node */
163225
} meta_cfg_info_t;
164226

227+
165228
/**********************************************************************//**
166229
This function opens the default configuration table, and find the
167230
table and column info that used for InnoDB Memcached, and set up
168-
InnoDB Memcached's meta_cfg_info_t structure
169-
@return true if everything works out fine */
170-
bool
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*
171238
innodb_config(
172239
/*==========*/
173-
meta_cfg_info_t* item); /*!< out: meta info structure */
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 */
174243

175244
/**********************************************************************//**
176245
This function verifies the table configuration information, and fills
@@ -189,4 +258,13 @@ innodb_config_free(
189258
meta_cfg_info_t* item); /*!< in/own: meta info
190259
structure */
191260

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 */
192270
#endif

plugin/innodb_memcached/innodb_memcache/include/innodb_engine.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Created 03/15/2011 Jimmy Yang
3232
#include <memcached/engine.h>
3333
#include <memcached/util.h>
3434
#include <memcached/visibility.h>
35-
#include <innodb_list.h>
35+
#include <innodb_utility.h>
3636
#include <innodb_config.h>
3737

3838
/** Default settings that determine the number of write operation for
@@ -68,6 +68,8 @@ struct innodb_conn_data_struct {
6868
last commit */
6969
void* thd; /*!< MySQL THD, used for binlog */
7070
void* mysql_tbl; /*!< MySQL TABLE, used for binlog */
71+
meta_cfg_info_t*conn_meta; /*!< metadata info for this
72+
connection */
7173
UT_LIST_NODE_T(innodb_conn_data_t)
7274
conn_list; /*!< list ptr */
7375
};
@@ -112,7 +114,7 @@ typedef struct innodb_engine {
112114
ib_trx_level_t trx_level; /*!< transaction isolation
113115
level */
114116
int cfg_status; /*!< configure status */
115-
meta_cfg_info_t meta_info; /*!< metadata info from
117+
meta_cfg_info_t* meta_info; /*!< default metadata info from
116118
configuration */
117119
conn_list_t conn_data; /*!< list of data specific for
118120
connections */
@@ -126,6 +128,7 @@ typedef struct innodb_engine {
126128
size */
127129
uint64_t write_batch_size;/*!< configured write batch
128130
size */
131+
hash_table_t* meta_hash; /*!< hash table for metadata */
129132
} innodb_engine_t;
130133

131134
#endif /* INNODB_ENGINE_H */

0 commit comments

Comments
 (0)