summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMattias Jonsson <mattias.jonsson@oracle.com>2012-08-15 14:56:55 +0200
committerMattias Jonsson <mattias.jonsson@oracle.com>2012-08-15 14:56:55 +0200
commit404cce0ff82402c24c869a75606f329bfe9da9e9 (patch)
tree260d78771471eaa7564ad7b038429d2ab252b628 /sql
parent94bd7bd6b7687cf654df90b22a85425cf72af55c (diff)
parentbcee9f1896ab6015e77ea88fde5317f50edaead7 (diff)
downloadmariadb-git-404cce0ff82402c24c869a75606f329bfe9da9e9.tar.gz
manual merge 5.1->5.5
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_partition.cc126
-rw-r--r--sql/ha_partition.h13
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)
{