#include <cds/intrusive/split_list_rcu.h>
#include <cds/container/details/make_split_list_set.h>
-#include <cds/details/functor_wrapper.h>
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 RCU - one of \ref cds_urcu_gc "RCU type"
- - \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 of the value 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 can apply option-based notation with \p split_list::make_traits metafunction.
<b>Iterators</b>
The class supports a forward iterator (\ref iterator and \ref const_iterator).
- The iteration is ordered.
+ The iteration is unordered.
You may iterate over split-list set items only under RCU lock.
Only in this case the iterator is thread-safe since
while RCU is locked any set's item cannot be reclaimed.
- The requirement of RCU lock during iterating means that deletion of the elements (i.e. \ref erase)
- is not possible.
-
@warning The iterator object cannot be passed between threads
\warning Due to concurrent nature of skip-list set it is not guarantee that you can iterate
bool operator !=(iterator const& i ) const;
};
\endcode
- Note, the iterator object returned by \ref end, \p cend member functions points to \p NULL and should not be dereferenced.
+ Note, the iterator object returned by \p end(), \p cend() member functions points to \p nullptr and should not be dereferenced.
\par Usage
You should decide what garbage collector you want, and what ordered list you want to use. Split-ordered list
- is an original data structure based on an ordered list. Suppose, you want construct split-list set based on cds::urcu::general_buffered<> GC
- and LazyList as ordered list implementation. So, you beginning your program with following include:
+ is an original data structure based on an ordered list. Suppose, you want construct split-list set based on \p cds::urcu::general_buffered<> GC
+ and \p LazyList as ordered list implementation. So, you beginning your program with following include:
\code
#include <cds/urcu/general_buffered.h>
#include <cds/container/lazy_list_rcu.h>
- then, the header for RCU-based split-list set <tt>cds/container/split_list_set_rcu.h</tt>.
Now, you should declare traits for split-list set. The main parts of traits are a hash functor for the set and a comparing functor for ordered list.
- 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>.
+ Note that we define several function in \p foo_hash and \p foo_less functors for different argument types since we want call our \p %SplitListSet
+ object by the key of type \p int and by the value of type \p foo.
- The second attention: instead of using LazyList in 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 \p cds::contaner::lazy_list_tag 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.
};
// 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
// 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
};
,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::opt::hash< foo_hash > // hash functor
- ,cc::split_list::ordered_list_traits< // ordered list traits desired
+ ,cc::split_list::ordered_list_traits< // ordered list traits
cc::lazy_list::make_traits< // metafunction to build lazy list traits
- cc::opt::less< foo_less > // less-based compare functor
+ cc::opt::less< foo_less > // less-based compare functor
>::type
>
>::type
> foo_set;
\endcode
- In case of option-based declaration using split_list::make_traits metafunction
+ In case of option-based declaration using \p split_list::make_traits metafunction
the struct \p foo_set_traits is not required.
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 container::split_list::traits.
+ There are many other options for deep tuning of the split-list and ordered-list containers.
*/
template <
class RCU,
class T,
#ifdef CDS_DOXYGEN_INVOKED
- class Traits = split_list::type_traits
+ class Traits = split_list::traits
#else
class Traits
#endif
//@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 cds::urcu::gc< RCU > gc; ///< RCU-based garbage collector
+ typedef T value_type; ///< Type of value to be storedin the set
+ 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 \ref 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::item_counter item_counter; ///< Item counter type
+ typedef typename base_class::stat stat; ///< Internal statistics
typedef typename base_class::rcu_lock rcu_lock ; ///< RCU scoped lock
/// Group of \p extract_xxx functions require external locking if underlying ordered list requires that
- static CDS_CONSTEXPR_CONST bool c_bExtractLockExternal = base_class::c_bExtractLockExternal;
+ static CDS_CONSTEXPR const bool c_bExtractLockExternal = base_class::c_bExtractLockExternal;
protected:
//@cond
public:
/// pointer to extracted node
- typedef cds::urcu::exempt_ptr< gc, node_type, value_type, typename maker::ordered_list_traits::disposer > exempt_ptr;
+ using exempt_ptr = cds::urcu::exempt_ptr< gc, node_type, value_type, typename maker::ordered_list_traits::disposer >;
protected:
//@cond
-
- template <typename Q>
- static node_type * alloc_node(Q const& v )
- {
- return cxx_node_allocator().New( v );
- }
-
template <typename Q, typename Func>
bool find_( Q& val, Func f )
{
-# ifdef CDS_CXX11_LAMBDA_SUPPORT
- return base_class::find( val, [&f]( node_type& item, Q& val ) { cds::unref(f)(item.m_Value, val) ; } );
-# else
- find_functor_wrapper<Func> fw(f);
- return base_class::find( val, cds::ref(fw) );
-# endif
+ return base_class::find( val, [&f]( node_type& item, Q& val ) { f(item.m_Value, val) ; } );
}
template <typename Q, typename Less, typename Func>
bool find_with_( Q& val, Less pred, Func f )
{
-# ifdef CDS_CXX11_LAMBDA_SUPPORT
+ CDS_UNUSED( pred );
return base_class::find_with( val, typename maker::template predicate_wrapper<Less>::type(),
- [&f]( node_type& item, Q& val ) { cds::unref(f)(item.m_Value, val) ; } );
-# else
- find_functor_wrapper<Func> fw(f);
- return base_class::find_with( val, typename maker::template predicate_wrapper<Less>::type(), cds::ref(fw) );
-# endif
+ [&f]( node_type& item, Q& val ) { f(item.m_Value, val) ; } );
}
+ template <typename Q>
+ static node_type * alloc_node( Q const& v )
+ {
+ return cxx_node_allocator().New( v );
+ }
-# ifdef CDS_EMPLACE_SUPPORT
template <typename... Args>
static node_type * alloc_node( Args&&... args )
{
return cxx_node_allocator().MoveNew( std::forward<Args>(args)...);
}
-# endif
static void free_node( node_type * pNode )
{
return false;
}
-
- //@endcond
-
- protected:
- //@cond
-# ifndef CDS_CXX11_LAMBDA_SUPPORT
- template <typename Func>
- class insert_functor_wrapper: protected cds::details::functor_wrapper<Func>
- {
- typedef cds::details::functor_wrapper<Func> base_class;
- public:
- insert_functor_wrapper( Func f ): base_class(f) {}
-
- void operator()(node_type& node)
- {
- base_class::get()( node.m_Value );
- }
- };
-
- template <typename Func, typename Q>
- class ensure_functor_wrapper: protected cds::details::functor_wrapper<Func>
- {
- typedef cds::details::functor_wrapper<Func> base_class;
- Q const& m_val;
- public:
- ensure_functor_wrapper( Func f, Q const& v ): base_class(f), m_val(v) {}
-
- void operator()( bool bNew, node_type& item, node_type const& /*val*/ )
- {
- base_class::get()( bNew, item.m_Value, m_val );
- }
- };
-
- template <typename Func>
- class find_functor_wrapper: protected cds::details::functor_wrapper<Func>
- {
- typedef cds::details::functor_wrapper<Func> base_class;
- public:
- find_functor_wrapper( Func f ): base_class(f) {}
-
- template <typename Q>
- void operator()( node_type& item, Q& val )
- {
- base_class::get()( item.m_Value, val );
- }
- };
-
- struct empty_find_functor
- {
- template <typename Q>
- void operator()( node_type&, Q& )
- {}
- };
-
- template <typename Func>
- class erase_functor_wrapper: protected cds::details::functor_wrapper<Func>
- {
- typedef cds::details::functor_wrapper<Func> base_class;
- public:
- erase_functor_wrapper( Func f ): base_class( f ) {}
-
- void operator()(node_type& node)
- {
- base_class::get()( node.m_Value );
- }
- };
-# endif // ifndef CDS_CXX11_LAMBDA_SUPPORT
//@endcond
protected:
/// 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 container::split_list::dynamic_bucket_table option.
*/
SplitListSet()
: base_class()
/// Initializes split-ordered list
SplitListSet(
- size_t nItemCount ///< estimate average of item count
+ size_t nItemCount ///< estimated average of item count
, size_t nLoadFactor = 1 ///< load factor - average item count per bucket. Small integer up to 8, default is 1.
)
: base_class( nItemCount, nLoadFactor )
/// 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:
\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 <tt>boost::ref</tt>
+ The user-defined functor is called only if the inserting is success.
The function applies RCU lock internally.
*/
template <typename Q, typename Func>
- bool insert( Q const& val, Func f )
+ bool insert( Q const& key, Func f )
{
- scoped_node_ptr pNode( alloc_node( val ));
+ scoped_node_ptr pNode( alloc_node( key ));
-# ifdef CDS_CXX11_LAMBDA_SUPPORT
- if ( base_class::insert( *pNode, [&f](node_type& node) { cds::unref(f)( node.m_Value ) ; } ))
-# else
- insert_functor_wrapper<Func> fw(f);
- if ( base_class::insert( *pNode, cds::ref(fw) ) )
-# endif
- {
+ if ( base_class::insert( *pNode, [&f](node_type& node) { f( node.m_Value ) ; } )) {
pNode.release();
return true;
}
return false;
}
-# ifdef CDS_EMPLACE_SUPPORT
- /// 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.
The function applies RCU lock internally.
-
- @note This function is available only for compiler that supports
- variadic template and move semantics.
*/
template <typename... Args>
bool emplace( Args&&... args )
{
return insert_node( alloc_node( std::forward<Args>(args)...));
}
-# endif
- /// Ensures that the \p item exists in the set
+ /// Ensures that the \p val exists in the set
/**
The operation performs inserting or changing data with lock-free manner.
If the \p val key not found in the set, then the new item created from \p val
is inserted into the set. Otherwise, the functor \p func is called with the item found.
- The functor \p Func should be a function with signature:
- \code
- void func( bool bNew, value_type& item, const Q& val );
- \endcode
- or a functor:
+ The functor \p Func signature is:
\code
struct my_functor {
void operator()( bool bNew, value_type& item, const Q& val );
with arguments:
- \p bNew - \p true if the item has been inserted, \p false otherwise
- \p item - item of the set
- - \p val - argument \p val passed into the \p ensure function
+ - \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 <tt>boost::ref</tt>.
-
The function applies RCU lock internally.
Returns <tt> std::pair<bool, bool> </tt> where \p first is true if operation is successfull,
{
scoped_node_ptr pNode( alloc_node( val ));
-# ifdef CDS_CXX11_LAMBDA_SUPPORT
std::pair<bool, bool> bRet = base_class::ensure( *pNode,
[&func, &val]( bool bNew, node_type& item, node_type const& /*val*/ ) {
- cds::unref(func)( bNew, item.m_Value, val );
+ func( bNew, item.m_Value, val );
} );
-# else
- ensure_functor_wrapper<Func, Q> fw( func, val );
- std::pair<bool, bool> bRet = base_class::ensure( *pNode, cds::ref(fw) );
-# endif
-
if ( bRet.first && bRet.second )
pNode.release();
return bRet;
/// Deletes \p key from the set
/** \anchor cds_nonintrusive_SplitListSet_rcu_erase_val
- Since the key of SplitListSet's item type \p value_type is not explicitly specified,
- template parameter \p Q defines the key type searching in the list.
+ Template parameter of type \p Q defines the key type searching in the list.
The set item comparator should be able to compare the values of type \p value_type
and the type \p Q.
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() );
}
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,
- template parameter \p Q defines the key type searching in the list.
+ Template parameter of type \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.
template <typename Q, typename Func>
bool erase( Q const& key, Func f )
{
-# ifdef CDS_CXX11_LAMBDA_SUPPORT
- return base_class::erase( key, [&f](node_type& node) { cds::unref(f)( node.m_Value ); } );
-# else
- erase_functor_wrapper<Func> fw( f );
- return base_class::erase( key, cds::ref(fw) );
-# endif
+ return base_class::erase( key, [&f](node_type& node) { f( node.m_Value ); } );
}
/// Deletes the item from the set using \p pred predicate for searching
template <typename Q, typename Less, typename Func>
bool erase_with( Q const& key, Less pred, Func f )
{
-# ifdef CDS_CXX11_LAMBDA_SUPPORT
+ CDS_UNUSED( pred );
return base_class::erase_with( key, typename maker::template predicate_wrapper<Less>::type(),
- [&f](node_type& node) { cds::unref(f)( node.m_Value ); } );
-# else
- erase_functor_wrapper<Func> fw( f );
- return base_class::erase_with( key, typename maker::template predicate_wrapper<Less>::type(), cds::ref(fw) );
-# endif
+ [&f](node_type& node) { f( node.m_Value ); } );
}
/// Extracts an item from the set
/** \anchor cds_nonintrusive_SplitListSet_rcu_extract
- The function searches an item with key equal to \p val in the set,
- unlinks it from the set, places item pointer into \p dest argument, and returns \p true.
- If the item with the key equal to \p val is not found the function return \p false.
+ The function searches an item with key equal to \p key in the set,
+ unlinks it from the set, and returns \ref cds::urcu::exempt_ptr "exempt_ptr" pointer to the item found.
+ If the item with the key equal to \p key is not found the function returns an empty \p exempt_ptr.
@note The function does NOT call RCU read-side lock or synchronization,
and does NOT dispose the item found. It just excludes the item from the set
// Now, you can apply extract function
// Note that you must not delete the item found inside the RCU lock
- if ( theSet.extract( p, 10 )) {
+ p = theSet.extract( 10 );
+ if ( p ) {
// do something with p
...
}
\endcode
*/
template <typename Q>
- bool extract( exempt_ptr& dest, Q const& val )
+ exempt_ptr extract( Q const& key )
{
- node_type * pNode = base_class::extract_( val, key_comparator() );
- if ( pNode ) {
- dest = pNode;
- return true;
- }
- return false;
+ return exempt_ptr( base_class::extract_( key, key_comparator() ));
}
/// Extracts an item from the set using \p pred predicate for searching
\p pred must imply the same element order as the comparator used for building the set.
*/
template <typename Q, typename Less>
- bool extract_with( exempt_ptr& dest, Q const& val, Less pred )
+ exempt_ptr extract_with( Q const& key, Less pred )
{
- node_type * pNode = base_class::extract_with_( val, typename maker::template predicate_wrapper<Less>::type());
- if ( pNode ) {
- dest = pNode;
- return true;
- }
- return false;
+ CDS_UNUSED( pred );
+ return exempt_ptr( base_class::extract_with_( key, typename maker::template predicate_wrapper<Less>::type()));
}
- /// Finds the key \p val
+ /// Finds the key \p key
/** \anchor cds_nonintrusive_SplitListSet_rcu_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 <tt>boost::ref</tt> or cds::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
- 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 makes RCU lock internally.
- 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_( val, f );
+ return find_( key, f );
}
+ //@cond
+ template <typename Q, typename Func>
+ bool find( Q const& key, Func 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_rcu_find_func "find(Q&, Func)"
but \p pred is used for key comparing.
\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 )
+ bool find_with( Q& key, Less pred, Func f )
{
- return find_with_( val, pred, f );
+ return find_with_( key, pred, f );
}
-
- /// Find the key \p val
- /** \anchor cds_nonintrusive_SplitListSet_rcu_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 <tt>boost::ref</tt> or cds::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 makes RCU lock internally.
-
- 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 )
- {
- return find_( val, f );
- }
-
- /// Finds the key \p val using \p pred predicate for searching
- /**
- The function is an analog of \ref cds_nonintrusive_SplitListSet_rcu_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_rcu_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
The function makes RCU lock internally.
*/
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_rcu_find_val "find(Q const&)"
but \p pred is used for key comparing.
\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 val and return the item found
+ /// Finds the key \p key and return the item found
/** \anchor cds_nonintrusive_SplitListSet_rcu_get
- The function searches the item with key equal to \p val and returns the pointer to item found.
- If \p val is not found it returns \p NULL.
+ The function searches the item with key equal to \p key and returns the pointer to item found.
+ If \p key is not found it returns \p nullptr.
Note the compare functor should accept a parameter of type \p Q that can be not the same as \p value_type.
\endcode
*/
template <typename Q>
- value_type * get( Q const& val )
+ value_type * get( Q const& key )
{
- node_type * pNode = base_class::get( val );
+ node_type * pNode = base_class::get( key );
return pNode ? &pNode->m_Value : nullptr;
}
- /// Finds the key \p val and return the item found
+ /// Finds the key \p key and return the item found
/**
The function is an analog of \ref cds_nonintrusive_SplitListSet_rcu_get "get(Q const&)"
but \p pred is used for comparing the keys.
\p pred must imply the same element order as the comparator used for building the set.
*/
template <typename Q, typename Less>
- value_type * get_with( Q const& val, Less pred )
+ value_type * get_with( Q const& key, Less pred )
{
- node_type * pNode = base_class::get_with( val, typename maker::template predicate_wrapper<Less>::type());
+ CDS_UNUSED( pred );
+ node_type * pNode = base_class::get_with( key, typename maker::template predicate_wrapper<Less>::type());
return pNode ? &pNode->m_Value : nullptr;
}
- /// 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.
-
- RCU \p synchronize method can be called. RCU should not be locked.
- */
+ /// Clears the set (not atomic)
void clear()
{
base_class::clear();
{
return base_class::size();
}
- };
-
+ /// Returns internal statistics
+ stat const& statistics() const
+ {
+ return base_class::statistics();
+ }
+ };
}} // namespace cds::container
#endif // #ifndef __CDS_CONTAINER_SPLIT_LIST_SET_RCU_H