From: khizmax Date: Wed, 23 Dec 2015 21:26:21 +0000 (+0300) Subject: Fixed FeldmanHashSet X-Git-Tag: v2.1.0~14 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=ed2f764f442bb37e91335dfb81d4f9f95f9f6155;p=libcds.git Fixed FeldmanHashSet --- diff --git a/cds/algo/split_bitstring.h b/cds/algo/split_bitstring.h index 605d00ec..82cf1242 100644 --- a/cds/algo/split_bitstring.h +++ b/cds/algo/split_bitstring.h @@ -44,7 +44,7 @@ namespace cds { namespace algo { /// Initializises the splitter with reference to \p h and start bit offset \p nBitOffset split_bitstring( bitstring const& h, size_t nBitOffset ) : m_ptr( reinterpret_cast( &h ) + nBitOffset / c_nBitPerInt ) - , m_pos( nBitOffset % c_nBitPerInt ) + , m_pos( nBitOffset ) , m_first( reinterpret_cast(&h)) # ifdef _DEBUG , m_last( m_first + c_nHashSize ) @@ -90,6 +90,7 @@ namespace cds { namespace algo { else if ( nBits == nRest ) { result = *m_ptr >> ( c_nBitPerInt - nRest ); ++m_ptr; + assert( m_pos % c_nBitPerInt == 0 ); } else { uint_type const lsb = *m_ptr >> ( c_nBitPerInt - nRest ); @@ -139,6 +140,12 @@ namespace cds { namespace algo { return reinterpret_cast( m_first ); } + /// Returns current bit offset from beginning of bit-string + size_t bit_offset() const + { + return m_pos; + } + private: //@cond uint_type const* m_ptr; ///< current position in the hash diff --git a/cds/intrusive/details/feldman_hashset_base.h b/cds/intrusive/details/feldman_hashset_base.h index 4d1087c4..766b6683 100644 --- a/cds/intrusive/details/feldman_hashset_base.h +++ b/cds/intrusive/details/feldman_hashset_base.h @@ -370,7 +370,6 @@ namespace cds { namespace intrusive { struct traverse_data { hash_splitter splitter; array_node * pArr; - size_t nOffset; size_t nSlot; size_t nHeight; @@ -384,7 +383,6 @@ namespace cds { namespace intrusive { { splitter.reset(); pArr = arr.head(); - nOffset = arr.metrics().head_node_size_log; nSlot = splitter.cut( arr.metrics().head_node_size_log ); nHeight = 1; } @@ -419,7 +417,6 @@ namespace cds { namespace intrusive { pos.nSlot = pos.splitter.cut( metrics().array_node_size_log ); assert( pos.nSlot < metrics().array_node_size ); pos.pArr = to_array(slot.ptr()); - pos.nOffset += metrics().array_node_size_log; ++pos.nHeight; } else if (slot.bits() == flag_array_converting) { @@ -554,9 +551,7 @@ namespace cds { namespace intrusive { bool expand_slot( traverse_data& pos, node_ptr current) { - bool bRet = expand_slot( pos.pArr, pos.nSlot, current, pos.nOffset ); - //pos.reset( *this ); - return bRet; + return expand_slot( pos.pArr, pos.nSlot, current, pos.splitter.bit_offset()); } private: diff --git a/cds/intrusive/feldman_hashset_rcu.h b/cds/intrusive/feldman_hashset_rcu.h index ab6782a5..0f3bc27f 100644 --- a/cds/intrusive/feldman_hashset_rcu.h +++ b/cds/intrusive/feldman_hashset_rcu.h @@ -1139,6 +1139,7 @@ namespace cds { namespace intrusive { if ( pos.pArr->nodes[pos.nSlot].load( memory_model::memory_order_acquire ) != slot ) { // slot value has been changed - retry stats().onSlotChanged(); + continue; } else if ( slot.ptr() && cmp( hash, hash_accessor()(*slot.ptr())) == 0 ) { // item found diff --git a/cds/intrusive/impl/feldman_hashset.h b/cds/intrusive/impl/feldman_hashset.h index 24e77804..ad617404 100644 --- a/cds/intrusive/impl/feldman_hashset.h +++ b/cds/intrusive/impl/feldman_hashset.h @@ -1072,6 +1072,7 @@ namespace cds { namespace intrusive { if (guard.protect( pos.pArr->nodes[pos.nSlot], [](node_ptr p) -> value_type * { return p.ptr(); }) != slot) { // slot value has been changed - retry stats().onSlotChanged(); + continue; } else if (slot.ptr() && cmp(hash, hash_accessor()(*slot.ptr())) == 0) { // item found @@ -1098,7 +1099,7 @@ namespace cds { namespace intrusive { stats().onSlotChanged(); } else if (slot.ptr()) { - if (cmp(hash, hash_accessor()(*slot.ptr())) == 0 && pred(*slot.ptr())) { + if ( cmp(hash, hash_accessor()(*slot.ptr())) == 0 && pred(*slot.ptr())) { // item found - replace it with nullptr if ( pos.pArr->nodes[pos.nSlot].compare_exchange_strong(slot, node_ptr(nullptr), memory_model::memory_order_acquire, atomics::memory_order_relaxed)) { // slot is guarded by HP