From: Mattias Jonsson Date: August 20 2012 10:59am Subject: bzr push into mysql-trunk branch (mattias.jonsson:4251 to 4252) List-Archive: http://lists.mysql.com/commits/144571 Message-Id: <20120820105902.4952.80998.4252@MJONSSON-LAP.se.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 4252 Mattias Jonsson 2012-08-20 [merge] merge modified: sql/ha_partition.cc sql/ha_partition.h 4251 Marc Alff 2012-08-20 [merge] Merge mysql-5.6 --> mysql-trunk modified: storage/perfschema/pfs.cc === modified file 'sql/ha_partition.cc' --- a/sql/ha_partition.cc revid:marc.alff@stripped +++ b/sql/ha_partition.cc revid:mattias.jonsson@stripped @@ -391,7 +391,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(); @@ -3143,7 +3143,6 @@ int ha_partition::open(const char *name, { char *name_buffer_ptr; int error= HA_ERR_INITIALIZATION; - uint alloc_len; handler **file; char name_buff[FN_REFLEN]; ulonglong check_table_flags; @@ -3164,32 +3163,6 @@ int ha_partition::open(const char *name, 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= @@ -3208,7 +3181,7 @@ int ha_partition::open(const char *name, 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*); @@ -3291,12 +3264,6 @@ int ha_partition::open(const char *name, 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; /* Some handlers update statistics as part of the open call. This will in @@ -3441,7 +3408,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(); free_partition_bitmaps(); DBUG_ASSERT(m_part_info); file= m_file; @@ -4776,6 +4743,77 @@ int ha_partition::rnd_pos_by_record(ucha 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 alloc_len; + uint used_parts= bitmap_bits_set(&m_part_info->read_partitions); + /* Allocate record buffer for each used partition. */ + alloc_len= used_parts * (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. + */ + char *ptr= (char*) m_ordered_rec_buffer; + uint i; + for (i= bitmap_get_first_set(&m_part_info->read_partitions); + i < m_tot_parts; + i= bitmap_get_next_set(&m_part_info->read_partitions, i)) + { + int2store(ptr, i); + ptr+= m_rec_length + PARTITION_BYTES_IN_POS; + } + 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 @@ -4817,6 +4855,10 @@ int ha_partition::index_init(uint inx, b } 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 @@ -4908,6 +4950,7 @@ int ha_partition::index_end() if ((tmp= m_file[i]->ha_index_end())) error= tmp; } + destroy_record_priority_queue(); DBUG_RETURN(error); } @@ -5652,6 +5695,7 @@ int ha_partition::handle_ordered_index_s uint i; uint j= 0; bool found= FALSE; + uchar *part_rec_buf_ptr= m_ordered_rec_buffer; DBUG_ENTER("ha_partition::handle_ordered_index_scan"); m_top_entry= NO_CURRENT_PART_ID; @@ -5664,7 +5708,7 @@ int ha_partition::handle_ordered_index_s i <= m_part_spec.end_part; i= bitmap_get_next_set(&m_part_info->read_partitions, i)) { - uchar *rec_buf_ptr= rec_buf(i); + uchar *rec_buf_ptr= part_rec_buf_ptr + PARTITION_BYTES_IN_POS; int error; handler *file= m_file[i]; @@ -5711,12 +5755,13 @@ int ha_partition::handle_ordered_index_s /* Initialize queue without order first, simply insert */ - queue_element(&m_queue, j++)= (uchar*)queue_buf(i); + queue_element(&m_queue, j++)= part_rec_buf_ptr; } else if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) { DBUG_RETURN(error); } + part_rec_buf_ptr+= m_rec_length + PARTITION_BYTES_IN_POS; } if (found) { @@ -5779,18 +5824,19 @@ int ha_partition::handle_ordered_next(uc { int error; uint part_id= m_top_entry; + uchar *rec_buf= queue_top(&m_queue) + PARTITION_BYTES_IN_POS; handler *file= m_file[part_id]; DBUG_ENTER("ha_partition::handle_ordered_next"); if (m_index_scan_type == partition_read_range) { error= file->read_range_next(); - memcpy(rec_buf(part_id), table->record[0], m_rec_length); + memcpy(rec_buf, table->record[0], m_rec_length); } else if (!is_next_same) - error= file->ha_index_next(rec_buf(part_id)); + error= file->ha_index_next(rec_buf); else - error= file->ha_index_next_same(rec_buf(part_id), m_start_key.key, + error= file->ha_index_next_same(rec_buf, m_start_key.key, m_start_key.length); if (error) { @@ -5833,10 +5879,11 @@ int ha_partition::handle_ordered_prev(uc { int error; uint part_id= m_top_entry; + uchar *rec_buf= queue_top(&m_queue) + PARTITION_BYTES_IN_POS; handler *file= m_file[part_id]; DBUG_ENTER("ha_partition::handle_ordered_prev"); - if ((error= file->ha_index_prev(rec_buf(part_id)))) + if ((error= file->ha_index_prev(rec_buf))) { if (error == HA_ERR_END_OF_FILE) { === modified file 'sql/ha_partition.h' --- a/sql/ha_partition.h revid:marc.alff@stripped +++ b/sql/ha_partition.h revid:mattias.jonsson@stripped @@ -606,21 +606,13 @@ 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); int handle_unordered_next(uchar * buf, bool next_same); 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))); - } - uchar *rec_buf(uint part_id) - { - return (queue_buf(part_id) + - PARTITION_BYTES_IN_POS); - } int handle_ordered_index_scan(uchar * buf, bool reverse_order); int handle_ordered_next(uchar * buf, bool next_same); int handle_ordered_prev(uchar * buf); No bundle (reason: useless for push emails).