diff options
-rw-r--r-- | include/my_bitmap.h | 12 | ||||
-rw-r--r-- | mysys/Makefile.am | 3 | ||||
-rw-r--r-- | mysys/my_bitmap.c | 135 | ||||
-rw-r--r-- | sql/handler.cc | 21 | ||||
-rw-r--r-- | sql/opt_range.cc | 15 |
5 files changed, 112 insertions, 74 deletions
diff --git a/include/my_bitmap.h b/include/my_bitmap.h index a5df6389488..109a12034ba 100644 --- a/include/my_bitmap.h +++ b/include/my_bitmap.h @@ -24,7 +24,7 @@ typedef struct st_bitmap { - uchar *bitmap; + uint32 *bitmap; uint bitmap_size; /* number of bits occupied by the above */ uint32 last_word_mask; uint32 *last_word_ptr; @@ -41,7 +41,7 @@ typedef struct st_bitmap #ifdef __cplusplus extern "C" { #endif -extern my_bool bitmap_init(MY_BITMAP *map, uchar *buf, uint bitmap_size, my_bool thread_safe); +extern my_bool bitmap_init(MY_BITMAP *map, uint32 *buf, uint bitmap_size, my_bool thread_safe); extern my_bool bitmap_is_clear_all(const MY_BITMAP *map); extern my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size); extern my_bool bitmap_is_set_all(const MY_BITMAP *map); @@ -84,10 +84,10 @@ extern void bitmap_lock_invert(MY_BITMAP *map); #define no_bytes_in_map(map) ((map->bitmap_size + 7)/8) #define no_words_in_map(map) ((map->bitmap_size + 31)/32) #define bytes_word_aligned(bytes) (4*((bytes + 3)/4)) -#define bitmap_set_bit(MAP, BIT) ((MAP)->bitmap[(BIT) / 8] |= (1 << ((BIT) & 7))) -#define bitmap_flip_bit(MAP, BIT) ((MAP)->bitmap[(BIT) / 8] ^= (1 << ((BIT) & 7))) -#define bitmap_clear_bit(MAP, BIT) ((MAP)->bitmap[(BIT) / 8] &= ~ (1 << ((BIT) & 7))) -#define bitmap_is_set(MAP, BIT) ((MAP)->bitmap[(BIT) / 8] & (1 << ((BIT) & 7))) +#define bitmap_set_bit(MAP, BIT) ((MAP)->bitmap[(BIT) / 32] |= (1 << ((BIT) & 31))) +#define bitmap_flip_bit(MAP, BIT) ((MAP)->bitmap[(BIT) / 32] ^= (1 << ((BIT) & 31))) +#define bitmap_clear_bit(MAP, BIT) ((MAP)->bitmap[(BIT) / 32] &= ~ (1 << ((BIT) & 31))) +#define bitmap_is_set(MAP, BIT) ((MAP)->bitmap[(BIT) / 32] & (1 << ((BIT) & 31))) #define bitmap_cmp(MAP1, MAP2) \ (memcmp((MAP1)->bitmap, (MAP2)->bitmap, 4*no_words_in_map((MAP1)))==0) #define bitmap_clear_all(MAP) \ diff --git a/mysys/Makefile.am b/mysys/Makefile.am index 03ee692645f..3031edcc77d 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -80,6 +80,9 @@ FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@ # which automaticly removes the object files you use to compile a final program # +test_bitmap$(EXEEXT): my_bitmap.c $(LIBRARIES) + $(LINK) $(FLAGS) -DMAIN ./my_bitmap.c $(LDADD) $(LIBS) + test_thr_alarm$(EXEEXT): thr_alarm.c $(LIBRARIES) $(CP) $(srcdir)/thr_alarm.c ./test_thr_alarm.c $(LINK) $(FLAGS) -DMAIN ./test_thr_alarm.c $(LDADD) $(LIBS) 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; diff --git a/sql/handler.cc b/sql/handler.cc index ff9a8e96268..8d23b4fa324 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1360,20 +1360,31 @@ int handler::ha_initialise() int handler::ha_allocate_read_write_set(ulong no_fields) { uint bitmap_size= 4*(((no_fields+1)+31)/32); - uchar *read_buf, *write_buf; + uint32 *read_buf, *write_buf; +#ifndef DEBUG_OFF + my_bool r; +#endif DBUG_ENTER("ha_allocate_read_write_set"); DBUG_PRINT("info", ("no_fields = %d", no_fields)); read_set= (MY_BITMAP*)sql_alloc(sizeof(MY_BITMAP)); write_set= (MY_BITMAP*)sql_alloc(sizeof(MY_BITMAP)); - read_buf= (uchar*)sql_alloc(bitmap_size); - write_buf= (uchar*)sql_alloc(bitmap_size); - DBUG_ASSERT(!bitmap_init(read_set, read_buf, (no_fields+1), FALSE)); - DBUG_ASSERT(!bitmap_init(write_set, write_buf, (no_fields+1), FALSE)); + read_buf= (uint32*)sql_alloc(bitmap_size); + write_buf= (uint32*)sql_alloc(bitmap_size); if (!read_set || !write_set || !read_buf || !write_buf) { ha_deallocate_read_write_set(); DBUG_RETURN(TRUE); } +#ifndef DEBUG_OFF + r = +#endif + bitmap_init(read_set, read_buf, no_fields+1, FALSE); + DBUG_ASSERT(!r /*bitmap_init(read_set...)*/); +#ifndef DEBUG_OFF + r = +#endif + bitmap_init(write_set, write_buf, no_fields+1, FALSE); + DBUG_ASSERT(!r /*bitmap_init(write_set...)*/); ha_clear_all_set(); DBUG_RETURN(FALSE); } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 3f2ea7ef562..e53f5ad0c66 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1566,9 +1566,9 @@ static int fill_used_fields_bitmap(PARAM *param) { TABLE *table= param->table; param->fields_bitmap_size= (table->s->fields/8 + 1); - uchar *tmp; + uint32 *tmp; uint pk; - if (!(tmp= (uchar*)alloc_root(param->mem_root, + if (!(tmp= (uint32*)alloc_root(param->mem_root, bytes_word_aligned(param->fields_bitmap_size))) || bitmap_init(¶m->needed_fields, tmp, param->fields_bitmap_size*8, FALSE)) @@ -2309,7 +2309,7 @@ static ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg) { ROR_SCAN_INFO *ror_scan; - uchar *bitmap_buf; + uint32 *bitmap_buf; uint keynr; DBUG_ENTER("make_ror_scan"); if (!(ror_scan= (ROR_SCAN_INFO*)alloc_root(param->mem_root, @@ -2323,7 +2323,7 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg) ror_scan->sel_arg= sel_arg; ror_scan->records= param->table->quick_rows[keynr]; - if (!(bitmap_buf= (uchar*)alloc_root(param->mem_root, + if (!(bitmap_buf= (uint32*)alloc_root(param->mem_root, bytes_word_aligned(param->fields_bitmap_size)))) DBUG_RETURN(NULL); @@ -2439,12 +2439,12 @@ static ROR_INTERSECT_INFO* ror_intersect_init(const PARAM *param) { ROR_INTERSECT_INFO *info; - uchar* buf; + uint32* buf; if (!(info= (ROR_INTERSECT_INFO*)alloc_root(param->mem_root, sizeof(ROR_INTERSECT_INFO)))) return NULL; info->param= param; - if (!(buf= (uchar*)alloc_root(param->mem_root, + if (!(buf= (uint32*)alloc_root(param->mem_root, bytes_word_aligned(param->fields_bitmap_size)))) return NULL; if (bitmap_init(&info->covered_fields, buf, param->fields_bitmap_size*8, @@ -3003,9 +3003,8 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param, ror_scan_mark= tree->ror_scans; uint32 int_buf[MAX_KEY/32+1]; - uchar *buf= (uchar*)&int_buf; MY_BITMAP covered_fields; - if (bitmap_init(&covered_fields, buf, nbits, FALSE)) + if (bitmap_init(&covered_fields, int_buf, nbits, FALSE)) DBUG_RETURN(0); bitmap_clear_all(&covered_fields); |