From a6374ded40a3334668e0c4fd81dc361e118106e4 Mon Sep 17 00:00:00 2001 From: khizmax Date: Tue, 15 Mar 2016 00:31:37 +0300 Subject: [PATCH] Migrated intrusive FeldmanHashSet unit test to gtest framework --- projects/Win/vc14/gtest-set.vcxproj | 6 + projects/Win/vc14/gtest-set.vcxproj.filters | 18 ++ test/unit/set/CMakeLists.txt | 5 + .../set/intrusive_feldman_hashset_rcu_gpb.cpp | 41 +++ .../set/intrusive_feldman_hashset_rcu_gpi.cpp | 41 +++ .../set/intrusive_feldman_hashset_rcu_gpt.cpp | 41 +++ .../set/intrusive_feldman_hashset_rcu_shb.cpp | 45 ++++ .../set/intrusive_feldman_hashset_rcu_sht.cpp | 45 ++++ .../unit/set/test_intrusive_feldman_hashset.h | 54 +--- .../set/test_intrusive_feldman_hashset_hp.h | 54 +++- .../set/test_intrusive_feldman_hashset_rcu.h | 233 ++++++++++++++++++ 11 files changed, 524 insertions(+), 59 deletions(-) create mode 100644 test/unit/set/intrusive_feldman_hashset_rcu_gpb.cpp create mode 100644 test/unit/set/intrusive_feldman_hashset_rcu_gpi.cpp create mode 100644 test/unit/set/intrusive_feldman_hashset_rcu_gpt.cpp create mode 100644 test/unit/set/intrusive_feldman_hashset_rcu_shb.cpp create mode 100644 test/unit/set/intrusive_feldman_hashset_rcu_sht.cpp create mode 100644 test/unit/set/test_intrusive_feldman_hashset_rcu.h diff --git a/projects/Win/vc14/gtest-set.vcxproj b/projects/Win/vc14/gtest-set.vcxproj index 36ac7da7..fb2007f7 100644 --- a/projects/Win/vc14/gtest-set.vcxproj +++ b/projects/Win/vc14/gtest-set.vcxproj @@ -30,6 +30,11 @@ + + + + + @@ -193,6 +198,7 @@ + diff --git a/projects/Win/vc14/gtest-set.vcxproj.filters b/projects/Win/vc14/gtest-set.vcxproj.filters index 776f5fa4..2b8ca4db 100644 --- a/projects/Win/vc14/gtest-set.vcxproj.filters +++ b/projects/Win/vc14/gtest-set.vcxproj.filters @@ -156,6 +156,21 @@ Source Files\intrusive:FeldmanHashSet + + Source Files\intrusive:FeldmanHashSet + + + Source Files\intrusive:FeldmanHashSet + + + Source Files\intrusive:FeldmanHashSet + + + Source Files\intrusive:FeldmanHashSet + + + Source Files\intrusive:FeldmanHashSet + @@ -191,5 +206,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/test/unit/set/CMakeLists.txt b/test/unit/set/CMakeLists.txt index efff233b..3f13b128 100644 --- a/test/unit/set/CMakeLists.txt +++ b/test/unit/set/CMakeLists.txt @@ -6,6 +6,11 @@ set(CDSGTEST_SET_SOURCES ../main.cpp intrusive_feldman_hashset_hp.cpp intrusive_feldman_hashset_dhp.cpp + intrusive_feldman_hashset_rcu_gpb.cpp + intrusive_feldman_hashset_rcu_gpi.cpp + intrusive_feldman_hashset_rcu_gpt.cpp + intrusive_feldman_hashset_rcu_shb.cpp + intrusive_feldman_hashset_rcu_sht.cpp intrusive_michael_lazy_hp.cpp intrusive_michael_lazy_dhp.cpp intrusive_michael_lazy_nogc.cpp diff --git a/test/unit/set/intrusive_feldman_hashset_rcu_gpb.cpp b/test/unit/set/intrusive_feldman_hashset_rcu_gpb.cpp new file mode 100644 index 00000000..35c432e7 --- /dev/null +++ b/test/unit/set/intrusive_feldman_hashset_rcu_gpb.cpp @@ -0,0 +1,41 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include + +#include "test_intrusive_feldman_hashset_rcu.h" + +namespace { + + typedef cds::urcu::general_buffered<> rcu_implementation; + +} // namespace + +INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPB, IntrusiveFeldmanHashSet, rcu_implementation ); diff --git a/test/unit/set/intrusive_feldman_hashset_rcu_gpi.cpp b/test/unit/set/intrusive_feldman_hashset_rcu_gpi.cpp new file mode 100644 index 00000000..e0114f8e --- /dev/null +++ b/test/unit/set/intrusive_feldman_hashset_rcu_gpi.cpp @@ -0,0 +1,41 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include + +#include "test_intrusive_feldman_hashset_rcu.h" + +namespace { + + typedef cds::urcu::general_instant<> rcu_implementation; + +} // namespace + +INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPI, IntrusiveFeldmanHashSet, rcu_implementation ); diff --git a/test/unit/set/intrusive_feldman_hashset_rcu_gpt.cpp b/test/unit/set/intrusive_feldman_hashset_rcu_gpt.cpp new file mode 100644 index 00000000..a152be57 --- /dev/null +++ b/test/unit/set/intrusive_feldman_hashset_rcu_gpt.cpp @@ -0,0 +1,41 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include + +#include "test_intrusive_feldman_hashset_rcu.h" + +namespace { + + typedef cds::urcu::general_threaded<> rcu_implementation; + +} // namespace + +INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPT, IntrusiveFeldmanHashSet, rcu_implementation ); diff --git a/test/unit/set/intrusive_feldman_hashset_rcu_shb.cpp b/test/unit/set/intrusive_feldman_hashset_rcu_shb.cpp new file mode 100644 index 00000000..93e357da --- /dev/null +++ b/test/unit/set/intrusive_feldman_hashset_rcu_shb.cpp @@ -0,0 +1,45 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include + +#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED + +#include "test_intrusive_feldman_hashset_rcu.h" + +namespace { + + typedef cds::urcu::signal_buffered<> rcu_implementation; + +} // namespace + +INSTANTIATE_TYPED_TEST_CASE_P( RCU_SHB, IntrusiveFeldmanHashSet, rcu_implementation ); + +#endif // CDS_URCU_SIGNAL_HANDLING_ENABLED diff --git a/test/unit/set/intrusive_feldman_hashset_rcu_sht.cpp b/test/unit/set/intrusive_feldman_hashset_rcu_sht.cpp new file mode 100644 index 00000000..ecd281af --- /dev/null +++ b/test/unit/set/intrusive_feldman_hashset_rcu_sht.cpp @@ -0,0 +1,45 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include + +#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED + +#include "test_intrusive_feldman_hashset_rcu.h" + +namespace { + + typedef cds::urcu::signal_threaded<> rcu_implementation; + +} // namespace + +INSTANTIATE_TYPED_TEST_CASE_P( RCU_SHT, IntrusiveFeldmanHashSet, rcu_implementation ); + +#endif // CDS_URCU_SIGNAL_HANDLING_ENABLED diff --git a/test/unit/set/test_intrusive_feldman_hashset.h b/test/unit/set/test_intrusive_feldman_hashset.h index 3960161c..bb3ae721 100644 --- a/test/unit/set/test_intrusive_feldman_hashset.h +++ b/test/unit/set/test_intrusive_feldman_hashset.h @@ -39,12 +39,9 @@ // forward declaration namespace cds { namespace intrusive {}} +namespace ci = cds::intrusive; namespace cds_test { - - namespace ci = cds::intrusive; - namespace co = cds::opt; - class intrusive_feldman_hashset: public fixture { public: @@ -218,6 +215,13 @@ namespace cds_test { std::for_each( data.begin(), data.end(), []( value_type& v ) { v.clear_stat(); }); + // get_level_statistics + { + std::vector< typename Set::level_statistics > level_stat; + s.get_level_statistics( level_stat ); + EXPECT_GT( level_stat.size(), 0 ); + } + // erase shuffle( indices.begin(), indices.end() ); for ( auto idx : indices ) { @@ -260,48 +264,6 @@ namespace cds_test { EXPECT_EQ( i.nDisposeCount, 1 ); } - // erase_at( iterator ) - for ( auto& i : data ) { - i.clear_stat(); - ASSERT_TRUE( s.insert( i ) ); - } - ASSERT_FALSE( s.empty() ); - ASSERT_CONTAINER_SIZE( s, nSetSize ); - - for ( auto it = s.begin(); it != s.end(); ++it ) { - ASSERT_TRUE( s.erase_at( it )); - ASSERT_FALSE( s.erase_at( it )); - } - ASSERT_TRUE( s.empty() ); - ASSERT_CONTAINER_SIZE( s, 0 ); - - // Force retiring cycle - Set::gc::force_dispose(); - for ( auto& i : data ) { - EXPECT_EQ( i.nDisposeCount, 1 ); - } - - // erase_at( reverse_iterator ) - for ( auto& i : data ) { - i.clear_stat(); - ASSERT_TRUE( s.insert( i ) ); - } - ASSERT_FALSE( s.empty() ); - ASSERT_CONTAINER_SIZE( s, nSetSize ); - - for ( auto it = s.rbegin(); it != s.rend(); ++it ) { - ASSERT_TRUE( s.erase_at( it ) ); - ASSERT_FALSE( s.erase_at( it ) ); - } - ASSERT_TRUE( s.empty() ); - ASSERT_CONTAINER_SIZE( s, 0 ); - - // Force retiring cycle - Set::gc::force_dispose(); - for ( auto& i : data ) { - EXPECT_EQ( i.nDisposeCount, 1 ); - } - // clear for ( auto& i : data ) { i.clear_stat(); diff --git a/test/unit/set/test_intrusive_feldman_hashset_hp.h b/test/unit/set/test_intrusive_feldman_hashset_hp.h index 81872c9e..17dd9ec9 100644 --- a/test/unit/set/test_intrusive_feldman_hashset_hp.h +++ b/test/unit/set/test_intrusive_feldman_hashset_hp.h @@ -33,14 +33,8 @@ #include "test_intrusive_feldman_hashset.h" -// forward declaration -namespace cds { namespace intrusive {}} - namespace cds_test { - namespace ci = cds::intrusive; - namespace co = cds::opt; - class intrusive_feldman_hashset_hp: public intrusive_feldman_hashset { typedef intrusive_feldman_hashset base_class; @@ -90,13 +84,6 @@ namespace cds_test { ASSERT_TRUE( s.insert( i ) ); } - // get_level_statistics - { - std::vector< ci::feldman_hashset::level_statistics > level_stat; - s.get_level_statistics( level_stat ); - EXPECT_GT( level_stat.size(), 0 ); - } - // get/extract for ( auto idx : indices ) { auto& i = data[idx]; @@ -129,6 +116,47 @@ namespace cds_test { EXPECT_EQ( i.nDisposeCount, 1 ); } + // erase_at( iterator ) + for ( auto& i : data ) { + i.clear_stat(); + ASSERT_TRUE( s.insert( i ) ); + } + ASSERT_FALSE( s.empty() ); + ASSERT_CONTAINER_SIZE( s, nSetSize ); + + for ( auto it = s.begin(); it != s.end(); ++it ) { + ASSERT_TRUE( s.erase_at( it ) ); + ASSERT_FALSE( s.erase_at( it ) ); + } + ASSERT_TRUE( s.empty() ); + ASSERT_CONTAINER_SIZE( s, 0 ); + + // Force retiring cycle + Set::gc::force_dispose(); + for ( auto& i : data ) { + EXPECT_EQ( i.nDisposeCount, 1 ); + } + + // erase_at( reverse_iterator ) + for ( auto& i : data ) { + i.clear_stat(); + ASSERT_TRUE( s.insert( i ) ); + } + ASSERT_FALSE( s.empty() ); + ASSERT_CONTAINER_SIZE( s, nSetSize ); + + for ( auto it = s.rbegin(); it != s.rend(); ++it ) { + ASSERT_TRUE( s.erase_at( it ) ); + ASSERT_FALSE( s.erase_at( it ) ); + } + ASSERT_TRUE( s.empty() ); + ASSERT_CONTAINER_SIZE( s, 0 ); + + // Force retiring cycle + Set::gc::force_dispose(); + for ( auto& i : data ) { + EXPECT_EQ( i.nDisposeCount, 1 ); + } } }; diff --git a/test/unit/set/test_intrusive_feldman_hashset_rcu.h b/test/unit/set/test_intrusive_feldman_hashset_rcu.h new file mode 100644 index 00000000..a8db5437 --- /dev/null +++ b/test/unit/set/test_intrusive_feldman_hashset_rcu.h @@ -0,0 +1,233 @@ +/* + This file is a part of libcds - Concurrent Data Structures library + + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016 + + Source code repo: http://github.com/khizmax/libcds/ + Download: http://sourceforge.net/projects/libcds/files/ + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CDSUNIT_SET_TEST_INTRUSIVE_FELDMAN_HASHSET_RCU_H +#define CDSUNIT_SET_TEST_INTRUSIVE_FELDMAN_HASHSET_RCU_H + +#include "test_intrusive_feldman_hashset.h" + +#include + +namespace ci = cds::intrusive; +namespace co = cds::opt; + +template +class IntrusiveFeldmanHashSet : public cds_test::intrusive_feldman_hashset +{ + typedef cds_test::intrusive_feldman_hashset base_class; + +protected: + typedef cds::urcu::gc rcu_type; + + template + void test( Set& s ) + { + // Precondition: set is empty + // Postcondition: set is empty + + base_class::test( s ); + + ASSERT_TRUE( s.empty() ); + ASSERT_CONTAINER_SIZE( s, 0 ); + + typedef typename Set::value_type value_type; + size_t const nSetSize = std::max( s.head_size() * 2, static_cast(100) ); + + std::vector< value_type > data; + std::vector< size_t> indices; + data.reserve( nSetSize ); + indices.reserve( nSetSize ); + for ( size_t key = 0; key < nSetSize; ++key ) { + data.push_back( value_type( static_cast(key) ) ); + indices.push_back( key ); + } + shuffle( indices.begin(), indices.end() ); + + typename Set::exempt_ptr xp; + value_type * rp; + typedef typename Set::rcu_lock rcu_lock; + + // get/extract from empty set + for ( auto idx : indices ) { + auto& i = data[idx]; + + { + rcu_lock l; + rp = s.get( i.key() ); + ASSERT_TRUE( !rp ); + } + + xp = s.extract( i.key() ); + ASSERT_TRUE( !xp ); + } + + // fill set + for ( auto& i : data ) { + i.nDisposeCount = 0; + ASSERT_TRUE( s.insert( i ) ); + } + + // get/extract + for ( auto idx : indices ) { + auto& i = data[idx]; + + { + rcu_lock l; + EXPECT_EQ( i.nFindCount, 0 ); + rp = s.get( i.key() ); + ASSERT_FALSE( !rp ); + ++rp->nFindCount; + EXPECT_EQ( i.nFindCount, 1 ); + } + + EXPECT_EQ( i.nEraseCount, 0 ); + xp = s.extract( i.key()); + ASSERT_FALSE( !xp ); + ++xp->nEraseCount; + EXPECT_EQ( i.nEraseCount, 1 ); + + xp = s.extract( i.key() ); + ASSERT_TRUE( !xp ); + } + + ASSERT_TRUE( s.empty() ); + ASSERT_CONTAINER_SIZE( s, 0 ); + + // Force retiring cycle + Set::gc::force_dispose(); + for ( auto& i : data ) { + EXPECT_EQ( i.nDisposeCount, 1 ); + } + } + + void SetUp() + { + RCU::Construct(); + cds::threading::Manager::attachThread(); + } + + void TearDown() + { + cds::threading::Manager::detachThread(); + RCU::Destruct(); + } +}; + +TYPED_TEST_CASE_P( IntrusiveFeldmanHashSet ); + +TYPED_TEST_P( IntrusiveFeldmanHashSet, compare ) +{ + typedef typename TestFixture::rcu_type rcu_type; + + struct traits : public ci::feldman_hashset::traits + { + typedef typename TestFixture::hash_accessor hash_accessor; + typedef typename TestFixture::cmp compare; + typedef typename TestFixture::mock_disposer disposer; + }; + + typedef ci::FeldmanHashSet< rcu_type, typename TestFixture::int_item, traits > set_type; + + set_type s; + this->test( s ); +} + +TYPED_TEST_P( IntrusiveFeldmanHashSet, less ) +{ + typedef ci::FeldmanHashSet< typename TestFixture::rcu_type, typename TestFixture::int_item, + typename ci::feldman_hashset::make_traits< + ci::feldman_hashset::hash_accessor< typename TestFixture::hash_accessor > + , ci::opt::less< std::less> + , ci::opt::disposer< typename TestFixture::mock_disposer> + >::type + > set_type; + + set_type s( 5, 2 ); + this->test( s ); +} + +TYPED_TEST_P( IntrusiveFeldmanHashSet, cmpmix ) +{ + struct traits : public ci::feldman_hashset::traits + { + typedef typename TestFixture::hash_accessor hash_accessor; + typedef typename TestFixture::cmp compare; + typedef std::less less; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::simple_item_counter item_counter; + }; + + typedef ci::FeldmanHashSet< typename TestFixture::rcu_type, typename TestFixture::int_item, traits > set_type; + + set_type s( 3, 4 ); + this->test( s ); +} + +TYPED_TEST_P( IntrusiveFeldmanHashSet, backoff ) +{ + struct traits : public ci::feldman_hashset::traits + { + typedef typename TestFixture::hash_accessor hash_accessor; + typedef typename TestFixture::cmp compare; + typedef typename TestFixture::mock_disposer disposer; + typedef cds::backoff::empty back_off; + typedef ci::opt::v::sequential_consistent memory_model; + }; + + typedef ci::FeldmanHashSet< typename TestFixture::rcu_type, typename TestFixture::int_item, traits > set_type; + + set_type s( 8, 3 ); + this->test( s ); +} + +TYPED_TEST_P( IntrusiveFeldmanHashSet, stat ) +{ + struct traits : public ci::feldman_hashset::traits + { + typedef typename TestFixture::hash_accessor hash_accessor; + typedef typename TestFixture::cmp compare; + typedef typename TestFixture::mock_disposer disposer; + typedef ci::feldman_hashset::stat<> stat; + }; + + typedef ci::FeldmanHashSet< typename TestFixture::rcu_type, typename TestFixture::int_item, traits > set_type; + + set_type s( 8, 3 ); + this->test( s ); +} + +// GCC 5: All test names should be written on single line, otherwise a runtime error will be encountered like as +// "No test named can be found in this test case" +REGISTER_TYPED_TEST_CASE_P( IntrusiveFeldmanHashSet, + compare, less, cmpmix, backoff, stat + ); + + +#endif // #ifndef CDSUNIT_SET_TEST_INTRUSIVE_FELDMAN_HASHSET_RCU_H -- 2.34.1