277 lines
7.5 KiB
C++
277 lines
7.5 KiB
C++
|
#include <lw/lib/HashIndex.hh>
|
||
|
#include <cppunit/extensions/HelperMacros.h>
|
||
|
using namespace lw;
|
||
|
|
||
|
|
||
|
class HashIndexTest : public CppUnit::TestFixture
|
||
|
{
|
||
|
CPPUNIT_TEST_SUITE( HashIndexTest );
|
||
|
CPPUNIT_TEST( testEmpty );
|
||
|
CPPUNIT_TEST( testAddChain );
|
||
|
CPPUNIT_TEST( testAddMultiple );
|
||
|
|
||
|
CPPUNIT_TEST( testRemoveSingle );
|
||
|
CPPUNIT_TEST( testRemoveLast );
|
||
|
CPPUNIT_TEST( testRemoveMiddle );
|
||
|
|
||
|
CPPUNIT_TEST( testClear );
|
||
|
CPPUNIT_TEST( testFree );
|
||
|
|
||
|
CPPUNIT_TEST( testCopyCons );
|
||
|
CPPUNIT_TEST( testCopyAss );
|
||
|
|
||
|
CPPUNIT_TEST( testMoveCons );
|
||
|
CPPUNIT_TEST( testMoveAss );
|
||
|
|
||
|
CPPUNIT_TEST( testSwap );
|
||
|
CPPUNIT_TEST_SUITE_END( );
|
||
|
|
||
|
static constexpr uint32_t C_SIZE_ = 16;
|
||
|
|
||
|
public:
|
||
|
void testEmpty( );
|
||
|
|
||
|
void testAddChain( );
|
||
|
void testAddMultiple( );
|
||
|
|
||
|
void testRemoveSingle( );
|
||
|
void testRemoveLast( );
|
||
|
void testRemoveMiddle( );
|
||
|
|
||
|
void testClear( );
|
||
|
void testFree( );
|
||
|
|
||
|
void testCopyCons( );
|
||
|
void testCopyAss( );
|
||
|
|
||
|
void testMoveCons( );
|
||
|
void testMoveAss( );
|
||
|
|
||
|
void testSwap( );
|
||
|
};
|
||
|
CPPUNIT_TEST_SUITE_REGISTRATION( HashIndexTest );
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
void HashIndexTest::testEmpty( )
|
||
|
{
|
||
|
T_HashIndex index( C_SIZE_ , C_SIZE_ , C_SIZE_ );
|
||
|
for ( uint32_t k = 0 ; k < C_SIZE_ * 16 ; k ++ ) {
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , index.first( k ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
void HashIndexTest::testAddChain( )
|
||
|
{
|
||
|
T_HashIndex index( C_SIZE_ , C_SIZE_ , C_SIZE_ );
|
||
|
for ( uint32_t i = 0 ; i < 8 ; i ++ ) {
|
||
|
index.add( 0 );
|
||
|
}
|
||
|
|
||
|
auto idx( index.first( 0 ) );
|
||
|
int32_t i( 7 );
|
||
|
do {
|
||
|
CPPUNIT_ASSERT_EQUAL( uint32_t( i ) , idx );
|
||
|
i --;
|
||
|
idx = index.next( idx );
|
||
|
} while ( idx != T_HashIndex::INVALID_INDEX && i >= 0 );
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , idx );
|
||
|
CPPUNIT_ASSERT_EQUAL( i , -1 );
|
||
|
}
|
||
|
|
||
|
void HashIndexTest::testAddMultiple( )
|
||
|
{
|
||
|
T_HashIndex index( C_SIZE_ , C_SIZE_ , C_SIZE_ );
|
||
|
for ( uint32_t i = 0 ; i < 8 ; i ++ ) {
|
||
|
for ( uint32_t j = 0 ; j < 8 ; j ++ ) {
|
||
|
index.add( j );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for ( uint32_t j = 0 ; j < 8 ; j ++ ) {
|
||
|
auto idx( index.first( j ) );
|
||
|
int32_t i( 7 );
|
||
|
do {
|
||
|
CPPUNIT_ASSERT_EQUAL( uint32_t( i * 8 ) + j , idx );
|
||
|
i --;
|
||
|
idx = index.next( idx );
|
||
|
} while ( idx != T_HashIndex::INVALID_INDEX && i >= 0 );
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , idx );
|
||
|
CPPUNIT_ASSERT_EQUAL( i , -1 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
void HashIndexTest::testRemoveSingle( )
|
||
|
{
|
||
|
T_HashIndex index( C_SIZE_ , C_SIZE_ , C_SIZE_ );
|
||
|
index.add( 0 );
|
||
|
index.add( 1 );
|
||
|
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , index.first( 0 ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , index.first( 1 ) );
|
||
|
index.remove( 0 );
|
||
|
CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , index.first( 1 ) );
|
||
|
}
|
||
|
|
||
|
void HashIndexTest::testRemoveLast( )
|
||
|
{
|
||
|
T_HashIndex index( C_SIZE_ , C_SIZE_ , C_SIZE_ );
|
||
|
for ( uint32_t i = 0 ; i < 8 ; i ++ ) {
|
||
|
index.add( 0 );
|
||
|
}
|
||
|
index.add( 1 );
|
||
|
CPPUNIT_ASSERT_EQUAL( uint32_t( 7 ) , index.first( 0 ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( uint32_t( 8 ) , index.first( 1 ) );
|
||
|
index.remove( 7 );
|
||
|
CPPUNIT_ASSERT_EQUAL( uint32_t( 6 ) , index.first( 0 ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( uint32_t( 7 ) , index.first( 1 ) );
|
||
|
}
|
||
|
|
||
|
void HashIndexTest::testRemoveMiddle( )
|
||
|
{
|
||
|
T_HashIndex index( C_SIZE_ , C_SIZE_ , C_SIZE_ );
|
||
|
for ( uint32_t i = 0 ; i < 8 ; i ++ ) {
|
||
|
index.add( 0 );
|
||
|
}
|
||
|
index.add( 1 );
|
||
|
CPPUNIT_ASSERT_EQUAL( uint32_t( 7 ) , index.first( 0 ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( uint32_t( 8 ) , index.first( 1 ) );
|
||
|
// Chain 0: 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 -> X
|
||
|
// Chain 1: 8 -> X
|
||
|
|
||
|
index.remove( 6 );
|
||
|
|
||
|
// Chain 0: 7 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 -> X
|
||
|
// Chain 1: 6 -> X
|
||
|
CPPUNIT_ASSERT_EQUAL( uint32_t( 7 ) , index.first( 0 ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( uint32_t( 5 ) , index.next( 7 ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( uint32_t( 6 ) , index.first( 1 ) );
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
void HashIndexTest::testClear( )
|
||
|
{
|
||
|
T_HashIndex index( C_SIZE_ , C_SIZE_ , C_SIZE_ );
|
||
|
for ( uint32_t k = 0 ; k < C_SIZE_ * 16 ; k ++ ) {
|
||
|
index.add( k >> 2 );
|
||
|
}
|
||
|
index.clear( );
|
||
|
for ( uint32_t k = 0 ; k < C_SIZE_ * 16 ; k ++ ) {
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , index.first( k ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void HashIndexTest::testFree( )
|
||
|
{
|
||
|
T_HashIndex index( C_SIZE_ , C_SIZE_ , C_SIZE_ );
|
||
|
for ( uint32_t k = 0 ; k < C_SIZE_ * 16 ; k ++ ) {
|
||
|
index.add( k >> 2 );
|
||
|
}
|
||
|
index.free( );
|
||
|
for ( uint32_t k = 0 ; k < C_SIZE_ * 16 ; k ++ ) {
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , index.first( k ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
void HashIndexTest::testCopyCons( )
|
||
|
{
|
||
|
T_HashIndex index( C_SIZE_ , C_SIZE_ , C_SIZE_ );
|
||
|
for ( uint32_t k = 0 ; k < 8 ; k ++ ) {
|
||
|
index.add( k );
|
||
|
}
|
||
|
T_HashIndex copy( index );
|
||
|
for ( uint32_t k = 0 ; k < 8 ; k ++ ) {
|
||
|
index.add( k + 8 );
|
||
|
}
|
||
|
|
||
|
for ( uint32_t k = 0 ; k < 8 ; k ++ ) {
|
||
|
CPPUNIT_ASSERT_EQUAL( k , copy.first( k ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( k , index.first( k ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , copy.next( k ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , index.next( k ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( k + 8 , index.first( k + 8 ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , index.next( k + 8 ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , copy.first( k + 8 ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void HashIndexTest::testCopyAss( )
|
||
|
{
|
||
|
T_HashIndex index( C_SIZE_ , C_SIZE_ , C_SIZE_ );
|
||
|
for ( uint32_t k = 0 ; k < 8 ; k ++ ) {
|
||
|
index.add( k );
|
||
|
}
|
||
|
T_HashIndex copy;
|
||
|
copy = index;
|
||
|
for ( uint32_t k = 0 ; k < 8 ; k ++ ) {
|
||
|
index.add( k + 8 );
|
||
|
}
|
||
|
|
||
|
for ( uint32_t k = 0 ; k < 8 ; k ++ ) {
|
||
|
CPPUNIT_ASSERT_EQUAL( k , copy.first( k ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( k , index.first( k ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , copy.next( k ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , index.next( k ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( k + 8 , index.first( k + 8 ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , index.next( k + 8 ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , copy.first( k + 8 ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
void HashIndexTest::testMoveCons( )
|
||
|
{
|
||
|
T_HashIndex index( C_SIZE_ , C_SIZE_ , C_SIZE_ );
|
||
|
for ( uint32_t k = 0 ; k < 8 ; k ++ ) {
|
||
|
index.add( k );
|
||
|
}
|
||
|
|
||
|
T_HashIndex copy( std::move( index ) );
|
||
|
for ( uint32_t k = 0 ; k < 8 ; k ++ ) {
|
||
|
CPPUNIT_ASSERT_EQUAL( k , copy.first( k ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , copy.next( k ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , index.first( k ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void HashIndexTest::testMoveAss( )
|
||
|
{
|
||
|
T_HashIndex index( C_SIZE_ , C_SIZE_ , C_SIZE_ );
|
||
|
for ( uint32_t k = 0 ; k < 8 ; k ++ ) {
|
||
|
index.add( k );
|
||
|
}
|
||
|
|
||
|
T_HashIndex copy;
|
||
|
copy = std::move( index );
|
||
|
for ( uint32_t k = 0 ; k < 8 ; k ++ ) {
|
||
|
CPPUNIT_ASSERT_EQUAL( k , copy.first( k ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , copy.next( k ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , index.first( k ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------*/
|
||
|
|
||
|
void HashIndexTest::testSwap( )
|
||
|
{
|
||
|
T_HashIndex index1 , index2;
|
||
|
for ( uint32_t k = 0 ; k < 8 ; k ++ ) {
|
||
|
index1.add( k );
|
||
|
index2.add( k + 8 );
|
||
|
}
|
||
|
swap( index1 , index2 );
|
||
|
for ( uint32_t k = 0 ; k < 8 ; k ++ ) {
|
||
|
CPPUNIT_ASSERT_EQUAL( k , index2.first( k ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , index2.next( k ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( k , index1.first( k + 8 ) );
|
||
|
CPPUNIT_ASSERT_EQUAL( T_HashIndex::INVALID_INDEX , index1.next( k + 8 ) );
|
||
|
}
|
||
|
}
|