diff options
author | Michael Widenius <monty@askmonty.org> | 2012-08-01 17:27:34 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2012-08-01 17:27:34 +0300 |
commit | 1d0f70c2f894b27e98773a282871d32802f67964 (patch) | |
tree | 833e683e0ced29c4323c29a9d845703d4dfcd81b /storage/innobase/include/row0merge.h | |
parent | 5a86a61219826aadf8d08cbc447fe438f2bf50c3 (diff) | |
download | mariadb-git-1d0f70c2f894b27e98773a282871d32802f67964.tar.gz |
Temporary commit of merge of MariaDB 10.0-base and MySQL 5.6
Diffstat (limited to 'storage/innobase/include/row0merge.h')
-rw-r--r-- | storage/innobase/include/row0merge.h | 203 |
1 files changed, 195 insertions, 8 deletions
diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h index be7c77e7724..c4e2f5ddf41 100644 --- a/storage/innobase/include/row0merge.h +++ b/storage/innobase/include/row0merge.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2005, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 2005, 2010, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA *****************************************************************************/ @@ -38,6 +38,58 @@ Created 13/06/2005 Jan Lindstrom #include "btr0types.h" #include "row0mysql.h" #include "lock0types.h" +#include "srv0srv.h" + +/** @brief Block size for I/O operations in merge sort. + +The minimum is UNIV_PAGE_SIZE, or page_get_free_space_of_empty() +rounded to a power of 2. + +When not creating a PRIMARY KEY that contains column prefixes, this +can be set as small as UNIV_PAGE_SIZE / 2. See the comment above +ut_ad(data_size < sizeof(row_merge_block_t)). */ +typedef byte row_merge_block_t; + +/** @brief Secondary buffer for I/O operations of merge records. + +This buffer is used for writing or reading a record that spans two +row_merge_block_t. Thus, it must be able to hold one merge record, +whose maximum size is the same as the minimum size of +row_merge_block_t. */ +typedef byte mrec_buf_t[UNIV_PAGE_SIZE_MAX]; + +/** @brief Merge record in row_merge_block_t. + +The format is the same as a record in ROW_FORMAT=COMPACT with the +exception that the REC_N_NEW_EXTRA_BYTES are omitted. */ +typedef byte mrec_t; + +/** Buffer for sorting in main memory. */ +struct row_merge_buf_struct { + mem_heap_t* heap; /*!< memory heap where allocated */ + dict_index_t* index; /*!< the index the tuples belong to */ + ulint total_size; /*!< total amount of data bytes */ + ulint n_tuples; /*!< number of data tuples */ + ulint max_tuples; /*!< maximum number of data tuples */ + const dfield_t**tuples; /*!< array of pointers to + arrays of fields that form + the data tuples */ + const dfield_t**tmp_tuples; /*!< temporary copy of tuples, + for sorting */ +}; + +/** Buffer for sorting in main memory. */ +typedef struct row_merge_buf_struct row_merge_buf_t; + +/** Information about temporary files used in merge sort */ +struct merge_file_struct { + int fd; /*!< file descriptor */ + ulint offset; /*!< file offset (end of file) */ + ib_uint64_t n_rec; /*!< number of records in the file */ +}; + +/** Information about temporary files used in merge sort */ +typedef struct merge_file_struct merge_file_t; /** Index field definition */ struct merge_index_field_struct { @@ -47,7 +99,7 @@ struct merge_index_field_struct { }; /** Index field definition */ -typedef struct merge_index_field_struct merge_index_field_t; +typedef struct merge_index_field_struct merge_index_field_t; /** Definition of an index being created */ struct merge_index_def_struct { @@ -60,7 +112,17 @@ struct merge_index_def_struct { }; /** Definition of an index being created */ -typedef struct merge_index_def_struct merge_index_def_t; +typedef struct merge_index_def_struct merge_index_def_t; + +/** Structure for reporting duplicate records. */ +struct row_merge_dup_struct { + const dict_index_t* index; /*!< index being sorted */ + struct TABLE* table; /*!< MySQL table object */ + ulint n_dup; /*!< number of duplicates */ +}; + +/** Structure for reporting duplicate records. */ +typedef struct row_merge_dup_struct row_merge_dup_t; /*********************************************************************//** Sets an exclusive lock on a table, for the duration of creating indexes. @@ -95,7 +157,8 @@ row_merge_drop_indexes( trx_t* trx, /*!< in: transaction */ dict_table_t* table, /*!< in: table containing the indexes */ dict_index_t** index, /*!< in: indexes to drop */ - ulint num_created); /*!< in: number of elements in index[] */ + ulint num_created); /*!< in: number of elements in + index[] */ /*********************************************************************//** Drop all partially created indexes during crash recovery. */ UNIV_INTERN @@ -117,7 +180,6 @@ row_merge_rename_tables( old_table->name */ const char* tmp_name, /*!< in: new name for old_table */ trx_t* trx); /*!< in: transaction handle */ - /*********************************************************************//** Create a temporary table for creating a primary key, using the definition of an existing table. @@ -173,7 +235,6 @@ row_merge_drop_table( /*=================*/ trx_t* trx, /*!< in: transaction */ dict_table_t* table); /*!< in: table instance to drop */ - /*********************************************************************//** Build indexes on a table by reading a clustered index, creating a temporary file containing index entries, merge sorting @@ -194,4 +255,130 @@ row_merge_build_indexes( struct TABLE* table); /*!< in/out: MySQL table, for reporting erroneous key value if applicable */ +/********************************************************************//** +Write a buffer to a block. */ +UNIV_INTERN +void +row_merge_buf_write( +/*================*/ + const row_merge_buf_t* buf, /*!< in: sorted buffer */ + const merge_file_t* of, /*!< in: output file */ + row_merge_block_t* block); /*!< out: buffer for writing to file */ +/********************************************************************//** +Sort a buffer. */ +UNIV_INTERN +void +row_merge_buf_sort( +/*===============*/ + row_merge_buf_t* buf, /*!< in/out: sort buffer */ + row_merge_dup_t* dup); /*!< in/out: for reporting duplicates */ +/********************************************************************//** +Write a merge block to the file system. +@return TRUE if request was successful, FALSE if fail */ +UNIV_INTERN +ibool +row_merge_write( +/*============*/ + int fd, /*!< in: file descriptor */ + ulint offset, /*!< in: offset where to write, + in number of row_merge_block_t elements */ + const void* buf); /*!< in: data */ +/********************************************************************//** +Empty a sort buffer. +@return sort buffer */ +UNIV_INTERN +row_merge_buf_t* +row_merge_buf_empty( +/*================*/ + row_merge_buf_t* buf); /*!< in,own: sort buffer */ +/*********************************************************************//** +Create a merge file. */ +UNIV_INTERN +void +row_merge_file_create( +/*==================*/ + merge_file_t* merge_file); /*!< out: merge file structure */ +/*********************************************************************//** +Merge disk files. +@return DB_SUCCESS or error code */ +UNIV_INTERN +ulint +row_merge_sort( +/*===========*/ + trx_t* trx, /*!< in: transaction */ + const dict_index_t* index, /*!< in: index being created */ + merge_file_t* file, /*!< in/out: file containing + index entries */ + row_merge_block_t* block, /*!< in/out: 3 buffers */ + int* tmpfd, /*!< in/out: temporary file handle */ + struct TABLE* table); /*!< in/out: MySQL table, for + reporting erroneous key value + if applicable */ +/*********************************************************************//** +Allocate a sort buffer. +@return own: sort buffer */ +UNIV_INTERN +row_merge_buf_t* +row_merge_buf_create( +/*=================*/ + dict_index_t* index); /*!< in: secondary index */ +/*********************************************************************//** +Deallocate a sort buffer. */ +UNIV_INTERN +void +row_merge_buf_free( +/*===============*/ + row_merge_buf_t* buf); /*!< in,own: sort buffer, to be freed */ +/*********************************************************************//** +Destroy a merge file. */ +UNIV_INTERN +void +row_merge_file_destroy( +/*===================*/ + merge_file_t* merge_file); /*!< out: merge file structure */ +/*********************************************************************//** +Compare two merge records. +@return 1, 0, -1 if mrec1 is greater, equal, less, respectively, than mrec2 */ +UNIV_INTERN +int +row_merge_cmp( +/*==========*/ + const mrec_t* mrec1, /*!< in: first merge + record to be compared */ + const mrec_t* mrec2, /*!< in: second merge + record to be compared */ + const ulint* offsets1, /*!< in: first record offsets */ + const ulint* offsets2, /*!< in: second record offsets */ + const dict_index_t* index, /*!< in: index */ + ibool* null_eq); /*!< out: set to TRUE if + found matching null values */ +/********************************************************************//** +Read a merge block from the file system. +@return TRUE if request was successful, FALSE if fail */ +UNIV_INTERN +ibool +row_merge_read( +/*===========*/ + int fd, /*!< in: file descriptor */ + ulint offset, /*!< in: offset where to read + in number of row_merge_block_t + elements */ + row_merge_block_t* buf); /*!< out: data */ +/********************************************************************//** +Read a merge record. +@return pointer to next record, or NULL on I/O error or end of list */ +UNIV_INTERN __attribute__((nonnull)) +const byte* +row_merge_read_rec( +/*===============*/ + row_merge_block_t* block, /*!< in/out: file buffer */ + mrec_buf_t* buf, /*!< in/out: secondary buffer */ + const byte* b, /*!< in: pointer to record */ + const dict_index_t* index, /*!< in: index of the record */ + int fd, /*!< in: file descriptor */ + ulint* foffs, /*!< in/out: file offset */ + const mrec_t** mrec, /*!< out: pointer to merge record, + or NULL on end of list + (non-NULL on I/O error) */ + ulint* offsets);/*!< out: offsets of mrec */ #endif /* row0merge.h */ |