diff options
author | Mattias Jonsson <mattias.jonsson@oracle.com> | 2012-08-15 14:56:55 +0200 |
---|---|---|
committer | Mattias Jonsson <mattias.jonsson@oracle.com> | 2012-08-15 14:56:55 +0200 |
commit | 404cce0ff82402c24c869a75606f329bfe9da9e9 (patch) | |
tree | 260d78771471eaa7564ad7b038429d2ab252b628 /sql | |
parent | 94bd7bd6b7687cf654df90b22a85425cf72af55c (diff) | |
parent | bcee9f1896ab6015e77ea88fde5317f50edaead7 (diff) | |
download | mariadb-git-404cce0ff82402c24c869a75606f329bfe9da9e9.tar.gz |
manual merge 5.1->5.5
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_partition.cc | 126 | ||||
-rw-r--r-- | sql/ha_partition.h | 13 |
2 files changed, 100 insertions, 39 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 1debc02d7f2..52134171491 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -320,7 +320,7 @@ ha_partition::~ha_partition() for (i= 0; i < m_tot_parts; i++) delete m_file[i]; } - my_free(m_ordered_rec_buffer); + destroy_record_priority_queue(); my_free(m_part_ids_sorted_by_num_of_records); clear_handler_file(); @@ -2638,7 +2638,6 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) { char *name_buffer_ptr; int error= HA_ERR_INITIALIZATION; - uint alloc_len; handler **file; char name_buff[FN_REFLEN]; bool is_not_tmp_table= (table_share->tmp_table == NO_TMP_TABLE); @@ -2656,32 +2655,6 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) m_start_key.length= 0; m_rec0= table->record[0]; m_rec_length= table_share->reclength; - alloc_len= m_tot_parts * (m_rec_length + PARTITION_BYTES_IN_POS); - alloc_len+= table_share->max_key_length; - if (!m_ordered_rec_buffer) - { - if (!(m_ordered_rec_buffer= (uchar*)my_malloc(alloc_len, MYF(MY_WME)))) - { - DBUG_RETURN(error); - } - { - /* - We set-up one record per partition and each record has 2 bytes in - front where the partition id is written. This is used by ordered - index_read. - We also set-up a reference to the first record for temporary use in - setting up the scan. - */ - char *ptr= (char*)m_ordered_rec_buffer; - uint i= 0; - do - { - int2store(ptr, i); - ptr+= m_rec_length + PARTITION_BYTES_IN_POS; - } while (++i < m_tot_parts); - m_start_key.key= (const uchar*)ptr; - } - } if (!m_part_ids_sorted_by_num_of_records) { if (!(m_part_ids_sorted_by_num_of_records= @@ -2711,7 +2684,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) if (m_is_clone_of) { - uint i; + uint i, alloc_len; DBUG_ASSERT(m_clone_mem_root); /* Allocate an array of handler pointers for the partitions handlers. */ alloc_len= (m_tot_parts + 1) * sizeof(handler*); @@ -2787,12 +2760,6 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) being opened once. */ clear_handler_file(); - /* - Initialize priority queue, initialized to reading forward. - */ - if ((error= init_queue(&m_queue, m_tot_parts, (uint) PARTITION_BYTES_IN_POS, - 0, key_rec_cmp, (void*)this))) - goto err_handler; /* Use table_share->ha_part_data to share auto_increment_value among @@ -2917,7 +2884,7 @@ int ha_partition::close(void) DBUG_ENTER("ha_partition::close"); DBUG_ASSERT(table->s == table_share); - delete_queue(&m_queue); + destroy_record_priority_queue(); bitmap_free(&m_bulk_insert_started); if (!m_is_clone_of) bitmap_free(&(m_part_info->used_partitions)); @@ -4213,6 +4180,87 @@ int ha_partition::rnd_pos_by_record(uchar *record) subset of the partitions are used, then only use those partitions. */ + +/** + Setup the ordered record buffer and the priority queue. +*/ + +bool ha_partition::init_record_priority_queue() +{ + DBUG_ENTER("ha_partition::init_record_priority_queue"); + DBUG_ASSERT(!m_ordered_rec_buffer); + /* + Initialize the ordered record buffer. + */ + if (!m_ordered_rec_buffer) + { + uint map_len, alloc_len; + uint used_parts= 0; + /* Allocate an array for mapping used partitions to their record buffer. */ + map_len= m_tot_parts * PARTITION_BYTES_IN_POS; + alloc_len= map_len; + /* Allocate record buffer for each used partition. */ + alloc_len+= bitmap_bits_set(&m_part_info->used_partitions) * + (m_rec_length + PARTITION_BYTES_IN_POS); + /* Allocate a key for temporary use when setting up the scan. */ + alloc_len+= table_share->max_key_length; + + if (!(m_ordered_rec_buffer= (uchar*)my_malloc(alloc_len, MYF(MY_WME)))) + DBUG_RETURN(true); + + /* + We set-up one record per partition and each record has 2 bytes in + front where the partition id is written. This is used by ordered + index_read. + We also set-up a reference to the first record for temporary use in + setting up the scan. + No need to initialize the full map, it should only be used partitions + that will be read, so it is better to not set them to find possible + bugs through valgrind. + */ + uint16 *map= (uint16*) m_ordered_rec_buffer; + char *ptr= (char*) m_ordered_rec_buffer + map_len; + uint16 i= 0; + do + { + if (bitmap_is_set(&m_part_info->used_partitions, i)) + { + map[i]= used_parts++; + int2store(ptr, i); + ptr+= m_rec_length + PARTITION_BYTES_IN_POS; + } + } while (++i < m_tot_parts); + m_start_key.key= (const uchar*)ptr; + /* Initialize priority queue, initialized to reading forward. */ + if (init_queue(&m_queue, used_parts, (uint) PARTITION_BYTES_IN_POS, + 0, key_rec_cmp, (void*)m_curr_key_info)) + { + my_free(m_ordered_rec_buffer); + m_ordered_rec_buffer= NULL; + DBUG_RETURN(true); + } + } + DBUG_RETURN(false); +} + + +/** + Destroy the ordered record buffer and the priority queue. +*/ + +void ha_partition::destroy_record_priority_queue() +{ + DBUG_ENTER("ha_partition::destroy_record_priority_queue"); + if (m_ordered_rec_buffer) + { + delete_queue(&m_queue); + my_free(m_ordered_rec_buffer); + m_ordered_rec_buffer= NULL; + } + DBUG_VOID_RETURN; +} + + /* Initialize handler before start of index scan @@ -4254,6 +4302,10 @@ int ha_partition::index_init(uint inx, bool sorted) } else m_curr_key_info[1]= NULL; + + if (init_record_priority_queue()) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + /* Some handlers only read fields as specified by the bitmap for the read set. For partitioned handlers we always require that the @@ -4328,11 +4380,11 @@ int ha_partition::index_end() do { int tmp; - /* TODO RONM: Change to index_end() when code is stable */ if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file))) if ((tmp= (*file)->ha_index_end())) error= tmp; } while (*(++file)); + destroy_record_priority_queue(); DBUG_RETURN(error); } diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 220af4d4e89..2142fd27a7f 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -511,6 +511,8 @@ public: virtual int read_range_next(); private: + bool init_record_priority_queue(); + void destroy_record_priority_queue(); int common_index_read(uchar * buf, bool have_start_key); int common_first_last(uchar * buf); int partition_scan_set_up(uchar * buf, bool idx_read_flag); @@ -518,8 +520,15 @@ private: int handle_unordered_scan_next_partition(uchar * buf); uchar *queue_buf(uint part_id) { - return (m_ordered_rec_buffer + - (part_id * (m_rec_length + PARTITION_BYTES_IN_POS))); + uint16 *part_id_map= (uint16*) m_ordered_rec_buffer; + /* Offset to the partition's record buffer in number of partitions. */ + uint offset= part_id_map[part_id]; + /* + Return the pointer to the partition's record buffer. + First skip the partition id map, and then add the offset. + */ + return (m_ordered_rec_buffer + m_tot_parts * PARTITION_BYTES_IN_POS + + (offset * (m_rec_length + PARTITION_BYTES_IN_POS))); } uchar *rec_buf(uint part_id) { |