Querying a bitmap distinguishing 0-values
I'm writing a piece of software that will process huge amounts of data. For memory efficiency, some of the fields in the records being processed are stored in a single bitmap.
Using #define
s I declared what both the po开发者_如何学JAVAsition and the size of each field in the bitmap is.
Now I need a fast way to check against predefined values. My first attempt was this:
bool checkBit(unsigned short int a_bitMap, unsigned short int a_bitValue, unsigned short int a_bitPosition)
{
// Values are always bit-0 based, so we need to shift here
unsigned short int _value = (a_bitValue << a_bitPosition);
return ((a_bitMap & _value) == _value);
}
Here, a_bitMap is the bitmap for the record being processed holding data for all fields, and a_bitValue is the (defined) coded value being checked (which would, in case of flags, always be 1).
This works and is fast, but this way I cannot use the value '0' as a coded value (so 3 bit give me only 7 options, not 8) so I came up with this solution:
bool checkBit(unsigned short int a_bitMap, unsigned short int a_bitValue, unsigned short int a_bitPosition, unsigned short int a_bitSize)
{
static const unsigned short int bitmapSize = 8 * sizeof(a_bitMap);
unsigned short int _shift = bitmapSize - (a_bitPosition + a_bitSize);
a_bitMap = (a_bitMap << _shift);
a_bitMap = (a_bitMap >> (a_bitPosition + _shift));
return (a_bitMap == a_bitValue);
}
This works exactly the way I want... but it slows down the process dramatically. The number of records that need to be processed goes into the billions, so these extra shifts have a huge impact. That's also why I'd like to avoid std::bitset, since billions of object instantiations gives too much overhead as well.
How can I do this while still being able to distinguish 0-values?
You probably want something like this:
bool checkBit(unsigned short int a_bitMap, unsigned short int a_bitPosition)
{
unsigned short int _value = (1 << a_bitPosition);
return (a_bitMap & _value) != 0;
}
This checks for the a_bitPosition's bit set/unset in a_bitMap and returns true if that specific bit is 1 and false otherwise.
As a solution I'd define and pass in a mask rather than position and size so if you wanted a 2 bit data from position 3 and 4 of an 8 bit map you'd define
#define mask = 0x18;//binary 00011000
then in check bit you just need to:
return (map & mask) == value;
精彩评论