Commit e2a6db40 authored by marko's avatar marko

branches/zip: Some more cleanup of fast index creation.

Move more definitions from row0mysql.h to row0mysql.c.  Remove the
unused definition of merge_thread.

merge_index_def_t: Replace merge_index_field_t** with merge_index_field_t*.
Use mem_heap_strdup() when copying strings.

ha_innobase::add_index(): Avoid excessive use of current_thd.
parent f2bcb9ca
......@@ -7817,29 +7817,22 @@ innobase_check_index_keys(
/***********************************************************************
Create index field definition for key part */
static
merge_index_field_t*
void
innobase_create_index_field_def(
/*============================*/
/* out: Index field definition for
this key part */
KEY_PART_INFO* key_part, /* in: Key definition */
mem_heap_t* heap) /* in: heap where memory is allocated */
KEY_PART_INFO* key_part, /* in: MySQL key definition */
mem_heap_t* heap, /* in: memory heap */
merge_index_field_t* index_field) /* out: index field
definition for key_part */
{
Field* field;
merge_index_field_t* index_field;
ibool is_unsigned;
ulint col_type;
ulint len;
DBUG_ENTER("innobase_create_index_field_def");
ut_a(key_part && heap);
index_field = (merge_index_field_t*) mem_heap_alloc_noninline(
heap,
sizeof(merge_index_field_t));
ut_a(index_field);
ut_ad(key_part);
ut_ad(index_field);
field = key_part->field;
ut_a(field);
......@@ -7860,11 +7853,9 @@ innobase_create_index_field_def(
index_field->prefix_len = 0;
}
len = strlen(field->field_name) + 1;
index_field->field_name = (char *)mem_heap_alloc_noninline(heap, len);
memcpy(index_field->field_name, field->field_name, len);
index_field->field_name = mem_heap_strdup(heap, field->field_name);
DBUG_RETURN(index_field);
DBUG_VOID_RETURN;
}
/***********************************************************************
......@@ -7888,8 +7879,8 @@ innobase_create_index_def(
index = (merge_index_def_t*) mem_heap_alloc_noninline(
heap, sizeof(merge_index_def_t));
index->fields = (merge_index_field_t**) mem_heap_alloc_noninline(
heap, sizeof(merge_index_field_t*) * n_fields);
index->fields = (merge_index_field_t*) mem_heap_alloc_noninline(
heap, n_fields * sizeof *index->fields);
index->ind_type = 0;
index->n_fields = n_fields;
......@@ -7914,11 +7905,8 @@ innobase_create_index_def(
}
for (ulint i = 0; i < n_fields; i++) {
KEY_PART_INFO* key_part;
key_part = key->key_part + i;
index->fields[i] = innobase_create_index_field_def(
key_part, heap);
innobase_create_index_field_def(&key->key_part[i], heap,
&index->fields[i]);
}
DBUG_RETURN(index);
......@@ -7927,32 +7915,22 @@ innobase_create_index_def(
/***********************************************************************
Copy index field definition */
static
merge_index_field_t*
void
innobase_copy_index_field_def(
/*==========================*/
/* out: Index field definition for
this index */
dict_field_t* field, /* in: Index definition to copy*/
mem_heap_t* heap) /* in: heap where memory is allocated */
const dict_field_t* field, /* in: definition to copy */
mem_heap_t* heap, /* in: memory heap */
merge_index_field_t* index_field) /* out: copied definition */
{
merge_index_field_t* index_field;
ulint len;
DBUG_ENTER("innobase_copy_index_field_def");
ut_a(field && heap);
index_field = (merge_index_field_t*) mem_heap_alloc_noninline(
heap,
sizeof(merge_index_field_t));
DBUG_ASSERT(field != NULL);
DBUG_ASSERT(index_field != NULL);
index_field->col_type = (field->col->prtype & 0xFFUL);
len = strlen(field->name) + 1;
index_field->field_name = (char *)mem_heap_alloc_noninline(heap, len);
memcpy(index_field->field_name, field->name, len);
index_field->field_name = mem_heap_strdup(heap, field->name);
index_field->prefix_len = field->prefix_len;
DBUG_RETURN(index_field);
DBUG_VOID_RETURN;
}
/***********************************************************************
......@@ -7968,7 +7946,6 @@ innobase_copy_index_def(
merge_index_def_t* new_index;
ulint n_fields;
ulint i;
ulint len;
DBUG_ENTER("innobase_copy_index_def");
......@@ -7988,20 +7965,16 @@ innobase_copy_index_def(
new_index = (merge_index_def_t*) mem_heap_alloc_noninline(
heap, sizeof(merge_index_def_t));
new_index->fields = (merge_index_field_t**) mem_heap_alloc_noninline(
heap, sizeof(merge_index_field_t*) * n_fields);
new_index->fields = (merge_index_field_t*) mem_heap_alloc_noninline(
heap, n_fields * sizeof *new_index->fields);
new_index->ind_type = index->type;
new_index->n_fields = n_fields;
len = strlen(index->name) + 1;
new_index->name = (char *)mem_heap_alloc_noninline(heap, len);
memcpy(new_index->name, index->name, len);
new_index->name = mem_heap_strdup(heap, index->name);
for (i = 0; i < n_fields; i++) {
dict_field_t* field = ((index->fields) + i);
new_index->fields[i] = innobase_copy_index_field_def(
field, heap);
innobase_copy_index_field_def(&index->fields[i], heap,
&new_index->fields[i]);
}
DBUG_RETURN(new_index);
......@@ -8154,9 +8127,11 @@ ha_innobase::add_index(
DBUG_ENTER("ha_innobase::add_index");
ut_a(table && key_info && num_of_keys);
update_thd(current_thd);
index = NULL;
parent_trx = check_trx_exists(ht, current_thd);
parent_trx = check_trx_exists(ht, user_thd);
trx_search_latch_release_if_reserved(parent_trx);
trx = parent_trx;
......@@ -8164,14 +8139,14 @@ ha_innobase::add_index(
trx_start_if_not_started_noninline(trx);
trx->mysql_thd = current_thd;
trx->mysql_query_str = &((*current_thd).query);
trx->mysql_thd = user_thd;
trx->mysql_query_str = &user_thd->query;
if (current_thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
if (user_thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
trx->check_foreigns = FALSE;
}
if (current_thd->options & OPTION_RELAXED_UNIQUE_CHECKS) {
if (user_thd->options & OPTION_RELAXED_UNIQUE_CHECKS) {
trx->check_unique_secondary = FALSE;
}
......@@ -8186,7 +8161,7 @@ ha_innobase::add_index(
if (error != DB_SUCCESS) {
trx_general_rollback_for_mysql(trx, FALSE, NULL);
error = convert_error_code_to_mysql(error, current_thd);
error = convert_error_code_to_mysql(error, user_thd);
DBUG_RETURN((int)error);
}
......@@ -8212,7 +8187,7 @@ ha_innobase::add_index(
new_primary = TRUE;
new_table_name = innobase_create_temporary_tablename(
current_thd, (const char *)innodb_table->name, 17431);
user_thd, (const char *)innodb_table->name, 17431);
row_mysql_lock_data_dictionary(trx);
......@@ -8227,7 +8202,7 @@ ha_innobase::add_index(
if (error != DB_SUCCESS) {
mem_heap_free_noninline(heap);
trx_general_rollback_for_mysql(trx, FALSE, NULL);
error = convert_error_code_to_mysql(error, current_thd);
error = convert_error_code_to_mysql(error, user_thd);
DBUG_RETURN((int)error);
}
......@@ -8360,7 +8335,7 @@ ha_innobase::add_index(
strcpy(old_name, innodb_table->name);
tmp_table_name = innobase_create_temporary_tablename(
current_thd, (const char *)innodb_table->name, 232125);
user_thd, (const char *)innodb_table->name, 232125);
trx_start_if_not_started_noninline(trx);
......@@ -8404,7 +8379,7 @@ ha_innobase::add_index(
/* There might be work for utility threads.*/
srv_active_wake_master_thread();
error = convert_error_code_to_mysql(error, current_thd);
error = convert_error_code_to_mysql(error, user_thd);
DBUG_RETURN((int)error);
}
......
......@@ -21,37 +21,6 @@ Created 13/06/2005 Jan Lindstrom
#include "btr0types.h"
#include "row0mysql.h"
/* Block size for I/O operations in merge sort */
#define MERGE_BLOCK_SIZE 1048576 /* 1M */
/* Intentional free space on every block */
#define MERGE_BLOCK_SAFETY_MARGIN 128
/* Enable faster index creation debug code */
/* #define UNIV_DEBUG_INDEX_CREATE 1 */
/* This block header structure is used to create linked list of the
blocks to the disk. Every block contains one header.*/
struct merge_block_header_struct {
ulint n_records; /* Number of records in the block. */
dulint offset; /* Offset of this block in the disk. */
dulint next; /* Offset to next block in the disk. */
};
typedef struct merge_block_header_struct merge_block_header_t;
/* This block structure is used to hold index records in the disk
and the memory */
struct merge_block_struct {
merge_block_header_t header; /* Block header information */
char data[MERGE_BLOCK_SIZE - sizeof(merge_block_header_t)];/* Data area i.e. heap */
};
typedef struct merge_block_struct merge_block_t;
/* Information about temporary files used in merge sort are stored
to this structure */
......@@ -63,19 +32,6 @@ struct merge_file_struct {
typedef struct merge_file_struct merge_file_t;
/* This structure holds parameters to thread which does a
disk based merge sort and inserts index records */
struct merge_thread_struct {
dict_index_t* index; /* in: Index to be created */
row_prebuilt_t* prebuilt; /* in: Prebuilt */
trx_t* trx; /* in: trx */
os_file_t file; /* in: File handle */
int error; /* out: error code or 0 */
};
typedef struct merge_thread_struct merge_thread_t;
/* This structure holds index field definitions */
struct merge_index_field_struct {
......@@ -92,7 +48,7 @@ struct merge_index_def_struct {
ulint n_fields; /* Number of fields in index */
ulint ind_type; /* 0, DICT_UNIQUE or DICT_CLUSTERED */
char* name; /* Index name */
merge_index_field_t** fields; /* Field definitions */
merge_index_field_t* fields; /* Field definitions */
};
typedef struct merge_index_def_struct merge_index_def_t;
......
......@@ -85,6 +85,37 @@ struct merge_rec_list_struct {
typedef struct merge_rec_list_struct merge_rec_list_t;
/* Block size for I/O operations in merge sort */
#define MERGE_BLOCK_SIZE 1048576 /* 1M */
/* Intentional free space on every block */
#define MERGE_BLOCK_SAFETY_MARGIN 128
/* Enable faster index creation debug code */
/* #define UNIV_DEBUG_INDEX_CREATE 1 */
/* This block header structure is used to create linked list of the
blocks to the disk. Every block contains one header.*/
struct merge_block_header_struct {
ulint n_records; /* Number of records in the block. */
dulint offset; /* Offset of this block in the disk. */
dulint next; /* Offset to next block in the disk. */
};
typedef struct merge_block_header_struct merge_block_header_t;
/* This block structure is used to hold index records in the disk
and the memory */
struct merge_block_struct {
merge_block_header_t header; /* Block header information */
char data[MERGE_BLOCK_SIZE - sizeof(merge_block_header_t)];/* Data area i.e. heap */
};
typedef struct merge_block_struct merge_block_t;
static
dict_index_t*
row_merge_dict_table_get_index(
......@@ -101,7 +132,7 @@ row_merge_dict_table_get_index(
index_def->n_fields * sizeof(char*));
for (i = 0; i < index_def->n_fields; ++i) {
column_names[i] = index_def->fields[i]->field_name;
column_names[i] = index_def->fields[i].field_name;
}
index = dict_table_get_index_by_max_id(
......@@ -2150,13 +2181,11 @@ row_merge_create_index(
for (i = 0; i < n_fields; i++) {
merge_index_field_t* ifield;
ifield = index_def->fields[i];
/* TODO: [What's this comment] We assume all fields
should be sorted in ascending order, hence the '0' */
ifield = &index_def->fields[i];
dict_mem_index_add_field(
*index, ifield->field_name, ifield->prefix_len);
dict_mem_index_add_field(*index,
ifield->field_name,
ifield->prefix_len);
}
/* Add the index to SYS_INDEXES, this will use the prototype
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment