diff --git a/sql/Makefile.am b/sql/Makefile.am index aabe7c08f0fa82992f5200814f228091e99f42a5..50cd18b816e68d7f932aefac27298d854b9f546d 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -91,6 +91,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \ slave.cc sql_repl.cc rpl_filter.cc \ sql_union.cc sql_derived.cc \ + bitvector.cc \ client.c sql_client.cc mini_client_errors.c pack.c\ stacktrace.c repl_failsafe.h repl_failsafe.cc \ sql_olap.cc sql_view.cc \ diff --git a/sql/bitvector.cc b/sql/bitvector.cc index d50ad7df33bbdce982e0702f33e267b9b721924c..219d34c5920867cff5982d36bd099a06717fe138 100644 --- a/sql/bitvector.cc +++ b/sql/bitvector.cc @@ -120,7 +120,7 @@ uint bitvector::get_first_bit_set() return MYSQL_NO_BIT_FOUND; } -uint bitvector::get_first_bit_unset() +uint bitvector::get_first_bit_clear() { uchar *byte_ptr; uint32 *data_ptr= (uint32*)data(), bit_found,i,j,k; @@ -154,41 +154,6 @@ uint bitvector::get_first_bit_unset() } #ifdef TEST_BITVECTOR - -int main() -{ - int i; - for (i= 0; i < 4096; i++) - if (do_test(i)) - return -1; - return 0; -} - -bool do_test(uint bitsize) -{ - bitvector *bv; - bv = new bitvector; - bv->init(bitsize); - if (test_set_get_clear_bit(bv,bitsize)) - return TRUE; - if (test_flip_bit(bv,bitsize)) - return TRUE; - if (test_operators(bv,bitsize)) - return TRUE; - if (test_get_all_bits(bvbitsize)) - return TRUE; - if (test_compare_operators(bv,bitsize)) - return TRUE; - if (test_count_bits_set(bv,bitsize)) - return TRUE; - if (test_get_first_bit(bv,bitsize)) - return TRUE; - if (test_get_next_bit(bv,bitsize)) - return TRUE; - printf("OK"); - return FALSE; -} - uint get_rand_bit(uint bitsize) { return (rand() % bitsize); @@ -201,7 +166,7 @@ bool test_set_get_clear_bit(bitvector *bv, uint bitsize) for (i=0; i < no_loops; i++) { test_bit= get_rand_bit(bitsize); - bv->set_bit(test_bit) + bv->set_bit(test_bit); if (!bv->get_bit(test_bit)) goto error1; bv->clear_bit(test_bit); @@ -219,12 +184,12 @@ bool test_set_get_clear_bit(bitvector *bv, uint bitsize) bool test_flip_bit(bitvector *bv, uint bitsize) { - uint i test_bit; + uint i, test_bit; uint no_loops= bitsize > 128 ? 128 : bitsize; for (i=0; i < no_loops; i++) { test_bit= get_rand_bit(bitsize); - bv->flip_bit(test_bit) + bv->flip_bit(test_bit); if (!bv->get_bit(test_bit)) goto error1; bv->flip_bit(test_bit); @@ -284,7 +249,7 @@ bool test_compare_operators(bitvector *bv, uint bitsize) bool test_count_bits_set(bitvector *bv, uint bitsize) { - uint i, bit_count=0; + uint i, bit_count=0, test_bit; uint no_loops= bitsize > 128 ? 128 : bitsize; for (i=0; i < no_loops; i++) { @@ -296,9 +261,9 @@ bool test_count_bits_set(bitvector *bv, uint bitsize) } } if (bit_count==0 && bitsize > 0) - error1; + goto error1; if (bv->no_bits_set() != bit_count) - error2; + goto error2; return FALSE; error1: printf("No bits set bitsize = %u", bitsize); @@ -317,4 +282,39 @@ bool test_get_next_bit(bitvector *bv, uint bitsize) { return FALSE; } + +bool do_test(uint bitsize) +{ + bitvector *bv; + bv = new bitvector; + bv->init(bitsize); + if (test_set_get_clear_bit(bv,bitsize)) + return TRUE; + if (test_flip_bit(bv,bitsize)) + return TRUE; + if (test_operators(bv,bitsize)) + return TRUE; + if (test_get_all_bits(bv, bitsize)) + return TRUE; + if (test_compare_operators(bv,bitsize)) + return TRUE; + if (test_count_bits_set(bv,bitsize)) + return TRUE; + if (test_get_first_bit(bv,bitsize)) + return TRUE; + if (test_get_next_bit(bv,bitsize)) + return TRUE; + printf("OK"); + return FALSE; +} + +int main() +{ + int i; + for (i= 0; i < 4096; i++) + if (do_test(i)) + return -1; + return 0; +} + #endif diff --git a/sql/bitvector.h b/sql/bitvector.h index 4d3e8982007e966b7a4dc5d39b7f7188f361d8b1..bb7a1d6c3b974e780d92535855157d987cb7fcbc 100644 --- a/sql/bitvector.h +++ b/sql/bitvector.h @@ -85,49 +85,7 @@ class bitvector return ((bits + 31) >> 5) << 2; } - void create_last_word_mask() - { - - /* Get the number of used bits (1..8) in the last byte */ - unsigned int const used= 1U + ((size()-1U) & 0x7U); - - /* - * Create a mask with the upper 'unused' bits set and the lower 'used' - * bits clear. The bits within each byte is stored in big-endian order. - */ - unsigned char const mask= (~((1 << used) - 1)) & 255; - last_word_ptr= (uint32*)(m_data+((bytes()-1U)>>2)); - - /* - The first bytes are to be set to zero since they represent real bits - in the bitvector. The last bytes are set to 0xFF since they represent - bytes not used by the bitvector. Finally the last byte contains bits - as set by the mask above. - */ - - unsigned char *ptr= (unsigned char*)&last_word_mask; - switch (bytes()&3) - { - case 1: - last_word_mask= ~0U; - ptr[0]= mask; - return; - case 2: - last_word_mask= ~0U; - ptr[0]= 0; - ptr[1]= mask; - return; - case 3: - last_word_mask= 0U; - ptr[2]= mask; - ptr[3]= 0xFFU; - return; - case 0: - last_word_mask= 0U; - ptr[3]= mask; - return; - } - } + void create_last_word_mask(); inline void tidy_last_word() { @@ -181,19 +139,18 @@ class bitvector my_free((char*)m_data, MYF(0)); } - int init(size_t size) - { - DBUG_ASSERT(size < MYSQL_NO_BIT_FOUND); - m_size= size; - m_data= (uchar*)my_malloc(byte_size_word_aligned(size), MYF(0)); - if (m_data) - { - create_last_word_mask(); - clear_all(); - return FALSE; - } - return TRUE; - } + /* + Allocate memory to the bitvector and create last word mask + and clear all bits in the bitvector. + */ + int init(size_t size); + + /* Get number of bits set in the bitvector */ + uint no_bits_set(); + /* Get first bit set/clear in bitvector */ + uint get_first_bit_set(); + uint get_first_bit_clear(); + /* Swap the guts of this instance with another instance. */ void swap(bitvector& other) @@ -332,84 +289,6 @@ class bitvector return *this; } - uint no_bits_set() - { - uint no_bytes= bytes(), res=0, i; - uchar *ptr= m_data; - *last_word_ptr^=last_word_mask; //Reset last bits to zero - for (i=0; i< no_bytes; i++, ptr++) - res+=my_count_bits_ushort(*ptr); - *last_word_ptr^=last_word_mask; //Set last bits to one again - return res; - } - - uint get_first_bit_set() - { - uchar *byte_ptr; - uint32 *data_ptr= (uint32*)data(), bit_found,i,j,k; - for (i=0; data_ptr <= last_word_ptr; data_ptr++, i++) - { - if (*data_ptr) - { - byte_ptr= (uchar*)data_ptr; - for (j=0; j < 4; j++, byte_ptr++) - { - if (*byte_ptr) - { - for (k=0; k < 8; k++) - { - if (*byte_ptr & (1 << k)) - { - bit_found= (i << 5) + (j << 3) + k; - if (bit_found == m_size) - return MYSQL_NO_BIT_FOUND; - else - return bit_found; - } - } - DBUG_ASSERT(1); - } - } - DBUG_ASSERT(1); - } - } - return MYSQL_NO_BIT_FOUND; - } - - uint get_first_bit_unset() - { - uchar *byte_ptr; - uint32 *data_ptr= (uint32*)data(), bit_found,i,j,k; - for (i=0; data_ptr <= last_word_ptr; data_ptr++, i++) - { - if (*data_ptr != 0xFFFFFFFF) - { - byte_ptr= (uchar*)data_ptr; - for (j=0; j < 4; j++, byte_ptr++) - { - if (*byte_ptr != 0xFF) - { - for (k=0; k < 8; k++) - { - if (!(*byte_ptr & (1 << k))) - { - bit_found= (i << 5) + (j << 3) + k; - if (bit_found == m_size) - return MYSQL_NO_BIT_FOUND; - else - return bit_found; - } - } - DBUG_ASSERT(1); - } - } - DBUG_ASSERT(1); - } - } - return MYSQL_NO_BIT_FOUND; - } - - private: size_t m_size; uint32 last_word_mask; diff --git a/sql/handler.cc b/sql/handler.cc index c00f79c2995f4be87ee9d6db6ea0cc0e6a9d3a7c..229fe4ccc18b1de7b4243560b7e5993479ce0607 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1451,6 +1451,7 @@ void handler::ha_set_bit_in_rw_set(uint fieldnr, bool write_op) DBUG_PRINT("info", ("Set bit in write set")); write_set->set_bit((size_t)fieldnr); } + DBUG_VOID_RETURN; } bool handler::ha_get_bit_in_read_set(uint fieldnr)