diff options
Diffstat (limited to 'mysys/my_bitmap.c')
-rw-r--r-- | mysys/my_bitmap.c | 279 |
1 files changed, 31 insertions, 248 deletions
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c index fe5faff47bc..83d03177eba 100644 --- a/mysys/my_bitmap.c +++ b/mysys/my_bitmap.c @@ -13,8 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Handling of uchar arrays as large bitmaps. @@ -24,17 +23,13 @@ * the internal size is a set of 32 bit words * the number of bits specified in creation can be any number > 0 - * there are THREAD safe versions of most calls called bitmap_lock_* - many of those are not used and not compiled normally but the code - already exist for them in an #ifdef:ed part. These can only be used - if THREAD was specified in bitmap_init TODO: - Make assembler THREAD safe versions of these using test-and-set instructions + Make assembler thread safe versions of these using test-and-set instructions Original version created by Sergei Golubchik 2001 - 2004. New version written and test program added and some changes to the interface - was made by Mikael Ronström 2005, with assistance of Tomas Ulin and Mats + was made by Mikael Ronstrom 2005, with assistance of Tomas Ulin and Mats Kindahl. */ @@ -141,19 +136,14 @@ static inline my_bitmap_map last_word_mask(uint bit) static inline void bitmap_lock(MY_BITMAP *map __attribute__((unused))) { -#ifdef THREAD if (map->mutex) - pthread_mutex_lock(map->mutex); -#endif + mysql_mutex_lock(map->mutex); } - static inline void bitmap_unlock(MY_BITMAP *map __attribute__((unused))) { -#ifdef THREAD if (map->mutex) - pthread_mutex_unlock(map->mutex); -#endif + mysql_mutex_unlock(map->mutex); } @@ -165,30 +155,24 @@ my_bool bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits, { uint size_in_bytes= bitmap_buffer_size(n_bits); uint extra= 0; -#ifdef THREAD if (thread_safe) { size_in_bytes= ALIGN_SIZE(size_in_bytes); - extra= sizeof(pthread_mutex_t); + extra= sizeof(mysql_mutex_t); } map->mutex= 0; -#endif if (!(buf= (my_bitmap_map*) my_malloc(size_in_bytes+extra, MYF(MY_WME)))) DBUG_RETURN(1); -#ifdef THREAD if (thread_safe) { - map->mutex= (pthread_mutex_t *) ((char*) buf + size_in_bytes); - pthread_mutex_init(map->mutex, MY_MUTEX_INIT_FAST); + map->mutex= (mysql_mutex_t *) ((char*) buf + size_in_bytes); + mysql_mutex_init(key_BITMAP_mutex, map->mutex, MY_MUTEX_INIT_FAST); } -#endif } -#ifdef THREAD else { DBUG_ASSERT(thread_safe == 0); } -#endif map->bitmap= buf; map->n_bits= n_bits; @@ -203,11 +187,9 @@ void bitmap_free(MY_BITMAP *map) DBUG_ENTER("bitmap_free"); if (map->bitmap) { -#ifdef THREAD if (map->mutex) - pthread_mutex_destroy(map->mutex); -#endif - my_free((char*) map->bitmap, MYF(0)); + mysql_mutex_destroy(map->mutex); + my_free(map->bitmap); map->bitmap=0; } DBUG_VOID_RETURN; @@ -327,43 +309,31 @@ void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size) my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size) { - uint prefix_bits= prefix_size % 32; - my_bitmap_map *word_ptr= map->bitmap, last_word; - my_bitmap_map *end_prefix= word_ptr + prefix_size / 32; - DBUG_ASSERT(word_ptr && prefix_size <= map->n_bits); + uint prefix_mask= last_byte_mask(prefix_size); + uchar *m= (uchar*) map->bitmap; + uchar *end_prefix= m+(prefix_size-1)/8; + uchar *end; + DBUG_ASSERT(m && prefix_size <= map->n_bits); - /* 1: Words that should be filled with 1 */ - for (; word_ptr < end_prefix; word_ptr++) - if (*word_ptr != 0xFFFFFFFF) - return FALSE; + /* Empty prefix is always true */ + if (!prefix_size) + return 1; - last_word= *map->last_word_ptr & ~map->last_word_mask; + while (m < end_prefix) + if (*m++ != 0xff) + return 0; - /* 2: Word which contains the end of the prefix (if any) */ - if (prefix_bits) - { - if (word_ptr == map->last_word_ptr) - return uint4korr((uchar*)&last_word) == (uint32)((1 << prefix_bits) - 1); - if (uint4korr((uchar*)word_ptr) != (uint32)((1 << prefix_bits) - 1)) - return FALSE; - word_ptr++; - } + end= ((uchar*) map->bitmap) + no_bytes_in_map(map) - 1; + if (m == end) + return ((*m & last_byte_mask(map->n_bits)) == prefix_mask); - /* 3: Words that should be filled with 0 */ - for (; word_ptr < map->last_word_ptr; word_ptr++) - if (*word_ptr != 0) - return FALSE; + if (*m != prefix_mask) + return 0; - /* - We can end up here in two situations: - 1) We went through the whole bitmap in step 1. This will happen if the - whole bitmap is filled with 1 and prefix_size is a multiple of 32 - (i.e. the prefix does not end in the middle of a word). - In this case word_ptr will be larger than map->last_word_ptr. - 2) We have gone through steps 1-3 and just need to check that also - the last word is 0. - */ - return word_ptr > map->last_word_ptr || last_word == 0; + while (++m < end) + if (*m != 0) + return 0; + return ((*m & last_byte_mask(map->n_bits)) == 0); } @@ -371,7 +341,6 @@ my_bool bitmap_is_set_all(const MY_BITMAP *map) { my_bitmap_map *data_ptr= map->bitmap; my_bitmap_map *end= map->last_word_ptr; - for (; data_ptr < end; data_ptr++) if (*data_ptr != 0xFFFFFFFF) return FALSE; @@ -613,10 +582,10 @@ uint bitmap_bits_set(const MY_BITMAP *map) return res; } - void bitmap_copy(MY_BITMAP *map, const MY_BITMAP *map2) { my_bitmap_map *to= map->bitmap, *from= map2->bitmap, *end; + DBUG_ASSERT(map->bitmap && map2->bitmap && map->n_bits==map2->n_bits); end= map->last_word_ptr; @@ -715,189 +684,3 @@ void bitmap_lock_clear_bit(MY_BITMAP *map, uint bitmap_bit) bitmap_unlock(map); } - -#ifdef NOT_USED -my_bool bitmap_lock_is_prefix(const MY_BITMAP *map, uint prefix_size) -{ - my_bool res; - bitmap_lock((MY_BITMAP *)map); - res= bitmap_is_prefix(map, prefix_size); - bitmap_unlock((MY_BITMAP *)map); - return res; -} - - -void bitmap_lock_set_all(MY_BITMAP *map) -{ - bitmap_lock(map); - bitmap_set_all(map); - bitmap_unlock(map); -} - - -void bitmap_lock_clear_all(MY_BITMAP *map) -{ - bitmap_lock(map); - bitmap_clear_all(map); - bitmap_unlock(map); -} - - -void bitmap_lock_set_prefix(MY_BITMAP *map, uint prefix_size) -{ - bitmap_lock(map); - bitmap_set_prefix(map, prefix_size); - bitmap_unlock(map); -} - - -my_bool bitmap_lock_is_clear_all(const MY_BITMAP *map) -{ - uint res; - bitmap_lock((MY_BITMAP *)map); - res= bitmap_is_clear_all(map); - bitmap_unlock((MY_BITMAP *)map); - return res; -} - - -my_bool bitmap_lock_is_set_all(const MY_BITMAP *map) -{ - uint res; - bitmap_lock((MY_BITMAP *)map); - res= bitmap_is_set_all(map); - bitmap_unlock((MY_BITMAP *)map); - return res; -} - - -my_bool bitmap_lock_is_set(const MY_BITMAP *map, uint bitmap_bit) -{ - my_bool res; - DBUG_ASSERT(map->bitmap && bitmap_bit < map->n_bits); - bitmap_lock((MY_BITMAP *)map); - res= bitmap_is_set(map, bitmap_bit); - bitmap_unlock((MY_BITMAP *)map); - return res; -} - - -my_bool bitmap_lock_is_subset(const MY_BITMAP *map1, const MY_BITMAP *map2) -{ - uint res; - bitmap_lock((MY_BITMAP *)map1); - bitmap_lock((MY_BITMAP *)map2); - res= bitmap_is_subset(map1, map2); - bitmap_unlock((MY_BITMAP *)map2); - bitmap_unlock((MY_BITMAP *)map1); - return res; -} - - -my_bool bitmap_lock_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2) -{ - uint res; - - DBUG_ASSERT(map1->bitmap && map2->bitmap && - map1->n_bits==map2->n_bits); - bitmap_lock((MY_BITMAP *)map1); - bitmap_lock((MY_BITMAP *)map2); - res= bitmap_cmp(map1, map2); - bitmap_unlock((MY_BITMAP *)map2); - bitmap_unlock((MY_BITMAP *)map1); - return res; -} - - -void bitmap_lock_intersect(MY_BITMAP *map, const MY_BITMAP *map2) -{ - bitmap_lock(map); - bitmap_lock((MY_BITMAP *)map2); - bitmap_intersect(map, map2); - bitmap_unlock((MY_BITMAP *)map2); - bitmap_unlock(map); -} - - -void bitmap_lock_subtract(MY_BITMAP *map, const MY_BITMAP *map2) -{ - bitmap_lock(map); - bitmap_lock((MY_BITMAP *)map2); - bitmap_subtract(map, map2); - bitmap_unlock((MY_BITMAP *)map2); - bitmap_unlock(map); -} - - -void bitmap_lock_union(MY_BITMAP *map, const MY_BITMAP *map2) -{ - bitmap_lock(map); - bitmap_lock((MY_BITMAP *)map2); - bitmap_union(map, map2); - bitmap_unlock((MY_BITMAP *)map2); - bitmap_unlock(map); -} - - -/* - SYNOPSIS - bitmap_bits_set() - map - RETURN - Number of set bits in the bitmap. -*/ -uint bitmap_lock_bits_set(const MY_BITMAP *map) -{ - uint res; - bitmap_lock((MY_BITMAP *)map); - DBUG_ASSERT(map->bitmap); - res= bitmap_bits_set(map); - bitmap_unlock((MY_BITMAP *)map); - return res; -} - - -/* - SYNOPSIS - bitmap_get_first() - map - RETURN - Number of first unset bit in the bitmap or MY_BIT_NONE if all bits are set. -*/ -uint bitmap_lock_get_first(const MY_BITMAP *map) -{ - uint res; - bitmap_lock((MY_BITMAP*)map); - res= bitmap_get_first(map); - bitmap_unlock((MY_BITMAP*)map); - return res; -} - - -uint bitmap_lock_get_first_set(const MY_BITMAP *map) -{ - uint res; - bitmap_lock((MY_BITMAP*)map); - res= bitmap_get_first_set(map); - bitmap_unlock((MY_BITMAP*)map); - return res; -} - - -void bitmap_lock_set_bit(MY_BITMAP *map, uint bitmap_bit) -{ - DBUG_ASSERT(map->bitmap && bitmap_bit < map->n_bits); - bitmap_lock(map); - bitmap_set_bit(map, bitmap_bit); - bitmap_unlock(map); -} - - -void bitmap_lock_flip_bit(MY_BITMAP *map, uint bitmap_bit) -{ - DBUG_ASSERT(map->bitmap && bitmap_bit < map->n_bits); - bitmap_lock(map); - bitmap_flip_bit(map, bitmap_bit); - bitmap_unlock(map); -} -#endif /* NOT_USED */ |