-//$$CDS-header$$
+/*
+ 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 "cppunit/thread.h"
#include "set2/set_type.h"
namespace {
struct key_thread
{
- size_t nKey;
- size_t nThread;
+ uint32_t nKey;
+ uint16_t nThread;
+ uint16_t pad_;
key_thread( size_t key, size_t threadNo )
- : nKey( key )
- , nThread( threadNo )
+ : nKey( static_cast<uint32_t>(key))
+ , nThread( static_cast<uint16_t>(threadNo))
+ , pad_(0)
{}
key_thread()
size_t c_nCuckooProbesetSize = 16; // CuckooSet probeset size (only for list-based probeset)
size_t c_nCuckooProbesetThreshold = 0; // CUckooSet probeset threshold (0 - use default)
+ size_t c_nFeldmanSet_HeadBits = 10;
+ size_t c_nFeldmanSet_ArrayBits = 4;
+
size_t c_nLoadFactor = 2;
std::vector<size_t> m_arrData;
protected:
- typedef CppUnitMini::TestCase Base;
typedef key_thread key_type;
typedef size_t value_type;
template <typename Q>
void operator()( bool /*bNew*/, key_value_pair const&, Q const& )
{}
+
+ void operator()(key_value_pair& /*cur*/, key_value_pair * /*prev*/)
+ {}
};
public:
size_t m_nInsertSuccess;
virtual void init() { cds::threading::Manager::attachThread() ; }
virtual void fini() { cds::threading::Manager::detachThread() ; }
+ template <typename SetType, bool>
+ struct eraser {
+ static bool erase( SetType& s, size_t key, size_t /*thread*/)
+ {
+ return s.erase_with( key, key_less() );
+ }
+ };
+
+ template <typename SetType>
+ struct eraser<SetType, true> {
+ static bool erase(SetType& s, size_t key, size_t thread)
+ {
+ return s.erase( key_type(key, thread));
+ }
+ };
+
virtual void test()
{
Set& rSet = m_Set;
std::vector<size_t>& arrData = getTest().m_arrData;
if ( m_nThreadNo & 1 ) {
- for ( size_t k = 0; k < nInsThreadCount; ++k ) {
- for ( size_t i = 0; i < arrData.size(); ++i ) {
- if ( arrData[i] & 1 ) {
- if ( rSet.erase_with( arrData[i], key_less() ))
+ for (size_t i = 0; i < arrData.size(); ++i) {
+ if (arrData[i] & 1) {
+ for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+ if ( eraser<Set, Set::c_bEraseExactKey>::erase( rSet, arrData[i], k ))
++m_nDeleteSuccess;
else
++m_nDeleteFailed;
}
}
else {
- for ( size_t k = 0; k < nInsThreadCount; ++k ) {
- for ( size_t i = arrData.size() - 1; i > 0; --i ) {
- if ( arrData[i] & 1 ) {
- if ( rSet.erase_with( arrData[i], key_less() ))
+ for (size_t i = arrData.size() - 1; i > 0; --i) {
+ if (arrData[i] & 1) {
+ for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+ if (eraser<Set, Set::c_bEraseExactKey>::erase(rSet, arrData[i], k))
++m_nDeleteSuccess;
else
++m_nDeleteFailed;
virtual void init() { cds::threading::Manager::attachThread() ; }
virtual void fini() { cds::threading::Manager::detachThread() ; }
+ template <typename SetType, bool>
+ struct extractor {
+ static typename SetType::guarded_ptr extract(SetType& s, size_t key, size_t /*thread*/)
+ {
+ return s.extract_with( key, key_less());
+ }
+ };
+
+ template <typename SetType>
+ struct extractor<SetType, true> {
+ static typename SetType::guarded_ptr extract(SetType& s, size_t key, size_t thread)
+ {
+ return s.extract( key_type(key, thread));
+ }
+ };
+
virtual void test()
{
Set& rSet = m_Set;
size_t const nInsThreadCount = getTest().c_nInsThreadCount;
if ( m_nThreadNo & 1 ) {
- for ( size_t k = 0; k < nInsThreadCount; ++k ) {
- for ( size_t i = 0; i < arrData.size(); ++i ) {
- if ( arrData[i] & 1 ) {
- gp = rSet.extract_with( arrData[i], key_less());
+ for ( size_t i = 0; i < arrData.size(); ++i ) {
+ if (arrData[i] & 1) {
+ for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+ gp = extractor<Set, Set::c_bEraseExactKey>::extract( rSet, arrData[i], k );
if ( gp )
++m_nExtractSuccess;
else
}
}
else {
- for ( size_t k = 0; k < nInsThreadCount; ++k ) {
- for ( size_t i = arrData.size() - 1; i > 0; --i ) {
- if ( arrData[i] & 1 ) {
- gp = rSet.extract_with( arrData[i], key_less());
+ for (size_t i = arrData.size() - 1; i > 0; --i) {
+ if (arrData[i] & 1) {
+ for ( size_t k = 0; k < nInsThreadCount; ++k ) {
+ gp = extractor<Set, Set::c_bEraseExactKey>::extract( rSet, arrData[i], k);
if ( gp )
++m_nExtractSuccess;
else
virtual void init() { cds::threading::Manager::attachThread() ; }
virtual void fini() { cds::threading::Manager::detachThread() ; }
+ template <typename SetType, bool>
+ struct extractor {
+ static typename SetType::exempt_ptr extract(SetType& s, size_t key, size_t /*thread*/)
+ {
+ return s.extract_with(key, key_less());
+ }
+ };
+
+ template <typename SetType>
+ struct extractor<SetType, true> {
+ static typename SetType::exempt_ptr extract(SetType& s, size_t key, size_t thread)
+ {
+ return s.extract(key_type(key, thread));
+ }
+ };
+
virtual void test()
{
Set& rSet = m_Set;
size_t const nInsThreadCount = getTest().c_nInsThreadCount;
if ( m_nThreadNo & 1 ) {
- for ( size_t k = 0; k < nInsThreadCount; ++k ) {
- for ( size_t i = 0; i < arrData.size(); ++i ) {
- if ( arrData[i] & 1 ) {
+ for (size_t i = 0; i < arrData.size(); ++i) {
+ if (arrData[i] & 1) {
+ for ( size_t k = 0; k < nInsThreadCount; ++k ) {
if ( Set::c_bExtractLockExternal ) {
typename Set::rcu_lock l;
- xp = rSet.extract_with( arrData[i], key_less() );
+ xp = extractor<Set, Set::c_bEraseExactKey>::extract( rSet, arrData[i], k);
if ( xp )
++m_nExtractSuccess;
else
++m_nExtractFailed;
}
else {
- xp = rSet.extract_with( arrData[i], key_less() );
+ xp = extractor<Set, Set::c_bEraseExactKey>::extract(rSet, arrData[i], k);
if ( xp )
++m_nExtractSuccess;
else
}
}
else {
- for ( size_t k = 0; k < nInsThreadCount; ++k ) {
- for ( size_t i = arrData.size() - 1; i > 0; --i ) {
- if ( arrData[i] & 1 ) {
+ for (size_t i = arrData.size() - 1; i > 0; --i) {
+ if (arrData[i] & 1) {
+ for ( size_t k = 0; k < nInsThreadCount; ++k ) {
if ( Set::c_bExtractLockExternal ) {
typename Set::rcu_lock l;
- xp = rSet.extract_with( arrData[i], key_less() );
+ xp = extractor<Set, Set::c_bEraseExactKey>::extract(rSet, arrData[i], k);
if ( xp )
++m_nExtractSuccess;
else
++m_nExtractFailed;
}
else {
- xp = rSet.extract_with( arrData[i], key_less() );
+ xp = extractor<Set, Set::c_bEraseExactKey>::extract(rSet, arrData[i], k);
if ( xp )
++m_nExtractSuccess;
else
}
void setUpParams( const CppUnitMini::TestCfg& cfg );
+ virtual void endTestCase();
# include "set2/set_defs.h"
CDSUNIT_DECLARE_MichaelSet
CDSUNIT_DECLARE_SkipListSet
CDSUNIT_DECLARE_EllenBinTreeSet
CDSUNIT_DECLARE_CuckooSet
+ CDSUNIT_DECLARE_FeldmanHashSet_fixed
+ CDSUNIT_DECLARE_FeldmanHashSet_city
CPPUNIT_TEST_SUITE_(Set_DelOdd, "Map_DelOdd")
CDSUNIT_TEST_MichaelSet
CDSUNIT_TEST_SplitList
CDSUNIT_TEST_SkipListSet
CDSUNIT_TEST_EllenBinTreeSet
+ CDSUNIT_TEST_FeldmanHashSet_fixed
+ CDSUNIT_TEST_FeldmanHashSet_city
CDSUNIT_TEST_CuckooSet
-
- //CDSUNIT_TEST_MultiLevelHashSet // the test is not suitable
CPPUNIT_TEST_SUITE_END();
};
} // namespace set2