mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
MDEV-17613 Refactor prune_partitions() to build into a dedicated bitmap
prune_partitions() built the used-partition set directly in read_partitions: it cleared it, let find_used_partitions*() fill it, and in the index-merge case used it as scratch too - both buffer and result. The patch adds PART_PRUNE_PARAM::parts_bitmap and builds the return into it instead. read_partitions is produced from it only at the end: copied when the condition was analyzed (IMPOSSIBLE included, parts_bitmap left empty), or set to all locked partitions via mark_all_partitions_as_used() when nothing could be pruned. Pure refactoring: read_partitions ends up identical on every path. It decouples the pruning scratch from read_partitions, so a later commit can switch the final bitmap_copy() to bitmap_intersect() - letting pruning narrow a pre-set read_partitions (e.g. a versioned table selecting only its current partition) instead of overwriting it.
This commit is contained in:
@@ -4019,7 +4019,7 @@ void store_key_image_to_rec(Field *field, uchar *ptr, uint len)
|
||||
struct st_part_prune_param;
|
||||
struct st_part_opt_info;
|
||||
|
||||
typedef void (*mark_full_part_func)(partition_info*, uint32);
|
||||
typedef void (*mark_full_part_func)(struct st_part_prune_param*, uint32);
|
||||
|
||||
/*
|
||||
Partition pruning operation context
|
||||
@@ -4080,6 +4080,12 @@ typedef struct st_part_prune_param
|
||||
/* Iterator to be used to obtain the "current" set of used partitions */
|
||||
PARTITION_ITERATOR part_iter;
|
||||
|
||||
/*
|
||||
Initialized bitmap of read_partitions size.
|
||||
find_used_partitions() will save the set of used partitions here.
|
||||
*/
|
||||
MY_BITMAP parts_bitmap;
|
||||
|
||||
/* Initialized bitmap of num_subparts size */
|
||||
MY_BITMAP subparts_bitmap;
|
||||
|
||||
@@ -4181,7 +4187,7 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
|
||||
thd->no_errors=1; // Don't warn about NULL
|
||||
thd->mem_root=&alloc;
|
||||
|
||||
bitmap_clear_all(&part_info->read_partitions);
|
||||
bitmap_clear_all(&prune_param.parts_bitmap);
|
||||
|
||||
prune_param.key= prune_param.range_param.key_parts;
|
||||
SEL_TREE *tree;
|
||||
@@ -4259,7 +4265,11 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
|
||||
all_used:
|
||||
retval= FALSE; // some partitions are used
|
||||
mark_all_partitions_as_used(prune_param.part_info);
|
||||
goto all_used_end;
|
||||
end:
|
||||
bitmap_copy(&prune_param.part_info->read_partitions,
|
||||
&prune_param.parts_bitmap);
|
||||
all_used_end:
|
||||
dbug_tmp_restore_column_maps(&table->read_set, &table->write_set, old_sets);
|
||||
thd->no_errors=0;
|
||||
thd->mem_root= range_par->old_root;
|
||||
@@ -4337,20 +4347,21 @@ static void store_selargs_to_rec(PART_PRUNE_PARAM *ppar, SEL_ARG **start,
|
||||
|
||||
|
||||
/* Mark a partition as used in the case when there are no subpartitions */
|
||||
static void mark_full_partition_used_no_parts(partition_info* part_info,
|
||||
static void mark_full_partition_used_no_parts(PART_PRUNE_PARAM *ppar,
|
||||
uint32 part_id)
|
||||
{
|
||||
DBUG_ENTER("mark_full_partition_used_no_parts");
|
||||
DBUG_PRINT("enter", ("Mark partition %u as used", part_id));
|
||||
bitmap_set_bit(&part_info->read_partitions, part_id);
|
||||
bitmap_set_bit(&ppar->parts_bitmap, part_id);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/* Mark a partition as used in the case when there are subpartitions */
|
||||
static void mark_full_partition_used_with_parts(partition_info *part_info,
|
||||
static void mark_full_partition_used_with_parts(PART_PRUNE_PARAM *ppar,
|
||||
uint32 part_id)
|
||||
{
|
||||
partition_info *part_info= ppar->part_info;
|
||||
uint32 start= part_id * part_info->num_subparts;
|
||||
uint32 end= start + part_info->num_subparts;
|
||||
DBUG_ENTER("mark_full_partition_used_with_parts");
|
||||
@@ -4358,7 +4369,7 @@ static void mark_full_partition_used_with_parts(partition_info *part_info,
|
||||
for (; start != end; start++)
|
||||
{
|
||||
DBUG_PRINT("info", ("1:Mark subpartition %u as used", start));
|
||||
bitmap_set_bit(&part_info->read_partitions, start);
|
||||
bitmap_set_bit(&ppar->parts_bitmap, start);
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@@ -4386,7 +4397,7 @@ static int find_used_partitions_imerge_list(PART_PRUNE_PARAM *ppar,
|
||||
MY_BITMAP all_merges;
|
||||
uint bitmap_bytes;
|
||||
my_bitmap_map *bitmap_buf;
|
||||
uint n_bits= ppar->part_info->read_partitions.n_bits;
|
||||
uint n_bits= ppar->parts_bitmap.n_bits;
|
||||
bitmap_bytes= bitmap_buffer_size(n_bits);
|
||||
if (!(bitmap_buf= (my_bitmap_map*) alloc_root(ppar->range_param.mem_root,
|
||||
bitmap_bytes)))
|
||||
@@ -4412,15 +4423,15 @@ static int find_used_partitions_imerge_list(PART_PRUNE_PARAM *ppar,
|
||||
}
|
||||
|
||||
if (res != -1)
|
||||
bitmap_intersect(&all_merges, &ppar->part_info->read_partitions);
|
||||
bitmap_intersect(&all_merges, &ppar->parts_bitmap);
|
||||
|
||||
|
||||
if (bitmap_is_clear_all(&all_merges))
|
||||
return 0;
|
||||
|
||||
bitmap_clear_all(&ppar->part_info->read_partitions);
|
||||
bitmap_clear_all(&ppar->parts_bitmap);
|
||||
}
|
||||
memcpy(ppar->part_info->read_partitions.bitmap, all_merges.bitmap,
|
||||
memcpy(ppar->parts_bitmap.bitmap, all_merges.bitmap,
|
||||
bitmap_bytes);
|
||||
return 1;
|
||||
}
|
||||
@@ -4573,6 +4584,8 @@ int find_used_partitions_imerge(PART_PRUNE_PARAM *ppar, SEL_IMERGE *imerge)
|
||||
-1 Couldn't infer any partition pruning "intervals" from the passed
|
||||
SEL_ARG* tree (which means that all partitions should be marked as
|
||||
used) Marking partitions as used is the responsibility of the caller.
|
||||
|
||||
The set of used partitions is saved in PART_PRUNE_PARAM::parts_bitmap.
|
||||
*/
|
||||
|
||||
static
|
||||
@@ -4791,7 +4804,7 @@ int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree)
|
||||
{
|
||||
for (uint i= 0; i < ppar->part_info->num_subparts; i++)
|
||||
if (bitmap_is_set(&ppar->subparts_bitmap, i))
|
||||
bitmap_set_bit(&ppar->part_info->read_partitions,
|
||||
bitmap_set_bit(&ppar->parts_bitmap,
|
||||
part_id * ppar->part_info->num_subparts + i);
|
||||
}
|
||||
goto pop_and_go_right;
|
||||
@@ -4853,7 +4866,7 @@ int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree)
|
||||
while ((part_id= ppar->part_iter.get_next(&ppar->part_iter)) !=
|
||||
NOT_A_PARTITION_ID)
|
||||
{
|
||||
bitmap_set_bit(&part_info->read_partitions,
|
||||
bitmap_set_bit(&ppar->parts_bitmap,
|
||||
part_id * part_info->num_subparts + subpart_id);
|
||||
}
|
||||
res= 1; /* Some partitions were marked as used */
|
||||
@@ -4908,7 +4921,7 @@ process_next_key_part:
|
||||
while ((part_id= ppar->part_iter.get_next(&ppar->part_iter)) !=
|
||||
NOT_A_PARTITION_ID)
|
||||
{
|
||||
ppar->mark_full_partition_used(ppar->part_info, part_id);
|
||||
ppar->mark_full_partition_used(ppar, part_id);
|
||||
found= TRUE;
|
||||
}
|
||||
res= MY_TEST(found);
|
||||
@@ -5048,6 +5061,15 @@ static bool create_partition_index_description(PART_PRUNE_PARAM *ppar)
|
||||
!(ppar->is_subpart_keypart= (my_bool*)alloc_root(alloc, sizeof(my_bool)*
|
||||
total_parts)))
|
||||
return TRUE;
|
||||
|
||||
{
|
||||
my_bitmap_map *buf;
|
||||
uint32 bufsize= bitmap_buffer_size(part_info->read_partitions.n_bits);
|
||||
if (!(buf= (my_bitmap_map*) alloc_root(alloc, bufsize)))
|
||||
return TRUE;
|
||||
my_bitmap_init(&ppar->parts_bitmap, buf,
|
||||
part_info->read_partitions.n_bits);
|
||||
}
|
||||
|
||||
if (ppar->subpart_fields)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user