mirror of
https://github.com/MariaDB/server.git
synced 2025-12-28 00:01:00 +00:00
Added bitmap_get_last_set functions.
This can be used by replication to optimize unpack_row and other things
This commit is contained in:
parent
04aaff9c0c
commit
a32d5c340f
@ -61,6 +61,7 @@ extern my_bool bitmap_exists_intersection(MY_BITMAP **bitmap_array,
|
||||
extern uint bitmap_set_next(MY_BITMAP *map);
|
||||
extern uint bitmap_get_first_clear(const MY_BITMAP *map);
|
||||
extern uint bitmap_get_first_set(const MY_BITMAP *map);
|
||||
extern uint bitmap_get_last_set(const MY_BITMAP *map);
|
||||
extern uint bitmap_bits_set(const MY_BITMAP *map);
|
||||
extern uint bitmap_get_next_set(const MY_BITMAP *map, uint bitmap_bit);
|
||||
extern void my_bitmap_free(MY_BITMAP *map);
|
||||
|
||||
@ -579,13 +579,44 @@ uint bitmap_get_first_set(const MY_BITMAP *map)
|
||||
my_bitmap_map *data_ptr= map->bitmap, *end= map->last_word_ptr;
|
||||
DBUG_ASSERT_BITMAP(map);
|
||||
|
||||
for (uint i=0; data_ptr <= end; data_ptr++, i++)
|
||||
for (uint i= 0; data_ptr <= end; data_ptr++, i++)
|
||||
if (*data_ptr)
|
||||
return my_find_first_bit(*data_ptr) + i * sizeof(my_bitmap_map)*8;
|
||||
return MY_BIT_NONE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Find last set bit in a bitmap (0 - (bit_map_size -1))
|
||||
Returns MY_BIT_NONE if no bits.
|
||||
*/
|
||||
|
||||
#define step(x) if (n >= (1ULL) << x) { bit+= x; n >>= x; }
|
||||
|
||||
uint get_last_bit(ulonglong n)
|
||||
{
|
||||
int bit= 0;
|
||||
DBUG_ASSERT(n > 0);
|
||||
|
||||
step(32) ; step(16); step(8); step(4); step(2); step(1);
|
||||
return bit;
|
||||
}
|
||||
#undef step
|
||||
|
||||
uint bitmap_get_last_set(const MY_BITMAP *map)
|
||||
{
|
||||
my_bitmap_map *data_ptr= map->bitmap, *end= map->last_word_ptr;
|
||||
DBUG_ASSERT_BITMAP(map);
|
||||
|
||||
do
|
||||
{
|
||||
if (*end)
|
||||
return (uint) ((end-data_ptr)*sizeof(my_bitmap_map))*8 + get_last_bit(*end);
|
||||
} while (end-- > data_ptr);
|
||||
return MY_BIT_NONE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Get the next set bit.
|
||||
|
||||
|
||||
@ -297,6 +297,44 @@ error2:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
my_bool test_get_last_bit(MY_BITMAP *map, uint bitsize)
|
||||
{
|
||||
uint i, test_bit= 0;
|
||||
uint no_loops= bitsize > 128 ? 128 : bitsize;
|
||||
|
||||
bitmap_set_all(map);
|
||||
test_bit= bitsize;
|
||||
if (bitmap_get_last_set(map) != bitsize-1)
|
||||
goto error1;
|
||||
|
||||
bitmap_clear_all(map);
|
||||
test_bit= 0;
|
||||
if (bitmap_get_last_set(map) != MY_BIT_NONE)
|
||||
goto error1;
|
||||
|
||||
for (i=0; i < no_loops; i++)
|
||||
{
|
||||
uint test_bit1, test_bit2;
|
||||
bitmap_clear_all(map);
|
||||
test_bit1= get_rand_bit(bitsize);
|
||||
bitmap_set_bit(map, test_bit1);
|
||||
|
||||
test_bit2= get_rand_bit(bitsize);
|
||||
bitmap_set_bit(map, test_bit2);
|
||||
|
||||
test_bit= MY_MAX(test_bit1, test_bit2);
|
||||
if (bitmap_get_last_set(map) != test_bit)
|
||||
goto error1;
|
||||
}
|
||||
return FALSE;
|
||||
error1:
|
||||
diag("get_last_set error bitsize=%u, test_bit=%u, res: %u",
|
||||
bitsize, test_bit, bitmap_get_last_set(map));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
my_bool test_get_next_bit(MY_BITMAP *map, uint bitsize)
|
||||
{
|
||||
uint i, j, test_bit;
|
||||
@ -641,6 +679,8 @@ my_bool do_test(uint bitsize)
|
||||
bitmap_clear_all(&map);
|
||||
if (test_get_first_bit(&map,bitsize))
|
||||
goto error;
|
||||
if (test_get_last_bit(&map,bitsize))
|
||||
goto error;
|
||||
bitmap_clear_all(&map);
|
||||
if (test_get_next_bit(&map,bitsize))
|
||||
goto error;
|
||||
@ -674,7 +714,7 @@ int main(int argc __attribute__((unused)),char *argv[])
|
||||
plan((max_size - min_size)/7+1);
|
||||
|
||||
/*
|
||||
It's ok to do steps in 7, as i module 64 will go trough all values 1..63.
|
||||
It's ok to do steps in 7, as i module 64 will go through all values 1..63.
|
||||
Any errors in the code should manifest as we are working with integers
|
||||
of size 16, 32, or 64 bits...
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user