Fixed FeldmanHashSet
authorkhizmax <libcds.dev@gmail.com>
Wed, 23 Dec 2015 21:26:21 +0000 (00:26 +0300)
committerkhizmax <libcds.dev@gmail.com>
Wed, 23 Dec 2015 21:26:21 +0000 (00:26 +0300)
cds/algo/split_bitstring.h
cds/intrusive/details/feldman_hashset_base.h
cds/intrusive/feldman_hashset_rcu.h
cds/intrusive/impl/feldman_hashset.h

index 605d00ec9d8cb6dc941b101cf8ce4a02f988d782..82cf1242635f6faad52a9aa66194290d3cd0506e 100644 (file)
@@ -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<uint_type const*>( &h ) + nBitOffset / c_nBitPerInt )
-            , m_pos( nBitOffset % c_nBitPerInt )
+            , m_pos( nBitOffset )
             , m_first( reinterpret_cast<uint_type const*>(&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<bitstring const *>( 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
index 4d1087c42e0bcc1e83d76581f77f727bd1368070..766b66838a840f3e3eb5dda4ceb9b67a978d8260 100644 (file)
@@ -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:
index ab6782a5d04828b9c30f40f5866a62522dcd00f6..0f3bc27f47abfb55e734ee68440cc4c9867dfcb9 100644 (file)
@@ -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
index 24e77804e852a42e2649b899c68fa160b2f6c2eb..ad61740469d8794d1a8460b41ba33a44480daace 100644 (file)
@@ -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