Added clear() to SplitList<nogc>
authorkhizmax <libcds.dev@gmail.com>
Sun, 13 Mar 2016 08:01:36 +0000 (11:01 +0300)
committerkhizmax <libcds.dev@gmail.com>
Sun, 13 Mar 2016 08:01:36 +0000 (11:01 +0300)
Doc fixed

cds/intrusive/details/split_list_base.h
cds/intrusive/lazy_list_nogc.h
cds/intrusive/michael_list_nogc.h
cds/intrusive/michael_set.h
cds/intrusive/michael_set_nogc.h
cds/intrusive/split_list.h
cds/intrusive/split_list_nogc.h

index 2259fe76b98257a46dd6d365538aecf442ad83cf..40b5f102ae33a83c7ea37792151b2260a3b7d981 100644 (file)
@@ -781,7 +781,7 @@ namespace cds { namespace intrusive {
                     opt::compare< key_compare >
                     ,opt::disposer< wrapped_disposer >
                     ,opt::boundary_node_type< splitlist_node_type >
-                >::type    result;
+                >::type result;
             };
 
             template <typename OrderedList, bool IsConst>
@@ -836,7 +836,6 @@ namespace cds { namespace intrusive {
                         ++m_itCur;
                 }
 
-
                 value_ptr operator ->() const
                 {
                     return m_itCur.operator->();
index c2434d224802d55f769c40bd3b30577ff584b286..cd31be7b7809bb67cdfdf32364a1dbf551462bf9 100644 (file)
@@ -777,6 +777,25 @@ namespace cds { namespace intrusive {
             return pPred->m_pNext.load(memory_model::memory_order_acquire) == pCur;
         }
 
+        // for split-list
+        template <typename Predicate>
+        void erase_for( Predicate pred )
+        {
+            node_type * pPred = nullptr;
+            node_type * pHead = m_Head.m_pNext.load( memory_model::memory_order_relaxed );
+
+            while ( pHead != &m_Tail ) {
+                node_type * p = pHead->m_pNext.load( memory_model::memory_order_relaxed );
+                if ( pred( *node_traits::to_value_ptr( pHead ))) {
+                    assert( pPred != nullptr );
+                    pPred->m_pNext.store( p, memory_model::memory_order_relaxed );
+                    dispose_node( pHead, disposer() );
+                }
+                else
+                    pPred = pHead;
+                pHead = p;
+            }
+        }
         //@endcond
     };
 
index 9a539b510ef3a58844e656d504033cb46f41474e..de48a4bf4fb09acf3b4c431e38bac3000fadf3d5 100644 (file)
@@ -666,6 +666,25 @@ namespace cds { namespace intrusive {
                 pCur = pNext;
             }
         }
+
+        // for split-list
+        template <typename Predicate>
+        void erase_for( Predicate pred )
+        {
+            node_type * pPred = nullptr;
+            node_type * pHead = m_pHead.load( memory_model::memory_order_relaxed );
+            while ( pHead ) {
+                node_type * p = pHead->m_pNext.load( memory_model::memory_order_relaxed );
+                if ( pred( *node_traits::to_value_ptr( pHead ))) {
+                    assert( pPred != nullptr );
+                    pPred->m_pNext.store( p, memory_model::memory_order_relaxed );
+                    dispose_node( pHead, disposer());
+                }
+                else
+                    pPred = pHead;
+                pHead = p;
+            }
+        }
         //@endcond
     };
 
index c91202ea7359ad940d7350d640779627a7535cff..16cac8f94339d7edd697082de28cd9ac7fb3e5f7 100644 (file)
@@ -267,7 +267,6 @@ namespace cds { namespace intrusive {
         /// Count of hazard pointer required for the algorithm
         static CDS_CONSTEXPR const size_t c_nHazardPtrCount = ordered_list::c_nHazardPtrCount;
 
-
     protected:
         item_counter    m_ItemCounter;   ///< Item counter
         hash            m_HashFunctor;   ///< Hash functor
index 9de82aae01b6af349b35d8a323ddfe6cba023765..65cdd4f4ac7dff3b289b79269648c11723745463 100644 (file)
@@ -356,9 +356,9 @@ namespace cds { namespace intrusive {
         /**
             The function unlink all items from the set.
             The function is not atomic. It cleans up each bucket and then resets the item counter to zero.
-            If there are a thread that performs insertion while \p clear is working the result is undefined in general case:
+            If there are a thread that performs insertion while \p %clear() is working the result is undefined in general case:
             <tt> empty() </tt> may return \p true but the set may contain item(s).
-            Therefore, \p clear may be used only for debugging purposes.
+            Therefore, \p %clear() may be used only for debugging purposes.
 
             For each item the \p disposer is called after unlinking.
         */
index 1316360f03d15aafc81970921bd052b74641185a..2e461795ba00e7f36147f5f25545369fb22792e6 100644 (file)
@@ -248,6 +248,9 @@ namespace cds { namespace intrusive {
         typedef typename traits::stat              stat;         ///< Internal statistics, see \p spit_list::stat
         typedef typename ordered_list::guarded_ptr guarded_ptr;  ///< Guarded pointer
 
+        /// Count of hazard pointer required
+        static CDS_CONSTEXPR const size_t c_nHazardPtrCount = ordered_list::c_nHazardPtrCount + 4; // +4 - for iterators
+
     protected:
         typedef typename ordered_list::node_type    list_node_type;  ///< Node type as declared in ordered list
         typedef split_list::node<list_node_type>    node_type;       ///< split-list node type
index 3784d5a8dbf5f7c17f27a02fea242978c45dbffb..b93ce4004cb34962cf5d05f770715840bd0508d9 100644 (file)
@@ -119,7 +119,7 @@ namespace cds { namespace intrusive {
         class ordered_list_wrapper: public ordered_list
         {
             typedef ordered_list base_class;
-            typedef typename base_class::auxiliary_head       bucket_head_type;
+            typedef typename base_class::auxiliary_head bucket_head_type;
 
         public:
             list_iterator insert_at_( dummy_node_type * pHead, value_type& val )
@@ -162,6 +162,12 @@ namespace cds { namespace intrusive {
                 bucket_head_type h(static_cast<list_node_type *>(pHead));
                 return base_class::insert_aux_node( h, pNode );
             }
+
+            template <typename Predicate>
+            void erase_for( Predicate pred )
+            {
+                return base_class::erase_for( pred );
+            }
         };
 
         //@endcond
@@ -495,6 +501,23 @@ namespace cds { namespace intrusive {
         }
         //@endcond
 
+
+        /// Clears the set (non-atomic, not thread-safe)
+        /**
+            The function unlink all items from the set.
+            The function is not atomic. It cleans up each bucket and then resets the item counter to zero.
+            If there are a thread that performs insertion while \p %clear() is working the result is undefined in general case:
+            <tt> empty() </tt> may return \p true but the set may contain item(s).
+            Therefore, \p %clear() may be used only for debugging purposes.
+
+            For each item the \p disposer is called after unlinking.
+        */
+        void clear()
+        {
+            m_List.erase_for( []( value_type const& val ) -> bool { return !node_traits::to_node_ptr( val )->is_dummy(); } );
+            m_ItemCounter.reset();
+        }
+
         /// Checks if the set is empty
         /**
             Emptiness is checked by item counting: if item count is zero then the set is empty.