WL 1682:
Divide bitvector into .cc and .h file sql/Makefile.am: Divide bitvector into .cc file and .h file sql/bitvector.cc: Fixed up test program for bitvector sql/bitvector.h: Move out things to .cc file sql/handler.cc: Forgotten debug statement
This commit is contained in:
parent
b458624e96
commit
e0504b7e7d
@ -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 \
|
||||
|
@ -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 @@ error2:
|
||||
|
||||
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
|
||||
|
147
sql/bitvector.h
147
sql/bitvector.h
@ -85,49 +85,7 @@ private:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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;
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user