#include #include using namespace ebcl; 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 ) ); } }