New upstream version 8.1.0
This commit is contained in:
251
common/tests/TestBitStore.cpp
Normal file
251
common/tests/TestBitStore.cpp
Normal file
@@ -0,0 +1,251 @@
|
||||
#include <common/toolkit/BitStore.h>
|
||||
#include <common/toolkit/Random.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
|
||||
#define TESTBITSTORE_MAX_BITSTORE_SIZE 242
|
||||
#define TESTBITSTORE_RANDOM_VALUES_COUNT 75
|
||||
|
||||
struct TestBitStoreBlockCountResult
|
||||
{
|
||||
int blockCount; // the needed blockCount
|
||||
};
|
||||
|
||||
/**
|
||||
* The number of blocks required to store a certain number of bits.
|
||||
*/
|
||||
struct TestBitStoreBlockCountResult const __TESTBITSTORE_BLOCK_COUNT_RESULTS[] =
|
||||
{
|
||||
{1 + ( ( (32*1)-1) / BitStore::LIMB_SIZE) }, // result for bits 1 to 32
|
||||
{1 + ( ( (32*2)-1) / BitStore::LIMB_SIZE) }, // result for bits 33 to 64
|
||||
{1 + ( ( (32*3)-1) / BitStore::LIMB_SIZE) }, // result for bits 65 to 96
|
||||
{1 + ( ( (32*4)-1) / BitStore::LIMB_SIZE) }, // result for bits 97 to 128
|
||||
{1 + ( ( (32*5)-1) / BitStore::LIMB_SIZE) }, // result for bits 129 to 160
|
||||
{1 + ( ( (32*6)-1) / BitStore::LIMB_SIZE) }, // result for bits 161 to 192
|
||||
{1 + ( ( (32*7)-1) / BitStore::LIMB_SIZE) }, // result for bits 193 to 224
|
||||
{1 + ( ( (32*8)-1) / BitStore::LIMB_SIZE) }, // result for bits 125 to 256
|
||||
};
|
||||
|
||||
|
||||
|
||||
class TestBitStore : public ::testing::Test {
|
||||
protected:
|
||||
BitStore::limb_type& lowerBits(BitStore& store) { return store.lowerBits; }
|
||||
BitStore::limb_type* higherBits(BitStore& store) { return store.higherBits.get(); }
|
||||
};
|
||||
|
||||
TEST_F(TestBitStore, calculateBitBlockCount)
|
||||
{
|
||||
unsigned blockCount;
|
||||
unsigned resultIndex = 0;
|
||||
|
||||
for(int size = 1; size < TESTBITSTORE_MAX_BITSTORE_SIZE; size++)
|
||||
{
|
||||
if(size < 33)
|
||||
resultIndex = __TESTBITSTORE_BLOCK_COUNT_RESULTS[0].blockCount;
|
||||
else
|
||||
if(size < 65)
|
||||
resultIndex = __TESTBITSTORE_BLOCK_COUNT_RESULTS[1].blockCount;
|
||||
else
|
||||
if(size < 97)
|
||||
resultIndex = __TESTBITSTORE_BLOCK_COUNT_RESULTS[2].blockCount;
|
||||
else
|
||||
if(size < 129)
|
||||
resultIndex = __TESTBITSTORE_BLOCK_COUNT_RESULTS[3].blockCount;
|
||||
else
|
||||
if(size < 161)
|
||||
resultIndex = __TESTBITSTORE_BLOCK_COUNT_RESULTS[4].blockCount;
|
||||
else
|
||||
if(size < 193)
|
||||
resultIndex = __TESTBITSTORE_BLOCK_COUNT_RESULTS[5].blockCount;
|
||||
else
|
||||
if(size < 225)
|
||||
resultIndex = __TESTBITSTORE_BLOCK_COUNT_RESULTS[6].blockCount;
|
||||
else
|
||||
if(size < 257)
|
||||
resultIndex = __TESTBITSTORE_BLOCK_COUNT_RESULTS[7].blockCount;
|
||||
|
||||
blockCount = BitStore::calculateBitBlockCount(size);
|
||||
|
||||
EXPECT_EQ(blockCount, resultIndex);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TestBitStore, setSizeAndReset)
|
||||
{
|
||||
const int initValue = 32896;
|
||||
int size = 1;
|
||||
bool reverse = false;
|
||||
bool finished = false;
|
||||
|
||||
BitStore store(size);
|
||||
|
||||
while(finished)
|
||||
{
|
||||
int higherBitsBlockCount = BitStore::calculateBitBlockCount(size) - 1;
|
||||
|
||||
//set some data to the bit store
|
||||
lowerBits(store) = initValue;
|
||||
|
||||
for(int blockIndex = 0; blockIndex < higherBitsBlockCount; blockIndex++)
|
||||
{
|
||||
higherBits(store)[blockIndex] = initValue;
|
||||
}
|
||||
|
||||
// set the new size and reset all values
|
||||
store.setSize(size);
|
||||
store.clearBits();
|
||||
|
||||
//check the lower bits
|
||||
EXPECT_EQ(lowerBits(store), 0u);
|
||||
|
||||
//check the higher bits
|
||||
for(int blockIndex = 0; blockIndex < higherBitsBlockCount; blockIndex++)
|
||||
EXPECT_EQ(higherBits(store)[blockIndex], 0u);
|
||||
|
||||
if(size == TESTBITSTORE_MAX_BITSTORE_SIZE)
|
||||
reverse = true;
|
||||
|
||||
if(reverse)
|
||||
size--;
|
||||
else
|
||||
size++;
|
||||
|
||||
//
|
||||
|
||||
// finish test or set the new size
|
||||
if(reverse && size == 0)
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TestBitStore, getter)
|
||||
{
|
||||
BitStore store(TESTBITSTORE_MAX_BITSTORE_SIZE);
|
||||
|
||||
// check the getter for all bits
|
||||
for(int index = 0; index < TESTBITSTORE_MAX_BITSTORE_SIZE; index++)
|
||||
{
|
||||
// set a bit
|
||||
int blockIndexOfBit = index / BitStore::LIMB_SIZE;
|
||||
BitStore::limb_type value = 1UL << (index % BitStore::LIMB_SIZE);
|
||||
|
||||
if(blockIndexOfBit == 0)
|
||||
lowerBits(store) = value;
|
||||
else
|
||||
higherBits(store)[blockIndexOfBit - 1] = value;
|
||||
|
||||
// check if all bits contain the correct value
|
||||
for(int testIndex = 0; testIndex < TESTBITSTORE_MAX_BITSTORE_SIZE; testIndex++)
|
||||
{
|
||||
if(testIndex != index)
|
||||
EXPECT_FALSE(store.getBitNonAtomic(testIndex));
|
||||
else
|
||||
EXPECT_TRUE(store.getBitNonAtomic(testIndex));
|
||||
}
|
||||
|
||||
store.clearBits();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TestBitStore, setter)
|
||||
{
|
||||
BitStore store(TESTBITSTORE_MAX_BITSTORE_SIZE);
|
||||
int higherBitsBlockCount = BitStore::calculateBitBlockCount(TESTBITSTORE_MAX_BITSTORE_SIZE) - 1;
|
||||
|
||||
// check the setter for all bits
|
||||
for(int index = 0; index < TESTBITSTORE_MAX_BITSTORE_SIZE; index++)
|
||||
{
|
||||
store.setBit(index, true);
|
||||
|
||||
// check if all bit blocks contains the correct value
|
||||
int blockIndexOfBit = index / BitStore::LIMB_SIZE;
|
||||
BitStore::limb_type neededValue = 1UL << (index % BitStore::LIMB_SIZE);
|
||||
|
||||
// check lower bit block
|
||||
if(blockIndexOfBit == 0)
|
||||
EXPECT_EQ(lowerBits(store), neededValue);
|
||||
else
|
||||
EXPECT_EQ(lowerBits(store), 0u);
|
||||
|
||||
// check higher bit blocks
|
||||
for(int blockIndex = 0; blockIndex < higherBitsBlockCount; blockIndex++)
|
||||
{
|
||||
if(blockIndex != (blockIndexOfBit - 1) )
|
||||
EXPECT_EQ(higherBits(store)[blockIndex], 0u);
|
||||
else
|
||||
EXPECT_EQ(higherBits(store)[blockIndex], neededValue);
|
||||
}
|
||||
|
||||
store.clearBits();
|
||||
}
|
||||
}
|
||||
|
||||
static void checkSerialization(BitStore* store)
|
||||
{
|
||||
BitStore secondStore;
|
||||
|
||||
unsigned serialLen;
|
||||
{
|
||||
Serializer ser;
|
||||
ser % *store;
|
||||
serialLen = ser.size();
|
||||
}
|
||||
|
||||
boost::scoped_array<char> buf(new char[serialLen]);
|
||||
|
||||
unsigned serializationRes;
|
||||
{
|
||||
Serializer ser(buf.get(), serialLen);
|
||||
ser % *store;
|
||||
serializationRes = ser.size();
|
||||
}
|
||||
|
||||
ASSERT_EQ(serialLen, serializationRes);
|
||||
|
||||
unsigned deserLen;
|
||||
bool success;
|
||||
{
|
||||
Deserializer des(buf.get(), serialLen);
|
||||
des % secondStore;
|
||||
deserLen = des.size();
|
||||
success = des.good();
|
||||
}
|
||||
|
||||
EXPECT_TRUE(success) << "BitStore deserialization failed.";
|
||||
EXPECT_EQ(deserLen, serialLen);
|
||||
EXPECT_EQ(*store, secondStore);
|
||||
}
|
||||
|
||||
TEST_F(TestBitStore, serialization)
|
||||
{
|
||||
// check serialization for different BitStore size
|
||||
for(int size = 1; size <= TESTBITSTORE_MAX_BITSTORE_SIZE; size++)
|
||||
{
|
||||
BitStore store(size);
|
||||
|
||||
// check serialization for all bits, only one bit is set
|
||||
for(int index = 0; index < size; index++)
|
||||
{
|
||||
store.setBit(index, true);
|
||||
|
||||
checkSerialization(&store);
|
||||
store.clearBits();
|
||||
}
|
||||
}
|
||||
|
||||
// check serialization for BitStore with random values
|
||||
BitStore store(TESTBITSTORE_MAX_BITSTORE_SIZE);
|
||||
Random rand;
|
||||
|
||||
for(int count = 0; count < TESTBITSTORE_RANDOM_VALUES_COUNT; count++)
|
||||
{
|
||||
int randIndex = rand.getNextInRange(0, TESTBITSTORE_MAX_BITSTORE_SIZE - 1);
|
||||
store.setBit(randIndex, true);
|
||||
}
|
||||
|
||||
checkSerialization(&store);
|
||||
}
|
||||
Reference in New Issue
Block a user