From 63aaf187d040a8cab07bfdbfe1abaf2126c37b10 Mon Sep 17 00:00:00 2001 From: Konstantin Osipov <kostja@tarantool.org> Date: Wed, 3 Jul 2013 17:10:05 +0400 Subject: [PATCH] Refactor space_new() so that it's used universally. Refactor space cache code, create indexes in space_create(). Remove init_storage option. --- include/box/box.h | 2 +- include/tarantool.h | 2 +- src/box/box.cc | 8 +-- src/box/key_def.h | 3 +- src/box/space.cc | 136 ++++++++++++++++++++++++-------------------- src/box/space.h | 33 +---------- src/memcached.cc | 11 +--- src/tarantool.cc | 16 ++++-- 8 files changed, 92 insertions(+), 119 deletions(-) diff --git a/include/box/box.h b/include/box/box.h index 08cd9cb2c3..2070dd9bca 100644 --- a/include/box/box.h +++ b/include/box/box.h @@ -49,7 +49,7 @@ struct tarantool_cfg; struct lua_State; /** To be called at program start. */ -void box_init(void); +void box_init(bool init_storage); /** To be called at program end. */ void box_free(void); diff --git a/include/tarantool.h b/include/tarantool.h index 017ae42881..a32850acf2 100644 --- a/include/tarantool.h +++ b/include/tarantool.h @@ -42,7 +42,7 @@ extern int snapshot_pid; extern struct tarantool_cfg cfg; extern const char *cfg_filename; extern char *cfg_filename_fullpath; -extern bool init_storage, booting; +extern bool booting; extern char *binary_filename; extern char *custom_proc_title; int reload_cfg(struct tbuf *out); diff --git a/src/box/box.cc b/src/box/box.cc index 019ee1bc99..ae16024ae0 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -119,8 +119,6 @@ process_ro(struct port *port, uint32_t op, const char *reqdata, uint32_t reqlen) static void recover_snap_row(const void *data) { - assert(primary_indexes_enabled == false); - const struct box_snap_row *row = (const struct box_snap_row *) data; struct space *space = space_find(row->space); @@ -323,7 +321,7 @@ box_free(void) } void -box_init(void) +box_init(bool init_storage) { title("loading"); atexit(box_free); @@ -400,10 +398,6 @@ snapshot_space(struct space *sp, void *udata) void box_snapshot(struct log_io *l, struct fio_batch *batch) { - /* --init-storage switch */ - if (primary_indexes_enabled == false) - return; - struct snapshot_space_param ud = { l, batch }; space_foreach(snapshot_space, &ud); diff --git a/src/box/key_def.h b/src/box/key_def.h index c25644ae39..1d0a395800 100644 --- a/src/box/key_def.h +++ b/src/box/key_def.h @@ -79,7 +79,8 @@ struct key_def { struct tarantool_cfg_space_index; void -key_def_create(struct key_def *def, struct tarantool_cfg_space_index *cfg_index); +key_def_create(struct key_def *def, + struct tarantool_cfg_space_index *cfg_index); void key_def_destroy(struct key_def *def); diff --git a/src/box/space.cc b/src/box/space.cc index 4d65ec4529..1a9701a6d4 100644 --- a/src/box/space.cc +++ b/src/box/space.cc @@ -44,29 +44,80 @@ extern "C" { static struct mh_i32ptr_t *spaces; -bool secondary_indexes_enabled = false; -bool primary_indexes_enabled = false; +/** + * Secondary indexes are built in bulk after all data is + * recovered. This flag indicates that the indexes are + * already built and ready for use. + */ +static bool secondary_indexes_enabled = false; +/** + * Primary indexes are enabled only after reading the snapshot. + */ +static bool primary_indexes_enabled = false; -struct space * -space_create(uint32_t space_no, struct key_def *key_defs, uint32_t key_count, uint32_t arity) +static void +space_init_field_types(struct space *space); + +static void +space_create(struct space *space, uint32_t space_no, + struct key_def *key_defs, uint32_t key_count, + uint32_t arity) { + memset(space, 0, sizeof(struct space)); + space->no = space_no; + space->arity = arity; + space->key_defs = key_defs; + space->key_count = key_count; + space_init_field_types(space); + /* fill space indexes */ + for (uint32_t j = 0; j < key_count; ++j) { + struct key_def *key_def = &space->key_defs[j]; + Index *index = Index::factory(key_def->type, key_def, space); + if (index == NULL) { + tnt_raise(LoggedError, ER_MEMORY_ISSUE, + "class Index", "malloc"); + } + space->index[j] = index; + } +} + +static void +space_destroy(struct space *space) +{ + for (uint32_t j = 0 ; j < space->key_count; j++) { + Index *index = space->index[j]; + delete index; + key_def_destroy(&space->key_defs[j]); + } + free(space->key_defs); + free(space->field_types); +} +struct space * +space_new(uint32_t space_no, struct key_def *key_defs, + uint32_t key_count, uint32_t arity) +{ struct space *space = space_by_n(space_no); if (space) - panic("Space %d is already exists", space_no); - space = (struct space *) calloc(sizeof(struct space), 1); - space->no = space_no; + tnt_raise(LoggedError, ER_SPACE_EXISTS, space_no); + + space = (struct space *) malloc(sizeof(struct space)); + + space_create(space, space_no, key_defs, key_count, arity); const struct mh_i32ptr_node_t node = { space->no, space }; mh_i32ptr_put(spaces, &node, NULL, NULL); - space->arity = arity; - space->key_defs = key_defs; - space->key_count = key_count; - return space; } +static void +space_delete(struct space *space) +{ + mh_i32ptr_del(spaces, space->no, NULL); + space_destroy(space); + free(space); +} /* return space by its number */ struct space * @@ -109,14 +160,6 @@ space_foreach(void (*func)(struct space *sp, void *udata), void *udata) { } } -/** Set index by index no */ -void -space_set_index(struct space *sp, uint32_t index_no, Index *idx) -{ - assert(index_no < BOX_INDEX_MAX); - sp->index[index_no] = idx; -} - struct tuple * space_replace(struct space *sp, struct tuple *old_tuple, struct tuple *new_tuple, enum dup_replace_mode mode) @@ -200,19 +243,10 @@ space_free(void) mh_foreach(spaces, i) { struct space *space = (struct space *) mh_i32ptr_node(spaces, i)->val; - mh_i32ptr_del(spaces, i, NULL); - - for (uint32_t j = 0 ; j < space->key_count; j++) { - Index *index = space->index[j]; - delete index; - key_def_destroy(&space->key_defs[j]); - } - - free(space->key_defs); - free(space->field_types); - free(space); + space_delete(space); } + } /** @@ -280,50 +314,26 @@ space_config() assert(cfg.memcached_port == 0 || i != cfg.memcached_space); - struct space *space = space_by_n(i); - if (space) - panic("space %u is already exists", i); - - space = (struct space *) calloc(sizeof(struct space), 1); - space->no = i; - - space->arity = (cfg_space->cardinality != -1) ? - cfg_space->cardinality : 0; + uint32_t arity = (cfg_space->cardinality != -1 ? + cfg_space->cardinality : 0); /* * Collect key/field info. We need aggregate * information on all keys before we can create * indexes. */ - space->key_count = 0; - for (uint32_t j = 0; cfg_space->index[j] != NULL; ++j) { - ++space->key_count; - } - + uint32_t key_count = 0; + while (cfg_space->index[key_count] != NULL) + key_count++; - space->key_defs = (struct key_def *) malloc(space->key_count * - sizeof(struct key_def)); - if (space->key_defs == NULL) { - panic("can't allocate key def array"); - } - for (uint32_t j = 0; cfg_space->index[j] != NULL; ++j) { - auto cfg_index = cfg_space->index[j]; - key_def_create(&space->key_defs[j], cfg_index); - } - space_init_field_types(space); + struct key_def *key_defs = (struct key_def *) + malloc(key_count * sizeof(struct key_def)); - /* fill space indexes */ for (uint32_t j = 0; cfg_space->index[j] != NULL; ++j) { auto cfg_index = cfg_space->index[j]; - enum index_type type = STR2ENUM(index_type, cfg_index->type); - struct key_def *key_def = &space->key_defs[j]; - Index *index = Index::factory(type, key_def, space); - assert(index != NULL); - space->index[j] = index; + key_def_create(&key_defs[j], cfg_index); } + (void) space_new(i, key_defs, key_count, arity); - const struct mh_i32ptr_node_t node = - { space->no, space }; - mh_i32ptr_put(spaces, &node, NULL, NULL); say_info("space %i successfully configured", i); } } diff --git a/src/box/space.h b/src/box/space.h index 730f42938a..aab8539dab 100644 --- a/src/box/space.h +++ b/src/box/space.h @@ -191,10 +191,6 @@ space_index(struct space *sp, uint32_t index_no) return NULL; } -/** Set index by index no. */ -void -space_set_index(struct space *sp, uint32_t index_no, Index *idx); - /** * Call a visitor function on every enabled space. */ @@ -218,7 +214,6 @@ space_find(uint32_t space_no) tnt_raise(ClientError, ER_NO_SUCH_SPACE, space_no); } - /** Get key_def ordinal number. */ static inline uint32_t key_def_n(struct space *sp, struct key_def *kp) @@ -227,21 +222,9 @@ key_def_n(struct space *sp, struct key_def *kp) return kp - sp->key_defs; } -static inline uint32_t -space_max_fieldno(struct space *sp) -{ - return sp->max_fieldno; -} - -static inline enum field_type -space_field_type(struct space *sp, uint32_t no) -{ - return sp->field_types[no]; -} - - struct space * -space_create(uint32_t space_no, struct key_def *key_defs, uint32_t key_count, uint32_t arity); +space_new(uint32_t space_no, struct key_def *key_defs, + uint32_t key_count, uint32_t arity); /** Get index ordinal number in space. */ @@ -258,17 +241,6 @@ index_is_primary(Index *index) return index_n(index) == 0; } -/** - * Secondary indexes are built in bulk after all data is - * recovered. This flag indicates that the indexes are - * already built and ready for use. - */ -extern bool secondary_indexes_enabled; -/** - * Primary indexes are enabled only after reading the snapshot. - */ -extern bool primary_indexes_enabled; - void space_init(void); void space_free(void); int @@ -278,7 +250,6 @@ void begin_build_primary_indexes(void); void end_build_primary_indexes(void); void build_secondary_indexes(void); - static inline Index * index_find(struct space *sp, uint32_t index_no) { diff --git a/src/memcached.cc b/src/memcached.cc index 5494b5862b..7e99cf54a6 100644 --- a/src/memcached.cc +++ b/src/memcached.cc @@ -501,7 +501,6 @@ memcached_space_init() if (cfg.memcached_port == 0) return; - /* Configure memcached index key. */ struct key_def *key_def = (struct key_def *) malloc(sizeof(struct key_def)); key_def->part_count = 1; @@ -511,21 +510,13 @@ memcached_space_init() key_def->parts = (struct key_part *) malloc(sizeof(struct key_part)); key_def->cmp_order = (uint32_t *) malloc(sizeof(uint32_t)); - if (key_def->parts == NULL || key_def->cmp_order == NULL) - panic("out of memory when configuring memcached_space"); - key_def->parts[0].fieldno = 0; key_def->parts[0].type = STRING; key_def->max_fieldno = 1; key_def->cmp_order[0] = 0; - - struct space *memc_s = - space_create(cfg.memcached_space, key_def, 1, 4); - - Index *memc_index = Index::factory(HASH, key_def, memc_s); - space_set_index(memc_s, 0, memc_index); + (void) space_new(cfg.memcached_space, key_def, 1, 4); } /** Delete a bunch of expired keys. */ diff --git a/src/tarantool.cc b/src/tarantool.cc index 22c8766928..680f52a9a0 100644 --- a/src/tarantool.cc +++ b/src/tarantool.cc @@ -84,7 +84,7 @@ struct tarantool_cfg cfg; static ev_signal *sigs = NULL; int snapshot_pid = 0; /* snapshot processes pid */ -bool init_storage, booting = true; +bool booting = true; extern const void *opt_def; static int @@ -622,6 +622,13 @@ initialize_minimal() coeio_init(); } +/** Callback of snapshot_save() when doing --init-storage */ +void +init_storage(struct log_io * /* l */, struct fio_batch * /* batch */) +{ + /* Nothing. */ +} + int main(int argc, char **argv) { @@ -790,11 +797,10 @@ main(int argc, char **argv) } if (gopt(opt, 'I')) { - init_storage = true; initialize_minimal(); - box_init(); + box_init(true); set_lsn(recovery_state, 1); - snapshot_save(recovery_state, box_snapshot); + snapshot_save(recovery_state, init_storage); exit(EXIT_SUCCESS); } @@ -838,7 +844,7 @@ main(int argc, char **argv) try { tarantool_L = tarantool_lua_init(); - box_init(); + box_init(false); memcached_init(cfg.bind_ipaddr, cfg.memcached_port); tarantool_lua_load_cfg(tarantool_L, &cfg); /* -- GitLab