summaryrefslogtreecommitdiff
path: root/mysys/my_bitmap.c
diff options
context:
space:
mode:
authorunknown <tomas@poseidon.ndb.mysql.com>2005-06-02 18:40:25 +0200
committerunknown <tomas@poseidon.ndb.mysql.com>2005-06-02 18:40:25 +0200
commit15ca553ab4574a28fd942155066d1492c87b121a (patch)
tree3380fac1e38c78273621c53282f01b7b49747471 /mysys/my_bitmap.c
parenta46f4cf4975a60ff6d8d2848a84fc25fe348aa40 (diff)
downloadmariadb-git-15ca553ab4574a28fd942155066d1492c87b121a.tar.gz
bitmap bug fixes and interface change
Diffstat (limited to 'mysys/my_bitmap.c')
-rw-r--r--mysys/my_bitmap.c135
1 files changed, 80 insertions, 55 deletions
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c
index ca8964b81e5..d7aca039426 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -50,8 +50,6 @@ void create_last_word_mask(MY_BITMAP *map)
* bits clear. The bits within each byte is stored in big-endian order.
*/
unsigned char const mask= (~((1 << used) - 1)) & 255;
- unsigned int byte_no= ((no_bytes_in_map(map)-1)) & ~3U;
- map->last_word_ptr= (uint32*)&map->bitmap[byte_no];
/*
The first bytes are to be set to zero since they represent real bits
@@ -59,14 +57,16 @@ void create_last_word_mask(MY_BITMAP *map)
bytes not used by the bitvector. Finally the last byte contains bits
as set by the mask above.
*/
-
unsigned char *ptr= (unsigned char*)&map->last_word_mask;
+
+ map->last_word_ptr= map->bitmap + no_words_in_map(map)-1;
switch (no_bytes_in_map(map)&3)
{
case 1:
map->last_word_mask= ~0U;
ptr[0]= mask;
return;
+
case 2:
map->last_word_mask= ~0U;
ptr[0]= 0;
@@ -101,28 +101,38 @@ static inline void bitmap_unlock(MY_BITMAP *map)
}
-my_bool bitmap_init(MY_BITMAP *map, uchar *buf, uint bitmap_size,
+my_bool bitmap_init(MY_BITMAP *map, uint32 *buf, uint bitmap_size,
my_bool thread_safe)
{
DBUG_ENTER("bitmap_init");
DBUG_ASSERT(bitmap_size > 0);
- if (!(map->bitmap=buf) &&
- !(map->bitmap= (uchar*) my_malloc(bitmap_size +
- (thread_safe ?
- sizeof(pthread_mutex_t) : 0),
- MYF(MY_WME))))
- return 1;
- map->bitmap_size=bitmap_size;
- create_last_word_mask(map);
+ if (!buf)
+ {
+ uint size_in_bytes= ((bitmap_size+31)/32)*4
+#ifdef THREAD
+ +(thread_safe ? sizeof(pthread_mutex_t) : 0)
+#endif
+ ;
+ if (!(buf= (uint32*) my_malloc(size_in_bytes, MYF(MY_WME))))
+ return 1;
+ }
+#ifdef THREAD
+ else
+ DBUG_ASSERT(thread_safe == 0);
+#endif
#ifdef THREAD
if (thread_safe)
{
- map->mutex=(pthread_mutex_t *)(map->bitmap+bitmap_size);
+ map->mutex=(pthread_mutex_t *)buf;
pthread_mutex_init(map->mutex, MY_MUTEX_INIT_FAST);
+ buf+= sizeof(pthread_mutex_t)/4;
}
else
map->mutex=0;
#endif
+ map->bitmap= buf;
+ map->bitmap_size=bitmap_size;
+ create_last_word_mask(map);
bitmap_clear_all(map);
DBUG_RETURN(0);
}
@@ -134,10 +144,15 @@ void bitmap_free(MY_BITMAP *map)
if (map->bitmap)
{
#ifdef THREAD
- if (map->mutex)
+ char *buf= (char *)map->mutex;
+ if (buf)
pthread_mutex_destroy(map->mutex);
-#endif
+ else
+ buf=(char*) map->bitmap;
+ my_free(buf, MYF(0));
+#else
my_free((char*) map->bitmap, MYF(0));
+#endif
map->bitmap=0;
}
DBUG_VOID_RETURN;
@@ -156,35 +171,37 @@ uint bitmap_set_next(MY_BITMAP *map)
void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size)
{
- uint prefix_bytes, prefix_bits;
+ uint prefix_bytes, prefix_bits, d;
+ uchar *m= (uchar *)map->bitmap;
DBUG_ASSERT(map->bitmap &&
(prefix_size <= map->bitmap_size || prefix_size == (uint) ~0));
set_if_smaller(prefix_size, map->bitmap_size);
if ((prefix_bytes= prefix_size / 8))
- memset(map->bitmap, 0xff, prefix_bytes);
+ memset(m, 0xff, prefix_bytes);
+ m+= prefix_bytes;
if ((prefix_bits= prefix_size & 7))
- map->bitmap[prefix_bytes++]= (1 << prefix_bits)-1;
- if (prefix_bytes < no_bytes_in_map(map))
- bzero(map->bitmap+prefix_bytes, no_bytes_in_map(map)-prefix_bytes);
- *map->last_word_ptr|= map->last_word_mask; //Set last bits
+ *m++= (1 << prefix_bits)-1;
+ if ((d= no_bytes_in_map(map)-prefix_bytes))
+ bzero(m, d);
+ *map->last_word_ptr|= map->last_word_mask; /*Set last bits*/
}
my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size)
{
uint prefix_bits= prefix_size & 0x7, res;
- uchar *m= map->bitmap;
- uchar *end_prefix= map->bitmap+prefix_size/8;
+ uchar *m= (uchar*)map->bitmap;
+ uchar *end_prefix= m+prefix_size/8;
uchar *end;
- DBUG_ASSERT(map->bitmap && prefix_size <= map->bitmap_size);
- end= map->bitmap+no_bytes_in_map(map);
+ DBUG_ASSERT(m && prefix_size <= map->bitmap_size);
+ end= m+no_bytes_in_map(map);
while (m < end_prefix)
if (*m++ != 0xff)
return 0;
- *map->last_word_ptr^= map->last_word_mask; //Clear bits
+ *map->last_word_ptr^= map->last_word_mask; /*Clear bits*/
res= 0;
if (prefix_bits && *m++ != (1 << prefix_bits)-1)
goto ret;
@@ -194,14 +211,14 @@ my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size)
goto ret;
res= 1;
ret:
- *map->last_word_ptr|= map->last_word_mask; //Set bits again
+ *map->last_word_ptr|= map->last_word_mask; /*Set bits again*/
return res;
}
my_bool bitmap_is_set_all(const MY_BITMAP *map)
{
- uint32 *data_ptr= (uint32*)map->bitmap;
+ uint32 *data_ptr= map->bitmap;
uint32 *end= map->last_word_ptr;
for (; data_ptr <= end; data_ptr++)
if (*data_ptr != 0xFFFFFFFF)
@@ -212,7 +229,7 @@ my_bool bitmap_is_set_all(const MY_BITMAP *map)
my_bool bitmap_is_clear_all(const MY_BITMAP *map)
{
- uint32 *data_ptr= (uint32*)map->bitmap;
+ uint32 *data_ptr= map->bitmap;
uint32 *end;
if (*map->last_word_ptr != map->last_word_mask)
return FALSE;
@@ -226,7 +243,7 @@ my_bool bitmap_is_clear_all(const MY_BITMAP *map)
my_bool bitmap_is_subset(const MY_BITMAP *map1, const MY_BITMAP *map2)
{
- uint32 *m1= (uint32*)map1->bitmap, *m2= (uint32*)map2->bitmap, *end;
+ uint32 *m1= map1->bitmap, *m2= map2->bitmap, *end;
DBUG_ASSERT(map1->bitmap && map2->bitmap &&
map1->bitmap_size==map2->bitmap_size);
@@ -244,13 +261,13 @@ my_bool bitmap_is_subset(const MY_BITMAP *map1, const MY_BITMAP *map2)
void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2)
{
- uint32 *to= (uint32*)map->bitmap, *from= (uint32*)map2->bitmap, *end;
+ uint32 *to= map->bitmap, *from= map2->bitmap, *end;
uint len= no_words_in_map(map), len2 = no_words_in_map(map2);
DBUG_ASSERT(map->bitmap && map2->bitmap);
end= to+min(len,len2);
- *map2->last_word_ptr^= map2->last_word_mask; //Clear last bits in map2
+ *map2->last_word_ptr^= map2->last_word_mask; /*Clear last bits in map2*/
while (to < end)
*to++ &= *from++;
@@ -260,14 +277,14 @@ void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2)
while (to < end)
*to++=0;
}
- *map2->last_word_ptr|= map2->last_word_mask; //Set last bits in map
- *map->last_word_ptr|= map->last_word_mask; //Set last bits in map2
+ *map2->last_word_ptr|= map2->last_word_mask; /*Set last bits in map*/
+ *map->last_word_ptr|= map->last_word_mask; /*Set last bits in map2*/
}
void bitmap_subtract(MY_BITMAP *map, const MY_BITMAP *map2)
{
- uint32 *to= (uint32*)map->bitmap, *from= (uint32*)map2->bitmap, *end;
+ uint32 *to= map->bitmap, *from= map2->bitmap, *end;
DBUG_ASSERT(map->bitmap && map2->bitmap &&
map->bitmap_size==map2->bitmap_size);
@@ -276,13 +293,13 @@ void bitmap_subtract(MY_BITMAP *map, const MY_BITMAP *map2)
while (to <= end)
*to++ &= ~(*from++);
- *map->last_word_ptr|= map->last_word_mask; //Set last bits again
+ *map->last_word_ptr|= map->last_word_mask; /*Set last bits again*/
}
void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2)
{
- uint32 *to= (uint32*)map->bitmap, *from= (uint32*)map2->bitmap, *end;
+ uint32 *to= map->bitmap, *from= map2->bitmap, *end;
DBUG_ASSERT(map->bitmap && map2->bitmap &&
map->bitmap_size==map2->bitmap_size);
@@ -295,42 +312,39 @@ void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2)
void bitmap_xor(MY_BITMAP *map, const MY_BITMAP *map2)
{
- uint32 *to= (uint32*)map->bitmap, *from= (uint32*)map2->bitmap, *end;
-
+ uint32 *to= map->bitmap, *from= map2->bitmap, *end= map->last_word_ptr;
DBUG_ASSERT(map->bitmap && map2->bitmap &&
map->bitmap_size==map2->bitmap_size);
- end= map->last_word_ptr;
-
while (to <= end)
*to++ ^= *from++;
- *map->last_word_ptr|= map->last_word_mask; //Set last bits again
+ *map->last_word_ptr|= map->last_word_mask; /*Set last bits again*/
}
void bitmap_invert(MY_BITMAP *map)
{
- uint32 *to= (uint32*)map->bitmap, *end;
+ uint32 *to= map->bitmap, *end;
DBUG_ASSERT(map->bitmap);
end= map->last_word_ptr;
while (to <= end)
*to++ ^= 0xFFFFFFFF;
- *map->last_word_ptr|= map->last_word_mask; //Set last bits again
+ *map->last_word_ptr|= map->last_word_mask; /*Set last bits again*/
}
uint bitmap_bits_set(const MY_BITMAP *map)
{
- uchar *m= map->bitmap;
+ uchar *m= (uchar*)map->bitmap;
uchar *end= m + no_bytes_in_map(map);
uint res= 0;
DBUG_ASSERT(map->bitmap);
- *map->last_word_ptr^=map->last_word_mask; //Reset last bits to zero
+ *map->last_word_ptr^=map->last_word_mask; /*Reset last bits to zero*/
while (m < end)
res+= my_count_bits_ushort(*m++);
- *map->last_word_ptr^=map->last_word_mask; //Set last bits to one again
+ *map->last_word_ptr^=map->last_word_mask; /*Set last bits to one again*/
return res;
}
@@ -341,7 +355,7 @@ uint bitmap_get_first_set(const MY_BITMAP *map)
uint32 *data_ptr, *end= map->last_word_ptr;
DBUG_ASSERT(map->bitmap);
- data_ptr= (uint32*)map->bitmap;
+ data_ptr= map->bitmap;
for (i=0; data_ptr <= end; data_ptr++, i++)
{
if (*data_ptr)
@@ -378,7 +392,7 @@ uint bitmap_get_first(const MY_BITMAP *map)
uint32 *data_ptr, *end= map->last_word_ptr;
DBUG_ASSERT(map->bitmap);
- data_ptr= (uint32*)map->bitmap;
+ data_ptr= map->bitmap;
for (i=0; data_ptr <= end; data_ptr++, i++)
{
if (*data_ptr != 0xFFFFFFFF)
@@ -612,7 +626,18 @@ void bitmap_lock_flip_bit(MY_BITMAP *map, uint bitmap_bit)
bitmap_unlock(map);
}
#endif
-#ifdef TEST_BITMAP
+#ifdef MAIN
+
+static void bitmap_print(MY_BITMAP *map)
+{
+ uint32 *to= map->bitmap, *end= map->last_word_ptr;
+ while (to <= end)
+ {
+ fprintf(stderr,"0x%x ", *to++);
+ }
+ fprintf(stderr,"\n");
+}
+
uint get_rand_bit(uint bitsize)
{
return (rand() % bitsize);
@@ -698,10 +723,10 @@ error2:
printf("Error in clear_all, bitsize = %u", bitsize);
return TRUE;
error3:
- printf("Error in bitwise set all, bitsize = %u", bitsize);
+ printf("Error in bitmap_is_set_all, bitsize = %u", bitsize);
return TRUE;
error4:
- printf("Error in bitwise clear all, bitsize = %u", bitsize);
+ printf("Error in bitmap_is_clear_all, bitsize = %u", bitsize);
return TRUE;
error5:
printf("Error in set_all through set_prefix, bitsize = %u", bitsize);
@@ -719,8 +744,8 @@ bool test_compare_operators(MY_BITMAP *map, uint bitsize)
MY_BITMAP *map2= &map2_obj, *map3= &map3_obj;
uint32 map2buf[1024];
uint32 map3buf[1024];
- bitmap_init(&map2_obj, (uchar*)&map2buf, bitsize, FALSE);
- bitmap_init(&map3_obj, (uchar*)&map3buf, bitsize, FALSE);
+ bitmap_init(&map2_obj, map2buf, bitsize, FALSE);
+ bitmap_init(&map3_obj, map3buf, bitsize, FALSE);
bitmap_clear_all(map2);
bitmap_clear_all(map3);
for (i=0; i < no_loops; i++)
@@ -926,7 +951,7 @@ bool do_test(uint bitsize)
{
MY_BITMAP map;
uint32 buf[1024];
- if (bitmap_init(&map, (uchar*)buf, bitsize, FALSE))
+ if (bitmap_init(&map, buf, bitsize, FALSE))
{
printf("init error for bitsize %d", bitsize);
goto error;