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