scoped_node_ptr pNode( alloc_node( key ));
std::pair<bool, bool> ret = base_class::update_at( refHead, *pNode,
- [&f]( bool bNew, node_type& node, node_type& ){ f( bNew, node.m_Data ); },
+ [&f]( bool bNew, node_type& node, node_type& ){ f( bNew, node.m_Data ); },
bAllowInsert );
if ( ret.first && ret.second )
pNode.release();
<ClCompile Include="..\..\..\tests\unit\map2\map_insdelfind_cuckoo.cpp" />\r
<ClCompile Include="..\..\..\tests\unit\map2\map_insdelfind_ellentree.cpp" />\r
<ClCompile Include="..\..\..\tests\unit\map2\map_insdelfind_michael.cpp" />\r
- <ClCompile Include="..\..\..\tests\unit\map2\map_insdelfind_refinable.cpp" />\r
+ <ClCompile Include="..\..\..\tests\unit\map2\map_insdelfind_multilevelhashmap.cpp" />\r
<ClCompile Include="..\..\..\tests\unit\map2\map_insdelfind_skip.cpp" />\r
<ClCompile Include="..\..\..\tests\unit\map2\map_insdelfind_split.cpp" />\r
<ClCompile Include="..\..\..\tests\unit\map2\map_insdelfind_std.cpp" />\r
tests/unit/map2/map_insdel_string_striped.cpp \
tests/unit/map2/map_insdel_string_std.cpp \
tests/unit/map2/map_insdelfind.cpp \
+ tests/unit/map2/map_insdelfind_bronsonavltree.cpp \
+ tests/unit/map2/map_insdelfind_cuckoo.cpp \
+ tests/unit/map2/map_insdelfind_ellentree.cpp \
tests/unit/map2/map_insdelfind_michael.cpp \
- tests/unit/map2/map_insdelfind_split.cpp \
+ tests/unit/map2/map_insdelfind_multilevelhashmap.cpp \
tests/unit/map2/map_insdelfind_skip.cpp \
- tests/unit/map2/map_insdelfind_ellentree.cpp \
- tests/unit/map2/map_insdelfind_bronsonavltree.cpp \
+ tests/unit/map2/map_insdelfind_split.cpp \
tests/unit/map2/map_insdelfind_striped.cpp \
- tests/unit/map2/map_insdelfind_refinable.cpp \
- tests/unit/map2/map_insdelfind_cuckoo.cpp \
tests/unit/map2/map_insdelfind_std.cpp \
tests/unit/map2/map_delodd.cpp \
tests/unit/map2/map_delodd_michael.cpp \
DeletePercentage=5\r
Duration=7\r
PrintGCStateFlag=1\r
+# *** Cuckoo map properties\r
+CuckooInitialSize=256\r
+CuckooProbesetSize=8\r
+# 0 - use default\r
+CuckooProbesetThreshold=0 \r
+# *** MultiLevelHashMap properties\r
+MultiLevelMapHeadBits=8\r
+MultiLevelMapArrayBits=4\r
\r
[Map_DelOdd]\r
MapSize=50000\r
DeletePercentage=5\r
Duration=15\r
PrintGCStateFlag=1\r
+# *** Cuckoo map properties\r
+CuckooInitialSize=1024\r
+CuckooProbesetSize=16\r
+# 0 - use default\r
+CuckooProbesetThreshold=0 \r
+# *** MultiLevelHashMap properties\r
+MultiLevelMapHeadBits=8\r
+MultiLevelMapArrayBits=4\r
\r
[Map_DelOdd]\r
MapSize=500000\r
DeletePercentage=5\r
Duration=15\r
PrintGCStateFlag=1\r
+# *** Cuckoo map properties\r
+CuckooInitialSize=1024\r
+CuckooProbesetSize=16\r
+# 0 - use default\r
+CuckooProbesetThreshold=0 \r
+# *** MultiLevelHashMap properties\r
+MultiLevelMapHeadBits=10\r
+MultiLevelMapArrayBits=4\r
+\r
\r
[Map_DelOdd]\r
MapSize=1000000\r
map_insdel_string_striped.cpp
map_insdel_string_std.cpp
map_insdelfind.cpp
+ map_insdelfind_bronsonavltree.cpp
+ map_insdelfind_cuckoo.cpp
+ map_insdelfind_ellentree.cpp
map_insdelfind_michael.cpp
- map_insdelfind_split.cpp
+ map_insdelfind_multilevelhashmap.cpp
map_insdelfind_skip.cpp
- map_insdelfind_ellentree.cpp
- map_insdelfind_bronsonavltree.cpp
+ map_insdelfind_split.cpp
map_insdelfind_striped.cpp
- map_insdelfind_refinable.cpp
- map_insdelfind_cuckoo.cpp
map_insdelfind_std.cpp
map_delodd.cpp
map_delodd_michael.cpp
namespace map2 {
CPPUNIT_TEST_SUITE_REGISTRATION( Map_InsDelFind );
- size_t Map_InsDelFind::c_nInitialMapSize = 500000;
- size_t Map_InsDelFind::c_nThreadCount = 8;
- size_t Map_InsDelFind::c_nMaxLoadFactor = 8;
- unsigned int Map_InsDelFind::c_nInsertPercentage = 5;
- unsigned int Map_InsDelFind::c_nDeletePercentage = 5;
- unsigned int Map_InsDelFind::c_nDuration = 30;
- bool Map_InsDelFind::c_bPrintGCState = true;
-
void Map_InsDelFind::setUpParams( const CppUnitMini::TestCfg& cfg )
{
- c_nInitialMapSize = cfg.getSizeT("InitialMapSize", c_nInitialMapSize );
+ c_nMapSize = cfg.getSizeT("InitialMapSize", c_nMapSize );
c_nThreadCount = cfg.getSizeT("ThreadCount", c_nThreadCount );
c_nMaxLoadFactor = cfg.getSizeT("MaxLoadFactor", c_nMaxLoadFactor );
c_nInsertPercentage = cfg.getUInt("InsertPercentage", c_nInsertPercentage );
c_nDuration = cfg.getUInt("Duration", c_nDuration );
c_bPrintGCState = cfg.getBool("PrintGCStateFlag", c_bPrintGCState );
+ c_nCuckooInitialSize = cfg.getSizeT("CuckooInitialSize", c_nCuckooInitialSize);
+ c_nCuckooProbesetSize = cfg.getSizeT("CuckooProbesetSize", c_nCuckooProbesetSize);
+ c_nCuckooProbesetThreshold = cfg.getSizeT("CuckooProbesetThreshold", c_nCuckooProbesetThreshold);
+
+ c_nMultiLevelMap_HeadBits = cfg.getSizeT("MultiLevelMapHeadBits", c_nMultiLevelMap_HeadBits);
+ c_nMultiLevelMap_ArrayBits = cfg.getSizeT("MultiLevelMapArrayBits", c_nMultiLevelMap_ArrayBits);
+
if ( c_nThreadCount == 0 )
- c_nThreadCount = cds::OS::topology::processor_count() * 2;
+ c_nThreadCount = std::thread::hardware_concurrency() * 2;
CPPUNIT_ASSERT( c_nInsertPercentage + c_nDeletePercentage <= 100 );
std::fill( pFirst, pLast, do_find );
shuffle( m_arrShuffle, pLast );
}
-
- void Map_InsDelFind::myRun(const char *in_name, bool invert /*= false*/)
- {
- setUpParams( m_Cfg.get( "Map_InsDelFind" ));
-
- run_MichaelMap(in_name, invert);
- run_SplitList(in_name, invert);
- run_SkipListMap(in_name, invert);
- run_EllenBinTreeMap(in_name, invert);
- run_BronsonAVLTreeMap(in_name, invert);
- run_StripedMap(in_name, invert);
- run_RefinableMap(in_name, invert);
- run_CuckooMap(in_name, invert);
- run_StdMap(in_name, invert);
-
- endTestCase();
- }
} // namespace map2
namespace map2 {
-# define TEST_MAP(IMPL, C, X) void C::X() { test<map_type<IMPL, key_type, value_type>::X >(); }
-# define TEST_MAP_NOLF(IMPL, C, X) void C::X() { test_nolf<map_type<IMPL, key_type, value_type>::X >(); }
-# define TEST_MAP_EXTRACT(IMPL, C, X) TEST_MAP(IMPL, C, X)
-# define TEST_MAP_NOLF_EXTRACT(IMPL, C, X) TEST_MAP_NOLF(IMPL, C, X)
+#define TEST_CASE(TAG, X) void X();
class Map_InsDelFind: public CppUnitMini::TestCase
{
- static size_t c_nInitialMapSize; // initial map size
- static size_t c_nThreadCount; // thread count
- static size_t c_nMaxLoadFactor; // maximum load factor
- static unsigned int c_nInsertPercentage;
- static unsigned int c_nDeletePercentage;
- static unsigned int c_nDuration; // test duration, seconds
- static bool c_bPrintGCState;
+ public:
+ size_t c_nMapSize = 500000; // initial map size
+ size_t c_nThreadCount = 8; // thread count
+ size_t c_nMaxLoadFactor = 8; // maximum load factor
+ unsigned int c_nInsertPercentage = 5;
+ unsigned int c_nDeletePercentage = 5;
+ unsigned int c_nDuration = 30; // test duration, seconds
+ bool c_bPrintGCState = true;
+
+ size_t c_nCuckooInitialSize = 1024;// initial size for CuckooMap
+ size_t c_nCuckooProbesetSize = 16; // CuckooMap probeset size (only for list-based probeset)
+ size_t c_nCuckooProbesetThreshold = 0; // CUckooMap probeset threshold (o - use default)
+
+ size_t c_nMultiLevelMap_HeadBits = 10;
+ size_t c_nMultiLevelMap_ArrayBits = 4;
+
+ size_t c_nLoadFactor = 2; // current load factor
public:
enum actions
typedef size_t key_type;
typedef size_t value_type;
- template <class MAP>
+ template <class Map>
class WorkThread: public CppUnitMini::TestThread
{
- MAP& m_Map;
+ Map& m_Map;
virtual WorkThread * clone()
{
size_t m_nFindFailed;
public:
- WorkThread( CppUnitMini::ThreadPool& pool, MAP& rMap )
+ WorkThread( CppUnitMini::ThreadPool& pool, Map& rMap )
: CppUnitMini::TestThread( pool )
, m_Map( rMap )
{}
virtual void init() { cds::threading::Manager::attachThread() ; }
virtual void fini() { cds::threading::Manager::detachThread() ; }
+ typedef std::pair< key_type const, value_type > map_value_type;
+
+ struct update_functor {
+ template <typename Q>
+ void operator()( bool /*bNew*/, map_value_type& /*cur*/, Q const& /*val*/ )
+ {}
+
+ // MultiLevelHashMap
+ void operator()( map_value_type& /*cur*/, map_value_type * /*old*/)
+ {}
+
+ // MichaelMap
+ void operator()( bool /*bNew*/, map_value_type& /*cur*/ )
+ {}
+
+ // BronsonAVLTreeMap
+ void operator()( bool /*bNew*/, key_type /*key*/, value_type& /*val*/ )
+ {}
+ };
+
virtual void test()
{
- MAP& rMap = m_Map;
+ Map& rMap = m_Map;
m_nInsertSuccess =
m_nInsertFailed =
actions * pAct = getTest().m_arrShuffle;
unsigned int i = 0;
- size_t const nNormalize = size_t(-1) / (c_nInitialMapSize * 2);
+ size_t const nNormalize = size_t(-1) / (getTest().c_nMapSize * 2);
size_t nRand = 0;
while ( !time_elapsed() ) {
size_t n = nRand / nNormalize;
switch ( pAct[i] ) {
case do_find:
- if ( rMap.find( n ))
+ if ( rMap.contains( n ))
++m_nFindSuccess;
else
++m_nFindFailed;
break;
case do_insert:
- if ( rMap.insert( n, n ))
- ++m_nInsertSuccess;
- else
- ++m_nInsertFailed;
+ if ( n % 2 ) {
+ if ( rMap.insert( n, n ))
+ ++m_nInsertSuccess;
+ else
+ ++m_nInsertFailed;
+ }
+ else {
+ if ( rMap.update(n, update_functor(), true ).first )
+ ++m_nInsertSuccess;
+ else
+ ++m_nInsertFailed;
+ }
break;
case do_delete:
if ( rMap.erase( n ))
};
protected:
- template <class MAP>
- void do_test( MAP& testMap )
+ template <class Map>
+ void do_test( Map& testMap )
{
- typedef WorkThread<MAP> work_thread;
+ typedef WorkThread<Map> work_thread;
cds::OS::Timer timer;
// fill map - only odd number
{
std::vector<size_t> arr;
- arr.reserve( c_nInitialMapSize );
- for ( size_t i = 0; i < c_nInitialMapSize; ++i )
+ arr.reserve( c_nMapSize );
+ for ( size_t i = 0; i < c_nMapSize; ++i )
arr.push_back( i * 2 + 1);
shuffle( arr.begin(), arr.end() );
- for ( size_t i = 0; i < c_nInitialMapSize; ++i )
+ for ( size_t i = 0; i < c_nMapSize; ++i )
testMap.insert( arr[i], arr[i] );
}
- CPPUNIT_MSG( " Insert " << c_nInitialMapSize << " items time (single-threaded)=" << timer.duration() );
+ CPPUNIT_MSG( " Insert " << c_nMapSize << " items time (single-threaded)=" << timer.duration() );
timer.reset();
CppUnitMini::ThreadPool pool( *this );
additional_cleanup( testMap );
}
- template <class MAP>
- void test()
+ template <class Map>
+ void run_test()
{
CPPUNIT_MSG( "Thread count=" << c_nThreadCount
- << " initial map size=" << c_nInitialMapSize
+ << " initial map size=" << c_nMapSize
<< " insert=" << c_nInsertPercentage << '%'
<< " delete=" << c_nDeletePercentage << '%'
<< " duration=" << c_nDuration << "s"
);
- for ( size_t nLoadFactor = 1; nLoadFactor <= c_nMaxLoadFactor; nLoadFactor *= 2 ) {
- CPPUNIT_MSG( "Load factor=" << nLoadFactor );
- MAP testMap( c_nInitialMapSize, nLoadFactor );
+ if ( Map::c_bLoadFactorDepended ) {
+ for ( c_nLoadFactor = 1; c_nLoadFactor <= c_nMaxLoadFactor; c_nLoadFactor *= 2 ) {
+ CPPUNIT_MSG( "Load factor=" << c_nLoadFactor );
+ Map testMap( *this );
+ do_test( testMap );
+ if ( c_bPrintGCState )
+ print_gc_state();
+ }
+ }
+ else {
+ Map testMap( *this );
do_test( testMap );
if ( c_bPrintGCState )
print_gc_state();
}
-
- }
-
- template <class MAP>
- void test_nolf()
- {
- CPPUNIT_MSG( "Thread count=" << c_nThreadCount
- << " initial map size=" << c_nInitialMapSize
- << " insert=" << c_nInsertPercentage << '%'
- << " delete=" << c_nDeletePercentage << '%'
- << " duration=" << c_nDuration << "s"
- );
-
- MAP testMap;
- do_test( testMap );
- if ( c_bPrintGCState )
- print_gc_state();
}
void setUpParams( const CppUnitMini::TestCfg& cfg );
- void run_MichaelMap(const char *in_name, bool invert = false);
- void run_SplitList(const char *in_name, bool invert = false);
- void run_StripedMap(const char *in_name, bool invert = false);
- void run_RefinableMap(const char *in_name, bool invert = false);
- void run_CuckooMap(const char *in_name, bool invert = false);
- void run_SkipListMap(const char *in_name, bool invert = false);
- void run_EllenBinTreeMap(const char *in_name, bool invert = false);
- void run_BronsonAVLTreeMap(const char *in_name, bool invert = false);
- void run_StdMap(const char *in_name, bool invert = false);
-
- virtual void myRun(const char *in_name, bool invert = false);
-
# include "map2/map_defs.h"
CDSUNIT_DECLARE_MichaelMap
CDSUNIT_DECLARE_SplitList
CDSUNIT_DECLARE_SkipListMap
CDSUNIT_DECLARE_EllenBinTreeMap
CDSUNIT_DECLARE_BronsonAVLTreeMap
+ CDSUNIT_DECLARE_MultiLevelHashMap
CDSUNIT_DECLARE_StripedMap
CDSUNIT_DECLARE_RefinableMap
CDSUNIT_DECLARE_CuckooMap
CDSUNIT_DECLARE_StdMap
+
+ CPPUNIT_TEST_SUITE(Map_InsDel_int)
+ CDSUNIT_TEST_MichaelMap
+ CDSUNIT_TEST_SplitList
+ CDSUNIT_TEST_SkipListMap
+ CDSUNIT_TEST_EllenBinTreeMap
+ CDSUNIT_TEST_BronsonAVLTreeMap
+ CDSUNIT_TEST_MultiLevelHashMap
+ CDSUNIT_TEST_CuckooMap
+ CDSUNIT_TEST_StripedMap
+ CDSUNIT_TEST_RefinableMap
+ CDSUNIT_TEST_StdMap
+ CPPUNIT_TEST_SUITE_END();
};
} // namespace map2
#include "map2/map_insdelfind.h"
#include "map2/map_type_bronson_avltree.h"
-namespace map2 {
- CDSUNIT_DEFINE_BronsonAVLTreeMap( cc::bronson_avltree::implementation_tag, Map_InsDelFind)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X) void Map_InsDelFind::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
- CPPUNIT_TEST_SUITE_PART( Map_InsDelFind, run_BronsonAVLTreeMap )
- CDSUNIT_TEST_BronsonAVLTreeMap
- CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+ CDSUNIT_DECLARE_BronsonAVLTreeMap
} // namespace map2
#include "map2/map_insdelfind.h"
#include "map2/map_type_cuckoo.h"
-namespace map2 {
- CDSUNIT_DEFINE_CuckooMap(cds::intrusive::cuckoo::implementation_tag, Map_InsDelFind)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X) void Map_InsDelFind::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
- CPPUNIT_TEST_SUITE_PART( Map_InsDelFind, run_CuckooMap )
- CDSUNIT_TEST_CuckooMap
- CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+ CDSUNIT_DECLARE_CuckooMap
} // namespace map2
#include "map2/map_insdelfind.h"
#include "map2/map_type_ellen_bintree.h"
-namespace map2 {
- CDSUNIT_DEFINE_EllenBinTreeMap( cc::ellen_bintree::implementation_tag, Map_InsDelFind)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X) void Map_InsDelFind::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
- CPPUNIT_TEST_SUITE_PART( Map_InsDelFind, run_EllenBinTreeMap )
- CDSUNIT_TEST_EllenBinTreeMap
- CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+ CDSUNIT_DECLARE_EllenBinTreeMap
} // namespace map2
#include "map2/map_insdelfind.h"
#include "map2/map_type_michael.h"
-namespace map2 {
- CDSUNIT_DEFINE_MichaelMap( cc::michael_map::implementation_tag, Map_InsDelFind )
+#undef TEST_CASE
+#define TEST_CASE(TAG, X) void Map_InsDelFind::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
- CPPUNIT_TEST_SUITE_PART( Map_InsDelFind, run_MichaelMap )
- CDSUNIT_TEST_MichaelMap
- CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+ CDSUNIT_DECLARE_MichaelMap
} // namespace map2
--- /dev/null
+//$$CDS-header$$
+
+#include "map2/map_insdelfind.h"
+#include "map2/map_type_multilevel_hashmap.h"
+
+#undef TEST_CASE
+#define TEST_CASE(TAG, X) void Map_InsDelFind::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
+
+namespace map2 {
+ CDSUNIT_DECLARE_MultiLevelHashMap
+} // namespace map2
+++ /dev/null
-//$$CDS-header$$
-
-#include "map2/map_insdelfind.h"
-#include "map2/map_type_striped.h"
-
-namespace map2 {
- CDSUNIT_DEFINE_RefinableMap(cc::striped_set::implementation_tag, Map_InsDelFind)
-
- CPPUNIT_TEST_SUITE_PART( Map_InsDelFind, run_RefinableMap )
- CDSUNIT_TEST_RefinableMap
- CPPUNIT_TEST_SUITE_END_PART()
-} // namespace map2
#include "map2/map_insdelfind.h"
#include "map2/map_type_skip_list.h"
-namespace map2 {
- CDSUNIT_DEFINE_SkipListMap( cc::skip_list::implementation_tag, Map_InsDelFind)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X) void Map_InsDelFind::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
- CPPUNIT_TEST_SUITE_PART( Map_InsDelFind, run_SkipListMap )
- CDSUNIT_TEST_SkipListMap
- CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+ CDSUNIT_DECLARE_SkipListMap
} // namespace map2
#include "map2/map_insdelfind.h"
#include "map2/map_type_split_list.h"
-namespace map2 {
- CDSUNIT_DEFINE_SplitList( cc::split_list::implementation_tag, Map_InsDelFind )
+#undef TEST_CASE
+#define TEST_CASE(TAG, X) void Map_InsDelFind::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
- CPPUNIT_TEST_SUITE_PART( Map_InsDelFind, run_SplitList )
- CDSUNIT_TEST_SplitList
- CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+ CDSUNIT_DECLARE_SplitList
} // namespace map2
#include "map2/map_insdelfind.h"
#include "map2/map_type_std.h"
-namespace map2 {
- CDSUNIT_DEFINE_StdMap( map2::std_implementation_tag, Map_InsDelFind)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X) void Map_InsDelFind::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
- CPPUNIT_TEST_SUITE_PART( Map_InsDelFind, run_StdMap )
- CDSUNIT_TEST_StdMap
- CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+ CDSUNIT_DECLARE_StdMap
} // namespace map2
#include "map2/map_insdelfind.h"
#include "map2/map_type_striped.h"
-namespace map2 {
- CDSUNIT_DEFINE_StripedMap(cc::striped_set::implementation_tag, Map_InsDelFind)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X) void Map_InsDelFind::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
- CPPUNIT_TEST_SUITE_PART( Map_InsDelFind, run_StripedMap )
- CDSUNIT_TEST_StripedMap
- CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+ CDSUNIT_DECLARE_StripedMap
+ CDSUNIT_DECLARE_RefinableMap
} // namespace map2