summaryrefslogtreecommitdiff
path: root/mysys/my_bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mysys/my_bitmap.c')
-rw-r--r--mysys/my_bitmap.c279
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 */