diff options
Diffstat (limited to 'include/my_bitmap.h')
-rw-r--r-- | include/my_bitmap.h | 67 |
1 files changed, 42 insertions, 25 deletions
diff --git a/include/my_bitmap.h b/include/my_bitmap.h index f88a6fe8..d5467065 100644 --- a/include/my_bitmap.h +++ b/include/my_bitmap.h @@ -22,14 +22,15 @@ #include <m_string.h> #include <my_pthread.h> -typedef uint32 my_bitmap_map; +typedef ulonglong my_bitmap_map; typedef struct st_bitmap { my_bitmap_map *bitmap; my_bitmap_map *last_word_ptr; - my_bitmap_map last_word_mask; + my_bitmap_map last_bit_mask; uint32 n_bits; /* number of bits occupied by the above */ + my_bool bitmap_allocated; } MY_BITMAP; #ifdef __cplusplus @@ -39,7 +40,7 @@ extern "C" { /* Reset memory. Faster then doing a full bzero */ #define my_bitmap_clear(A) ((A)->bitmap= 0) -extern void create_last_word_mask(MY_BITMAP *map); +extern void create_last_bit_mask(MY_BITMAP *map); extern my_bool my_bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits); extern my_bool bitmap_is_clear_all(const MY_BITMAP *map); extern my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size); @@ -53,12 +54,12 @@ extern my_bool bitmap_fast_test_and_set(MY_BITMAP *map, uint bitmap_bit); extern my_bool bitmap_fast_test_and_clear(MY_BITMAP *map, uint bitmap_bit); extern my_bool bitmap_union_is_set_all(const MY_BITMAP *map1, const MY_BITMAP *map2); -extern my_bool bitmap_exists_intersection(const MY_BITMAP **bitmap_array, +extern my_bool bitmap_exists_intersection(MY_BITMAP **bitmap_array, uint bitmap_count, uint start_bit, uint end_bit); extern uint bitmap_set_next(MY_BITMAP *map); -extern uint bitmap_get_first(const 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_bits_set(const MY_BITMAP *map); extern uint bitmap_get_next_set(const MY_BITMAP *map, uint bitmap_bit); @@ -71,54 +72,70 @@ extern void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2); extern void bitmap_xor(MY_BITMAP *map, const MY_BITMAP *map2); extern void bitmap_invert(MY_BITMAP *map); extern void bitmap_copy(MY_BITMAP *map, const MY_BITMAP *map2); +/* Functions to export/import bitmaps to an architecture independent format */ +extern void bitmap_export(uchar *to, MY_BITMAP *map); +extern void bitmap_import(MY_BITMAP *map, uchar *from); + +#define my_bitmap_map_bytes sizeof(my_bitmap_map) +#define my_bitmap_map_bits (my_bitmap_map_bytes*8) +/* Size in bytes to store 'bits' number of bits */ +#define bitmap_buffer_size(bits) (MY_ALIGN((bits), my_bitmap_map_bits)/8) +#define my_bitmap_buffer_size(map) bitmap_buffer_size((map)->n_bits) +#define no_bytes_in_export_map(map) (((map)->n_bits + 7)/8) +#define no_words_in_map(map) (((map)->n_bits + (my_bitmap_map_bits-1))/my_bitmap_map_bits) /* Fast, not thread safe, bitmap functions */ -#define bitmap_buffer_size(bits) (((bits)+31)/32)*4 -#define no_bytes_in_map(map) (((map)->n_bits + 7)/8) -#define no_words_in_map(map) (((map)->n_bits + 31)/32) -#define bytes_word_aligned(bytes) (4*((bytes + 3)/4)) -/* The following functions must be compatible with create_last_word_mask()! */ +/* The following functions must be compatible with create_last_bit_mask()! */ static inline void bitmap_set_bit(MY_BITMAP *map,uint bit) { - uchar *b= (uchar*) map->bitmap + bit / 8; DBUG_ASSERT(bit < map->n_bits); - *b= (uchar) (*b | 1U << (bit & 7)); + map->bitmap[bit/my_bitmap_map_bits]|= + (1ULL << (bit & (my_bitmap_map_bits-1))); } static inline void bitmap_flip_bit(MY_BITMAP *map,uint bit) { - uchar *b= (uchar*) map->bitmap + bit / 8; DBUG_ASSERT(bit < map->n_bits); - *b= (uchar) (*b ^ 1U << (bit & 7)); + map->bitmap[bit/my_bitmap_map_bits]^= + (1ULL << (bit & (my_bitmap_map_bits-1))); } static inline void bitmap_clear_bit(MY_BITMAP *map,uint bit) { - uchar *b= (uchar*) map->bitmap + bit / 8; DBUG_ASSERT(bit < map->n_bits); - *b= (uchar) (*b & ~(1U << (bit & 7))); + map->bitmap[bit/my_bitmap_map_bits]&= + ~(1ULL << (bit & (my_bitmap_map_bits-1))); } static inline uint bitmap_is_set(const MY_BITMAP *map,uint bit) { - const uchar *b= (const uchar*) map->bitmap + bit / 8; DBUG_ASSERT(bit < map->n_bits); - return !!(*b & (1U << (bit & 7))); + return (!!(map->bitmap[bit/my_bitmap_map_bits] & + (1ULL << (bit & (my_bitmap_map_bits-1))))); } +/* Return true if bitmaps are equal */ static inline my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2) { - if (memcmp(map1->bitmap, map2->bitmap, 4*(no_words_in_map(map1)-1)) != 0) - return FALSE; - return ((*map1->last_word_ptr | map1->last_word_mask) == - (*map2->last_word_ptr | map2->last_word_mask)); + DBUG_ASSERT(map1->n_bits == map2->n_bits); + return (memcmp(map1->bitmap, map2->bitmap, + my_bitmap_buffer_size(map1)) == 0); } #define bitmap_clear_all(MAP) \ - { memset((MAP)->bitmap, 0, 4*no_words_in_map((MAP))); } -#define bitmap_set_all(MAP) \ - (memset((MAP)->bitmap, 0xFF, 4*no_words_in_map((MAP)))) + { memset((MAP)->bitmap, 0, my_bitmap_buffer_size(MAP)); } + +static inline void +bitmap_set_all(const MY_BITMAP *map) +{ + if (map->n_bits) + { + memset(map->bitmap, 0xFF, my_bitmap_map_bytes * (no_words_in_map(map)-1)); + DBUG_ASSERT(map->bitmap + no_words_in_map(map)-1 == map->last_word_ptr); + *map->last_word_ptr= ~map->last_bit_mask; + } +} #ifdef __cplusplus } |