#ifndef __CDS_CONTAINER_IMPL_SKIP_LIST_MAP_H
#define __CDS_CONTAINER_IMPL_SKIP_LIST_MAP_H
-#include <cds/gc/guarded_ptr.h>
#include <cds/container/details/guarded_ptr_cast.h>
namespace cds { namespace container {
- \p GC - Garbage collector used.
- \p K - type of a key to be stored in the list.
- \p T - type of a value to be stored in the list.
- - \p Traits - type traits. See skip_list::type_traits for explanation.
-
- It is possible to declare option-based list with cds::container::skip_list::make_traits metafunction istead of \p Traits template
- argument.
- Template argument list \p Options of cds::container::skip_list::make_traits metafunction are:
- - opt::compare - key compare functor. No default functor is provided.
- If the option is not specified, the opt::less is used.
- - opt::less - specifies binary predicate used for key comparison. Default is \p std::less<K>.
- - opt::item_counter - the type of item counting feature. Default is \ref atomicity::empty_item_counter that is no item counting.
- - opt::memory_model - C++ memory ordering model. Can be opt::v::relaxed_ordering (relaxed memory model, the default)
- or opt::v::sequential_consistent (sequentially consisnent memory model).
- - skip_list::random_level_generator - random level generator. Can be skip_list::xorshift, skip_list::turbo_pascal or
- user-provided one. See skip_list::random_level_generator option description for explanation.
- Default is \p %skip_list::turbo_pascal.
- - opt::allocator - allocator for skip-list node. Default is \ref CDS_DEFAULT_ALLOCATOR.
- - opt::back_off - back-off strategy used. If the option is not specified, the cds::backoff::Default is used.
- - opt::stat - internal statistics. Available types: skip_list::stat, skip_list::empty_stat (the default)
-
- Like STL map class, %SkipListMap stores its key-value pair as <tt>std:pair< K const, T></tt>.
-
- \warning The skip-list requires up to 67 hazard pointers that may be critical for some GCs for which
+ - \p Traits - map traits, default is \p skip_list::traits
+ It is possible to declare option-based list with \p cds::container::skip_list::make_traits metafunction
+ istead of \p Traits template argument.
+
+ Like STL map class, \p %SkipListMap stores the key-value pair as <tt>std:pair< K const, T></tt>.
+
+ @warning The skip-list requires up to 67 hazard pointers that may be critical for some GCs for which
the guard count is limited (like \p gc::HP). Those GCs should be explicitly initialized with
hazard pointer enough: \code cds::gc::HP myhp( 67 ) \endcode. Otherwise an run-time exception may be raised
when you try to create skip-list object.
- \note There are several specializations of \p %SkipListMap for each \p GC. You should include:
+ @note There are several specializations of \p %SkipListMap for each \p GC. You should include:
- <tt><cds/container/skip_list_map_hp.h></tt> for \p gc::HP garbage collector
- <tt><cds/container/skip_list_map_dhp.h></tt> for \p gc::DHP garbage collector
- <tt><cds/container/skip_list_map_rcu.h></tt> for \ref cds_nonintrusive_SkipListMap_rcu "RCU type"
before end of the map. Therefore, such iteration is more suitable for debugging purpose only
Remember, each iterator object requires 2 additional hazard pointers, that may be
- a limited resource for \p GC like \p gc::HP (for gc::PTB the count of
+ a limited resource for \p GC like \p gc::HP (for gc::DHP the count of
guards is unlimited).
The iterator class supports the following minimalistic interface:
typename Key,
typename T,
#ifdef CDS_DOXYGEN_INVOKED
- typename Traits = skip_list::type_traits
+ typename Traits = skip_list::traits
#else
typename Traits
#endif
#endif
{
//@cond
- typedef details::make_skip_list_map< GC, Key, T, Traits > maker;
+ typedef details::make_skip_list_map< GC, Key, T, Traits > maker;
typedef typename maker::type base_class;
//@endcond
public:
- typedef typename base_class::gc gc ; ///< Garbage collector used
- typedef Key key_type ; ///< Key type
- typedef T mapped_type ; ///< Mapped type
+ typedef GC gc; ///< Garbage collector
+ typedef Key key_type; ///< Key type
+ typedef T mapped_type; ///< Mapped type
+ typedef Traits traits; ///< Map traits
# ifdef CDS_DOXYGEN_INVOKED
- typedef std::pair< K const, T> value_type ; ///< Value type stored in the map
+ typedef std::pair< K const, T> value_type; ///< Key-value pair to be stored in the map
# else
typedef typename maker::value_type value_type;
# endif
- typedef Traits options ; ///< Options specified
- typedef typename base_class::back_off back_off ; ///< Back-off strategy used
- typedef typename options::allocator allocator_type ; ///< Allocator type used for allocate/deallocate the skip-list nodes
- typedef typename base_class::item_counter item_counter ; ///< Item counting policy used
- typedef typename maker::key_comparator key_comparator ; ///< key comparison functor
- typedef typename base_class::memory_model memory_model ; ///< Memory ordering. See cds::opt::memory_model option
- typedef typename options::random_level_generator random_level_generator ; ///< random level generator
- typedef typename options::stat stat ; ///< internal statistics type
+ typedef typename base_class::back_off back_off; ///< Back-off strategy
+ typedef typename traits::allocator allocator_type; ///< Allocator type used for allocate/deallocate the skip-list nodes
+ typedef typename base_class::item_counter item_counter; ///< Item counting policy used
+ typedef typename maker::key_comparator key_comparator; ///< key comparison functor
+ typedef typename base_class::memory_model memory_model; ///< Memory ordering, see \p cds::opt::memory_model
+ typedef typename traits::random_level_generator random_level_generator ; ///< random level generator
+ typedef typename traits::stat stat; ///< internal statistics type
protected:
//@cond
typedef typename maker::node_allocator node_allocator;
typedef std::unique_ptr< node_type, typename maker::node_deallocator > scoped_node_ptr;
-
//@endcond
public:
/// Guarded pointer
- typedef cds::gc::guarded_ptr< gc, node_type, value_type, details::guarded_ptr_cast_set<node_type, value_type> > guarded_ptr;
+ typedef typename gc::template guarded_ptr< node_type, value_type, details::guarded_ptr_cast_set<node_type, value_type> > guarded_ptr;
protected:
//@cond
}
/// Returns a forward const iterator addressing the first element in a map
- //@{
const_iterator begin() const
{
return cbegin();
}
- const_iterator cbegin()
+ /// Returns a forward const iterator addressing the first element in a map
+ const_iterator cbegin() const
{
return const_iterator( base_class::cbegin() );
}
- //@}
/// Returns a forward iterator that addresses the location succeeding the last element in a map.
iterator end()
}
/// Returns a forward const iterator that addresses the location succeeding the last element in a map.
- //@{
const_iterator end() const
{
return cend();
}
- const_iterator cend()
+ /// Returns a forward const iterator that addresses the location succeeding the last element in a map.
+ const_iterator cend() const
{
return const_iterator( base_class::cend() );
}
- //@}
public:
/// Inserts new node with key and default value
The function creates a node with \p key and default value, and then inserts the node created into the map.
Preconditions:
- - The \ref key_type should be constructible from a value of type \p K.
- In trivial case, \p K is equal to \ref key_type.
- - The \ref mapped_type should be default-constructible.
+ - The \p key_type should be constructible from a value of type \p K.
+ In trivial case, \p K is equal to \p key_type.
+ - The \p mapped_type should be default-constructible.
Returns \p true if inserting successful, \p false otherwise.
*/
and then inserts the node created into the map.
Preconditions:
- - The \ref key_type should be constructible from \p key of type \p K.
- - The \ref value_type should be constructible from \p val of type \p V.
+ - The \p key_type should be constructible from \p key of type \p K.
+ - The \p value_type should be constructible from \p val of type \p V.
Returns \p true if \p val is inserted into the set, \p false otherwise.
*/
- <tt>item.first</tt> is a const reference to item's key that cannot be changed.
- <tt>item.second</tt> is a reference to item's value that may be changed.
- The user-defined functor can be passed by reference using \p std::ref
- and it is called only if inserting is successful.
-
- The key_type should be constructible from value of type \p K.
+ \p key_type should be constructible from value of type \p K.
The function allows to split creating of new item into two part:
- create item from \p key;
return false;
}
- /// For key \p key inserts data of type \ref value_type constructed with <tt>std::forward<Args>(args)...</tt>
+ /// For key \p key inserts data of type \p value_type created in-place from <tt>std::forward<Args>(args)...</tt>
/**
Returns \p true if inserting successful, \p false otherwise.
*/
The functor may change any fields of the \p item.second that is \ref value_type.
- You may pass \p func argument by reference using \p std::ref
-
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 list.
+
+ @warning See \ref cds_intrusive_item_creating "insert item troubleshooting"
*/
template <typename K, typename Func>
std::pair<bool, bool> ensure( K const& key, Func func )
template <typename K, typename Less>
bool erase_with( K const& key, Less pred )
{
+ CDS_UNUSED( pred );
return base_class::erase_with( key, cds::details::predicate_wrapper< node_type, Less, typename maker::key_accessor >());
}
void operator()(value_type& item) { ... }
};
\endcode
- The functor may be passed by reference using <tt>boost:ref</tt>
Return \p true if key is found and deleted, \p false otherwise
*/
template <typename K, typename Less, typename Func>
bool erase_with( K const& key, Less pred, Func f )
{
+ CDS_UNUSED( pred );
return base_class::erase_with( key,
cds::details::predicate_wrapper< node_type, Less, typename maker::key_accessor >(),
[&f]( node_type& node) { f( node.m_Value ); } );
/// Extracts the item from the map with specified \p key
/** \anchor cds_nonintrusive_SkipListMap_hp_extract
The function searches an item with key equal to \p key in the map,
- unlinks it from the map, and returns it in \p ptr parameter.
- If the item with key equal to \p key is not found the function returns \p false.
+ unlinks it from the map, and returns a guarded pointer to the item found.
+ If \p key is not found the function returns an empty guarded pointer.
Note the compare functor should accept a parameter of type \p K that can be not the same as \p key_type.
The item extracted is freed automatically by garbage collector \p GC
- when returned \ref guarded_ptr object will be destroyed or released.
+ when returned \p guarded_ptr object will be destroyed or released.
@note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
Usage:
skip_list theList;
// ...
{
- skip_list::guarded_ptr gp;
- if ( theList.extract( gp, 5 ) ) {
+ skip_list::guarded_ptr gp( theList.extract( 5 ));
+ if ( gp ) {
// Deal with gp
// ...
}
\endcode
*/
template <typename K>
- bool extract( guarded_ptr& ptr, K const& key )
+ guarded_ptr extract( K const& key )
{
- return base_class::extract_( ptr.guard(), key, typename base_class::key_comparator() );
+ guarded_ptr gp;
+ base_class::extract_( gp.guard(), key, typename base_class::key_comparator() );
+ return gp;
}
/// Extracts the item from the map with comparing functor \p pred
\p pred must imply the same element order as the comparator used for building the map.
*/
template <typename K, typename Less>
- bool extract_with( guarded_ptr& ptr, K const& key, Less pred )
+ guarded_ptr extract_with( K const& key, Less pred )
{
+ CDS_UNUSED( pred );
typedef cds::details::predicate_wrapper< node_type, Less, typename maker::key_accessor > wrapped_less;
- return base_class::extract_( ptr.guard(), key, cds::opt::details::make_comparator_from_less<wrapped_less>() );
+ guarded_ptr gp;
+ base_class::extract_( gp.guard(), key, cds::opt::details::make_comparator_from_less<wrapped_less>() );
+ return gp;
}
/// Extracts an item with minimal key from the map
/**
- The function searches an item with minimal key, unlinks it, and returns the item found in \p ptr parameter.
- If the skip-list is empty the function returns \p false.
+ The function searches an item with minimal key, unlinks it, and returns an guarded pointer to the item found.
+ If the skip-list is empty the function returns an empty guarded pointer.
The item extracted is freed automatically by garbage collector \p GC
- when returned \ref guarded_ptr object will be destroyed or released.
+ when returned \p guarded_ptr object will be destroyed or released.
@note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
Usage:
skip_list theList;
// ...
{
- skip_list::guarded_ptr gp;
- if ( theList.extract_min( gp )) {
+ skip_list::guarded_ptr gp( theList.extract_min());
+ if ( gp ) {
// Deal with gp
//...
}
}
\endcode
*/
- bool extract_min( guarded_ptr& ptr)
+ guarded_ptr extract_min()
{
- return base_class::extract_min_( ptr.guard() );
+ guarded_ptr gp;
+ base_class::extract_min_( gp.guard() );
+ return gp;
}
/// Extracts an item with maximal key from the map
/**
- The function searches an item with maximal key, unlinks it, and returns the pointer to item found in \p ptr parameter.
- If the skip-list is empty the function returns empty \p guarded_ptr.
+ The function searches an item with maximal key, unlinks it, and returns a guarded pointer to item found.
+ If the skip-list is empty the function returns an empty \p guarded_ptr.
The item found is freed by garbage collector \p GC automatically
- when returned \ref guarded_ptr object will be destroyed or released.
+ when returned \p guarded_ptr object will be destroyed or released.
@note Each \p guarded_ptr object uses the GC's guard that can be limited resource.
Usage:
skip_list theList;
// ...
{
- skip_list::guarded_ptr gp;
- if ( theList.extract_max( gp )) {
+ skip_list::guarded_ptr gp( theList.extract_max());
+ if ( gp ) {
// Deal with gp
//...
}
}
\endcode
*/
- bool extract_max( guarded_ptr& dest )
+ guarded_ptr extract_max()
{
- return base_class::extract_max_( dest.guard() );
+ guarded_ptr gp;
+ base_class::extract_max_( gp.guard() );
+ return gp;
}
/// Find the key \p key
\endcode
where \p item is the item found.
- You can pass \p f argument by reference using \p std::ref
-
The functor may change \p item.second.
The function returns \p true if \p key is found, \p false otherwise.
template <typename K, typename Less, typename Func>
bool find_with( K const& key, Less pred, Func f )
{
+ CDS_UNUSED( pred );
return base_class::find_with( key,
cds::details::predicate_wrapper< node_type, Less, typename maker::key_accessor >(),
[&f](node_type& item, K const& ) { f( item.m_Value );});
template <typename K, typename Less>
bool find_with( K const& key, Less pred )
{
+ CDS_UNUSED( pred );
return base_class::find_with( key, cds::details::predicate_wrapper< node_type, Less, typename maker::key_accessor >() );
}
/// Finds the key \p key and return the item found
/** \anchor cds_nonintrusive_SkipListMap_hp_get
The function searches the item with key equal to \p key
- and assigns the item found to guarded pointer \p ptr.
- The function returns \p true if \p key is found, and \p false otherwise.
- If \p key is not found the \p ptr parameter is not changed.
+ and returns an guarded pointer to the item found.
+ If \p key is not found the function returns an empty guarded pointer.
- It is safe when a concurrent thread erases the item returned in \p ptr guarded pointer.
+ It is safe when a concurrent thread erases the item returned as \p guarded_ptr.
In this case the item will be freed later by garbage collector \p GC automatically
when \p guarded_ptr object will be destroyed or released.
@note Each \p guarded_ptr object uses one GC's guard which can be limited resource.
skip_list theList;
// ...
{
- skip_list::guarded_ptr gp;
- if ( theList.get( gp, 5 ) ) {
+ skip_list::guarded_ptr gp( theList.get( 5 ));
+ if ( gp ) {
// Deal with gp
//...
}
should accept a parameter of type \p K that can be not the same as \p value_type.
*/
template <typename K>
- bool get( guarded_ptr& ptr, K const& key )
+ guarded_ptr get( K const& key )
{
- return base_class::get_with_( ptr.guard(), key, typename base_class::key_comparator() );
+ guarded_ptr gp;
+ base_class::get_with_( gp.guard(), key, typename base_class::key_comparator() );
+ return gp;
}
/// Finds the key \p key and return the item found
/**
- The function is an analog of \ref cds_nonintrusive_SkipListMap_hp_get "get( guarded_ptr& ptr, K const&)"
+ The function is an analog of \ref cds_nonintrusive_SkipListMap_hp_get "get( K const&)"
but \p pred is used for comparing the keys.
\p Less functor has the semantics like \p std::less but should take arguments of type \ref key_type and \p K
\p pred must imply the same element order as the comparator used for building the map.
*/
template <typename K, typename Less>
- bool get_with( guarded_ptr& ptr, K const& key, Less pred )
+ guarded_ptr get_with( K const& key, Less pred )
{
+ CDS_UNUSED( pred );
typedef cds::details::predicate_wrapper< node_type, Less, typename maker::key_accessor > wrapped_less;
- return base_class::get_with_( ptr.guard(), key, cds::opt::details::make_comparator_from_less< wrapped_less >());
+ guarded_ptr gp;
+ base_class::get_with_( gp.guard(), key, cds::opt::details::make_comparator_from_less< wrapped_less >());
+ return gp;
}
/// Clears the map
}
/// Checks if the map is empty
- /**
- Emptiness is checked by item counting: if item count is zero then the map is empty.
- */
bool empty() const
{
return base_class::empty();
{
return base_class::statistics();
}
-
};
}} // namespace cds::container