Remove unused vars
[libcds.git] / cds / container / split_list_set.h
index b353cdd701e1f1045fdd46a6157440d906c2b66c..0f79c3a55b95a7c129756d748d313235d385742c 100644 (file)
@@ -16,13 +16,13 @@ namespace cds { namespace container {
         - [2003] Ori Shalev, Nir Shavit "Split-Ordered Lists - Lock-free Resizable Hash Tables"
         - [2008] Nir Shavit "The Art of Multiprocessor Programming"
 
-        See intrusive::SplitListSet for a brief description of the split-list algorithm.
+        See \p intrusive::SplitListSet for a brief description of the split-list algorithm.
 
         Template parameters:
         - \p GC - Garbage collector used
-        - \p T - type stored in the split-list. The type must be default- and copy-constructible.
-        - \p Traits - type traits, default is split_list::type_traits. Instead of declaring split_list::type_traits -based
-            struct you may apply option-based notation with split_list::make_traits metafunction.
+        - \p T - type to be stored in the split-list.
+        - \p Traits - type traits, default is \p split_list::traits. Instead of declaring \p split_list::traits -based
+            struct you may apply option-based notation with \p split_list::make_traits metafunction.
 
         There are the specializations:
         - for \ref cds_urcu_desc "RCU" - declared in <tt>cd/container/split_list_set_rcu.h</tt>,
@@ -32,9 +32,11 @@ namespace cds { namespace container {
 
         \par Usage
 
-        You should decide what garbage collector you want, and what ordered list you want to use. Split-ordered list
-        is original data structure based on an ordered list. Suppose, you want construct split-list set based on gc::DHP GC
-        and LazyList as ordered list implementation. So, you beginning your program with following include:
+        You should decide what garbage collector you want, and what ordered list you want to use as a base. Split-ordered list
+        is original data structure based on an ordered list.
+
+        Suppose, you want construct split-list set based on \p gc::DHP GC
+        and \p LazyList as ordered list implementation. So, you beginning your program with following include:
         \code
         #include <cds/container/lazy_list_dhp.h>
         #include <cds/container/split_list_set.h>
@@ -54,7 +56,7 @@ namespace cds { namespace container {
         Note that we define several function in <tt>foo_hash</tt> and <tt>foo_less</tt> functors for different argument types since we want call our \p %SplitListSet
         object by the key of type <tt>int</tt> and by the value of type <tt>foo</tt>.
 
-        The second attention: instead of using \p %LazyList in \p %SplitListSet traits we use a tag <tt>cds::contaner::lazy_list_tag</tt> for the lazy list.
+        The second attention: instead of using \p %LazyList in \p %SplitListSet traits we use a tag \p cds::contaner::lazy_list_tag for the lazy list.
         The split-list requires significant support from underlying ordered list class and it is not good idea to dive you
         into deep implementation details of split-list and ordered list interrelations. The tag paradigm simplifies split-list interface.
 
@@ -73,13 +75,13 @@ namespace cds { namespace container {
         };
 
         // SplitListSet traits
-        struct foo_set_traits: public cc::split_list::type_traits
+        struct foo_set_traits: public cc::split_list::traits
         {
-            typedef cc::lazy_list_tag   ordered_list    ;   // what type of ordered list we want to use
-            typedef foo_hash            hash            ;   // hash functor for our data stored in split-list set
+            typedef cc::lazy_list_tag   ordered_list; // what type of ordered list we want to use
+            typedef foo_hash            hash;         // hash functor for our data stored in split-list set
 
             // Type traits for our LazyList class
-            struct ordered_list_traits: public cc::lazy_list::type_traits
+            struct ordered_list_traits: public cc::lazy_list::traits
             {
                 typedef foo_less less   ;   // use our foo_less as comparator to order list nodes
             };
@@ -88,20 +90,20 @@ namespace cds { namespace container {
 
         Now you are ready to declare our set class based on \p %SplitListSet:
         \code
-        typedef cc::SplitListSet< cds::gc::PTB, foo, foo_set_traits > foo_set;
+        typedef cc::SplitListSet< cds::gc::DHP, foo, foo_set_traits > foo_set;
         \endcode
 
-        You may use the modern option-based declaration instead of classic type-traits-based one:
+        You may use the modern option-based declaration instead of classic traits-based one:
         \code
         typedef cc:SplitListSet<
-            cs::gc::PTB             // GC used
+            cs::gc::DHP             // GC used
             ,foo                    // type of data stored
             ,cc::split_list::make_traits<      // metafunction to build split-list traits
-                cc::split_list::ordered_list<cc::lazy_list_tag>     // tag for underlying ordered list implementation
+                cc::split_list::ordered_list<cc::lazy_list_tag>  // tag for underlying ordered list implementation
                 ,cc::opt::hash< foo_hash >               // hash functor
                 ,cc::split_list::ordered_list_traits<    // ordered list traits desired
-                    cc::lazy_list::make_traits<    // metafunction to build lazy list traits
-                        cc::opt::less< foo_less >           // less-based compare functor
+                    cc::lazy_list::make_traits<          // metafunction to build lazy list traits
+                        cc::opt::less< foo_less >        // less-based compare functor
                     >::type
                 >
             >::type
@@ -112,16 +114,15 @@ namespace cds { namespace container {
 
         Now, the set of type \p foo_set is ready to use in your program.
 
-        Note that in this example we show only mandatory type_traits parts, optional ones is the default and they are inherited
-        from cds::container::split_list::type_traits.
-        The <b>cds</b> library contains many other options for deep tuning of behavior of the split-list and
-        ordered-list containers.
+        Note that in this example we show only mandatory \p traits parts, optional ones is the default and they are inherited
+        from \p cds::container::split_list::traits.
+        There are many other options for deep tuning the split-list and ordered-list containers.
     */
     template <
         class GC,
         class T,
 #ifdef CDS_DOXYGEN_INVOKED
-        class Traits = split_list::type_traits
+        class Traits = split_list::traits
 #else
         class Traits
 #endif
@@ -140,15 +141,16 @@ namespace cds { namespace container {
         //@endcond
 
     public:
-        typedef Traits                            options         ; ///< \p Traits template argument
-        typedef typename maker::gc                gc              ; ///< Garbage collector
-        typedef typename maker::value_type        value_type      ; ///< type of value stored in the list
-        typedef typename maker::ordered_list      ordered_list    ; ///< Underlying ordered list class
+        typedef GC      gc;         ///< Garbage collector
+        typedef T       value_type; ///< Type of vlue to be stored in split-list
+        typedef Traits  traits;     ///< \p Traits template argument
+        typedef typename maker::ordered_list ordered_list; ///< Underlying ordered list class
         typedef typename base_class::key_comparator key_comparator; ///< key compare functor
 
         /// Hash functor for \p %value_type and all its derivatives that you use
-        typedef typename base_class::hash           hash;
-        typedef typename base_class::item_counter   item_counter  ;   ///< Item counter type
+        typedef typename base_class::hash         hash;
+        typedef typename base_class::item_counter item_counter; ///< Item counter type
+        typedef typename base_class::stat         stat; ///< Internal statistics
 
     protected:
         //@cond
@@ -168,6 +170,17 @@ namespace cds { namespace container {
             return cxx_node_allocator().New( v );
         }
 
+        template <typename... Args>
+        static node_type * alloc_node( Args&&... args )
+        {
+            return cxx_node_allocator().MoveNew( std::forward<Args>( args )... );
+        }
+
+        static void free_node( node_type * pNode )
+        {
+            cxx_node_allocator().Delete( pNode );
+        }
+
         template <typename Q, typename Func>
         bool find_( Q& val, Func f )
         {
@@ -177,21 +190,11 @@ namespace cds { namespace container {
         template <typename Q, typename Less, typename Func>
         bool find_with_( Q& val, Less pred, Func f )
         {
+            CDS_UNUSED( pred );
             return base_class::find_with( val, typename maker::template predicate_wrapper<Less>::type(),
                 [&f]( node_type& item, Q& val ) { f(item.m_Value, val) ; } );
         }
 
-        template <typename... Args>
-        static node_type * alloc_node( Args&&... args )
-        {
-            return cxx_node_allocator().MoveNew( std::forward<Args>(args)...);
-        }
-
-        static void free_node( node_type * pNode )
-        {
-            cxx_node_allocator().Delete( pNode );
-        }
-
         struct node_disposer {
             void operator()( node_type * pNode )
             {
@@ -209,7 +212,6 @@ namespace cds { namespace container {
                 p.release();
                 return true;
             }
-
             return false;
         }
 
@@ -305,8 +307,8 @@ namespace cds { namespace container {
         /// Initializes split-ordered list of default capacity
         /**
             The default capacity is defined in bucket table constructor.
-            See intrusive::split_list::expandable_bucket_table, intrusive::split_list::static_bucket_table
-            which selects by intrusive::split_list::dynamic_bucket_table option.
+            See \p intrusive::split_list::expandable_bucket_table, \p intrusive::split_list::static_bucket_table
+            which selects by \p split_list::dynamic_bucket_table option.
         */
         SplitListSet()
             : base_class()
@@ -314,8 +316,8 @@ namespace cds { namespace container {
 
         /// Initializes split-ordered list
         SplitListSet(
-            size_t nItemCount           ///< estimate average of item count
-            , size_t nLoadFactor = 1    ///< load factor - average item count per bucket. Small integer up to 8, default is 1.
+            size_t nItemCount           ///< estimated average of item count
+            , size_t nLoadFactor = 1    ///< the load factor - average item count per bucket. Small integer up to 8, default is 1.
             )
             : base_class( nItemCount, nLoadFactor )
         {}
@@ -350,13 +352,23 @@ namespace cds { namespace container {
         /// Returns a forward const iterator addressing the first element in a set
         const_iterator begin() const
         {
-            return const_iterator( base_class::begin() );
+            return cbegin();
+        }
+        /// Returns a forward const iterator addressing the first element in a set
+        const_iterator cbegin() const
+        {
+            return const_iterator( base_class::cbegin() );
         }
 
         /// Returns an const iterator that addresses the location succeeding the last element in a set
         const_iterator end() const
         {
-            return const_iterator( base_class::end() );
+            return cend();
+        }
+        /// Returns an const iterator that addresses the location succeeding the last element in a set
+        const_iterator cend() const
+        {
+            return const_iterator( base_class::cend() );
         }
 
     public:
@@ -388,10 +400,13 @@ namespace cds { namespace container {
             \code
                 void func( value_type& val );
             \endcode
-            where \p val is the item inserted. User-defined functor \p f should guarantee that during changing
-            \p val no any other changes could be made on this set's item by concurrent threads.
-            The user-defined functor is called only if the inserting is success. It may be passed by reference
-            using \p std::ref
+            where \p val is the item inserted.
+
+            The user-defined functor is called only if the inserting is success.
+
+            @warning For \ref cds_intrusive_MichaelList_hp "MichaelList" as the bucket see \ref cds_intrusive_item_creating "insert item troubleshooting".
+            \ref cds_intrusive_LazyList_hp "LazyList" provides exclusive access to inserted item and does not require any node-level
+            synchronization.
         */
         template <typename Q, typename Func>
         bool insert( Q const& val, Func f )
@@ -405,7 +420,7 @@ namespace cds { namespace container {
             return false;
         }
 
-        /// Inserts data of type \p %value_type constructed with <tt>std::forward<Args>(args)...</tt>
+        /// Inserts data of type \p value_type created from \p args
         /**
             Returns \p true if inserting successful, \p false otherwise.
         */
@@ -437,14 +452,15 @@ namespace cds { namespace container {
             - \p item - item of the set
             - \p val - argument \p val passed into the \p ensure function
 
-            The functor may change non-key fields of the \p item; however, \p func must guarantee
-            that during changing no any other modifications could be made on this item by concurrent threads.
-
-            You may pass \p func argument by reference using \p std::ref
+            The functor may change non-key fields of the \p item.
 
             Returns <tt> std::pair<bool, bool> </tt> where \p first is true if operation is successfull,
             \p second is true if new item has been added or \p false if the item with \p key
             already is in the set.
+
+            @warning For \ref cds_intrusive_MichaelList_hp "MichaelList" as the bucket see \ref cds_intrusive_item_creating "insert item troubleshooting".
+            \ref cds_intrusive_LazyList_hp "LazyList" provides exclusive access to inserted item and does not require any node-level
+            synchronization.
         */
         template <typename Q, typename Func>
         std::pair<bool, bool> ensure( Q const& val, Func func )
@@ -485,6 +501,7 @@ namespace cds { namespace container {
         template <typename Q, typename Less>
         bool erase_with( Q const& key, Less pred )
         {
+            CDS_UNUSED( pred );
             return base_class::erase_with( key, typename maker::template predicate_wrapper<Less>::type() );
         }
 
@@ -500,9 +517,8 @@ namespace cds { namespace container {
                 void operator()(value_type const& val);
             };
             \endcode
-            The functor may be passed by reference using <tt>boost:ref</tt>
 
-            Since the key of SplitListSet's \p value_type is not explicitly specified,
+            Since the key of split-list \p value_type is not explicitly specified,
             template parameter \p Q defines the key type searching in the list.
             The list item comparator should be able to compare the values of the type \p value_type
             and the type \p Q.
@@ -525,6 +541,7 @@ namespace cds { namespace container {
         template <typename Q, typename Less, typename Func>
         bool erase_with( Q const& key, Less pred, Func f )
         {
+            CDS_UNUSED( pred );
             return base_class::erase_with( key, typename maker::template predicate_wrapper<Less>::type(),
                 [&f](node_type& node) { f( node.m_Value ); } );
         }
@@ -576,40 +593,45 @@ namespace cds { namespace container {
             return extract_with_( dest.guard(), key, pred );
         }
 
-        /// Finds the key \p val
+        /// Finds the key \p key
         /** \anchor cds_nonintrusive_SplitListSet_find_func
 
-            The function searches the item with key equal to \p val and calls the functor \p f for item found.
+            The function searches the item with key equal to \p key and calls the functor \p f for item found.
             The interface of \p Func functor is:
             \code
             struct functor {
-                void operator()( value_type& item, Q& val );
+                void operator()( value_type& item, Q& key );
             };
             \endcode
-            where \p item is the item found, \p val is the <tt>find</tt> function argument.
-
-            You may pass \p f argument by reference using \p std::ref.
+            where \p item is the item found, \p key is the <tt>find</tt> function argument.
 
             The functor may change non-key fields of \p item. Note that the functor is only guarantee
             that \p item cannot be disposed during functor is executing.
             The functor does not serialize simultaneous access to the set's \p item. If such access is
             possible you must provide your own synchronization schema on item level to exclude unsafe item modifications.
 
-            The \p val argument is non-const since it can be used as \p f functor destination i.e., the functor
+            The \p key argument is non-const since it can be used as \p f functor destination i.e., the functor
             may modify both arguments.
 
             Note the hash functor specified for class \p Traits template parameter
             should accept a parameter of type \p Q that can be not the same as \p value_type.
 
-            The function returns \p true if \p val is found, \p false otherwise.
+            The function returns \p true if \p key is found, \p false otherwise.
         */
         template <typename Q, typename Func>
-        bool find( Q& val, Func f )
+        bool find( Q& key, Func f )
+        {
+            return find_( key, f );
+        }
+        //@cond
+        template <typename Q, typename Func>
+        bool find( Q const& key, Func f )
         {
-            return find_( val, f );
+            return find_( key, f );
         }
+        //@endcond
 
-        /// Finds the key \p val using \p pred predicate for searching
+        /// Finds the key \p key using \p pred predicate for searching
         /**
             The function is an analog of \ref cds_nonintrusive_SplitListSet_find_func "find(Q&, Func)"
             but \p pred is used for key comparing.
@@ -617,70 +639,34 @@ namespace cds { namespace container {
             \p Less must imply the same element order as the comparator used for building the set.
         */
         template <typename Q, typename Less, typename Func>
-        bool find_with( Q& val, Less pred, Func f )
-        {
-            return find_with_( val, pred, f );
-        }
-
-        /// Finds the key \p val
-        /** \anchor cds_nonintrusive_SplitListSet_find_cfunc
-
-            The function searches the item with key equal to \p val and calls the functor \p f for item found.
-            The interface of \p Func functor is:
-            \code
-            struct functor {
-                void operator()( value_type& item, Q const& val );
-            };
-            \endcode
-            where \p item is the item found, \p val is the <tt>find</tt> function argument.
-
-            You may pass \p f argument by reference using \p std::ref.
-
-            The functor may change non-key fields of \p item. Note that the functor is only guarantee
-            that \p item cannot be disposed during functor is executing.
-            The functor does not serialize simultaneous access to the set's \p item. If such access is
-            possible you must provide your own synchronization schema on item level to exclude unsafe item modifications.
-
-            Note the hash functor specified for class \p Traits template parameter
-            should accept a parameter of type \p Q that can be not the same as \p value_type.
-
-            The function returns \p true if \p val is found, \p false otherwise.
-        */
-        template <typename Q, typename Func>
-        bool find( Q const& val, Func f )
+        bool find_with( Q& key, Less pred, Func f )
         {
-            return find_( val, f );
+            return find_with_( key, pred, f );
         }
-
-        /// Finds the key \p val using \p pred predicate for searching
-        /**
-            The function is an analog of \ref cds_nonintrusive_SplitListSet_find_cfunc "find(Q const&, Func)"
-            but \p pred is used for key comparing.
-            \p Less functor has the interface like \p std::less.
-            \p Less must imply the same element order as the comparator used for building the set.
-        */
+        //@cond
         template <typename Q, typename Less, typename Func>
-        bool find_with( Q const& val, Less pred, Func f )
+        bool find_with( Q const& key, Less pred, Func f )
         {
-            return find_with_( val, pred, f );
+            return find_with_( key, pred, f );
         }
+        //@endcond
 
-        /// Finds the key \p val
+        /// Finds the key \p key
         /** \anchor cds_nonintrusive_SplitListSet_find_val
 
-            The function searches the item with key equal to \p val
+            The function searches the item with key equal to \p key
             and returns \p true if it is found, and \p false otherwise.
 
             Note the hash functor specified for class \p Traits template parameter
             should accept a parameter of type \p Q that can be not the same as \ref value_type.
         */
         template <typename Q>
-        bool find( Q const& val )
+        bool find( Q const& key )
         {
-            return base_class::find( val );
+            return base_class::find( key );
         }
 
-        /// Finds the key \p val using \p pred predicate for searching
+        /// Finds the key \p key using \p pred predicate for searching
         /**
             The function is an analog of \ref cds_nonintrusive_SplitListSet_find_val "find(Q const&)"
             but \p pred is used for key comparing.
@@ -688,9 +674,10 @@ namespace cds { namespace container {
             \p Less must imply the same element order as the comparator used for building the set.
         */
         template <typename Q, typename Less>
-        bool find_with( Q const& val, Less pred )
+        bool find_with( Q const& key, Less pred )
         {
-            return base_class::find_with( val, typename maker::template predicate_wrapper<Less>::type() );
+            CDS_UNUSED( pred );
+            return base_class::find_with( key, typename maker::template predicate_wrapper<Less>::type() );
         }
 
         /// Finds the key \p key and return the item found
@@ -741,11 +728,7 @@ namespace cds { namespace container {
             return get_with_( ptr.guard(), key, pred );
         }
 
-        /// Clears the set (non-atomic)
-        /**
-            The function unlink all items from the set.
-            The function is not atomic and not lock-free and should be used for debugging only.
-        */
+        /// Clears the set (not atomic)
         void clear()
         {
             base_class::clear();
@@ -767,6 +750,12 @@ namespace cds { namespace container {
             return base_class::size();
         }
 
+        /// Returns internal statistics
+        stat const& statistics() const
+        {
+            return base_class::statistics();
+        }
+
     protected:
         //@cond
         using base_class::extract_;
@@ -775,12 +764,14 @@ namespace cds { namespace container {
         template <typename Q, typename Less>
         bool extract_with_( typename gc::Guard& guard, Q const& key, Less pred )
         {
+            CDS_UNUSED( pred );
             return base_class::extract_with_( guard, key, typename maker::template predicate_wrapper<Less>::type() );
         }
 
         template <typename Q, typename Less>
         bool get_with_( typename gc::Guard& guard, Q const& key, Less pred )
         {
+            CDS_UNUSED( pred );
             return base_class::get_with_( guard, key, typename maker::template predicate_wrapper<Less>::type() );
         }