void operator()( bool bNew, value_type& item, const Q& val );
};
\endcode
-
with arguments:
- \p bNew - \p true if the item has been inserted, \p false otherwise
- \p item - item of the set
return bOk;
}
- /// Ensures that the \p val exists in the set
+ /// Updates the node
/**
- The operation performs inserting or changing data.
+ 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:
+ If \p key is not found in the set, then \p key is inserted iff \p bAllowInsert is \p true.
+ Otherwise, the functor \p func is called with item found.
+
+ The functor signature is:
\code
struct my_functor {
void operator()( bool bNew, value_type& item, const Q& val );
};
\endcode
-
with arguments:
- \p bNew - \p true if the item has been inserted, \p false otherwise
- - \p item - item of the list
- - \p val - argument \p val passed into the \p ensure function
+ - \p item - item of the set
+ - \p val - argument \p val passed into the \p %update() function
- The functor can change non-key fields of the \p item.
+ 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 val key
- already exists.
+ \p second is true if new item has been added or \p false if the item with \p key
+ already is in the map.
*/
template <typename Q, typename Func>
- std::pair<bool, bool> ensure( Q const& val, Func func )
+ std::pair<bool, bool> update( Q const& val, Func func, bool bAllowInsert = true )
{
std::pair<bool, bool> result;
bool bResize;
scoped_cell_lock sl( base_class::m_MutexPolicy, nHash );
pBucket = base_class::bucket( nHash );
- result = pBucket->ensure( val, func );
+ result = pBucket->update( val, func, bAllowInsert );
bResize = result.first && result.second && base_class::m_ResizingPolicy( ++base_class::m_ItemCounter, *this, *pBucket );
}
base_class::resize();
return result;
}
+ //@cond
+ template <typename Q, typename Func>
+ CDS_DEPRECATED("ensure() is deprecated, use update()")
+ std::pair<bool, bool> ensure( Q const& val, Func func )
+ {
+ return update( val, func, true );
+ }
+ //@endcond
/// Delete \p key from the set
/** \anchor cds_nonintrusive_StripedSet_erase
return base_class::find_with( val, pred, f );
}
- /// Find the key \p val
- /** \anchor cds_nonintrusive_StripedSet_find_val
-
- The function searches the item with key equal to \p val
+ /// Checks whether the set contains \p key
+ /**
+ 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 \p value_type.
+ Otherwise, you may use \p contains( Q const&, Less pred ) functions with explicit predicate for key comparing.
*/
template <typename Q>
- bool find( Q const& val )
+ bool contains( Q const& key )
{
- return base_class::find( val );
+ return base_class::contains( key );
}
+ //@cond
+ template <typename Q>
+ CDS_DEPRECATED("use contains()")
+ bool find( Q const& key )
+ {
+ return contains( key );
+ }
+ //@endcond
- /// Find the key \p val using \p pred predicate
+ /// Checks whether the map contains \p key using \p pred predicate for searching
/**
- The function is an analog of \ref cds_nonintrusive_StripedSet_find_val "find(Q const&)"
- but \p pred is used for key comparing
- \p Less has the interface like \p std::less.
- \p pred must imply the same element order as the comparator used for building the set.
-
- @note This function is enabled if the compiler supports C++11
- default template arguments for function template <b>and</b> the underlying container
- supports \p %find_with feature.
+ The function is similar to <tt>contains( key )</tt> 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 map.
*/
template <typename Q, typename Less
, typename Bucket = bucket_type, typename = typename std::enable_if< Bucket::has_find_with >::type >
+ bool contains( Q const& key, Less pred )
+ {
+ return base_class::contains( key, pred );
+ }
+ //@cond
+ template <typename Q, typename Less
+ , typename Bucket = bucket_type, typename = typename std::enable_if< Bucket::has_find_with >::type >
+ CDS_DEPRECATED("use contains()")
bool find_with( Q const& val, Less pred )
{
- return base_class::find_with( val, pred );
+ return contains( val, pred );
}
+ //@endcond
/// Clears the set
/**
}
template <typename Q, typename Func>
- std::pair<bool, bool> ensure( const Q& val, Func func )
+ std::pair<bool, bool> update( const Q& val, Func func, bool bAllowInsert )
{
- std::pair<iterator, bool> res = m_Set.insert( value_type(val) );
- func( res.second, const_cast<value_type&>(*res.first), val );
- return std::make_pair( true, res.second );
+ if ( bAllowInsert ) {
+ std::pair<iterator, bool> res = m_Set.insert( value_type(val) );
+ func( res.second, const_cast<value_type&>(*res.first), val );
+ return std::make_pair( true, res.second );
+ }
+ else {
+ auto it = m_Set.find( val );
+ if ( it == m_Set.end() )
+ return std::make_pair( false, false );
+ func( false, *it, val );
+ return std::make_pair( true, false );
+ }
}
template <typename Q, typename Func>
}
template <typename Q, typename Func>
- std::pair<bool, bool> ensure( Q const& val, Func func )
+ std::pair<bool, bool> update( Q const& val, Func func, bool bAllowInsert )
{
iterator it = std::lower_bound( m_List.begin(), m_List.end(), val, find_predicate() );
if ( it == m_List.end() || key_comparator()( val, *it ) != 0 ) {
// insert new
+ if ( !bAllowInsert )
+ return std::make_pair( false, false );
+
value_type newItem( val );
it = m_List.insert( it, newItem );
func( true, *it, val );
}
template <typename Q, typename Func>
- std::pair<bool, bool> ensure( const Q& val, Func func )
+ std::pair<bool, bool> update( const Q& val, Func func, bool bAllowInsert )
{
std::pair< iterator, bool > pos = find_prev_item( val );
if ( !pos.second ) {
// insert new
+ if ( !bAllowInsert )
+ return std::make_pair( false, false );
+
value_type newItem( val );
pos.first = m_List.insert_after( pos.first, newItem );
func( true, *pos.first, val );
//@endcond
public:
-
- /// Insert value \p val of type \p Q into the container
- /**
- The function allows to split creating of new item into two part:
- - create item with key only from \p val
- - try to insert new item into the container
- - if inserting is success, calls \p f functor to initialize value-field of the new item.
-
- The functor signature is:
- \code
- void func( value_type& item );
- \endcode
- where \p item is the item inserted.
-
- The type \p Q may differ from \ref value_type of items storing in the container.
- Therefore, the \p value_type should be comparable with type \p Q and constructible from type \p Q,
-
- The user-defined functor is called only if the inserting is success.
- */
template <typename Q, typename Func>
bool insert( const Q& val, Func f )
{
return false;
}
- /// Ensures that the \p item exists in the container
- /**
- The operation performs inserting or changing data.
-
- If the \p val key not found in the container, then the new item created from \p val
- is inserted. Otherwise, the functor \p func is called with the item found.
- The \p Func functor has interface:
- \code
- void func( bool bNew, value_type& item, const Q& val );
- \endcode
- or like a functor:
- \code
- struct my_functor {
- void operator()( bool bNew, value_type& item, const Q& val );
- };
- \endcode
-
- where arguments are:
- - \p bNew - \p true if the item has been inserted, \p false otherwise
- - \p item - container's item
- - \p val - argument \p val passed into the \p ensure function
-
- The functor may change non-key fields of the \p item.
-
- The type \p Q may differ from \ref value_type of items storing in the container.
- Therefore, the \p value_type should be comparable with type \p Q and constructible from type \p Q,
-
- 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 val key
- already exists.
- */
template <typename Q, typename Func>
- std::pair<bool, bool> ensure( const Q& val, Func func )
+ std::pair<bool, bool> update( const Q& val, Func func, bool bAllowInsert )
{
iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), val, find_predicate() );
if ( it == m_Vector.end() || key_comparator()( val, *it ) != 0 ) {
// insert new
+ if ( !bAllowInsert )
+ return std::make_pair( false, false );
+
value_type newItem( val );
it = m_Vector.insert( it, newItem );
func( true, *it, val );
}
}
- /// Delete \p key
- /**
- The function searches an item with key \p key, calls \p f functor
- and deletes the item. If \p key is not found, the functor is not called.
-
- The functor \p Func interface is:
- \code
- struct extractor {
- void operator()(value_type const& val);
- };
- \endcode
-
- The type \p Q may differ from \ref value_type of items storing in the container.
- Therefore, the \p value_type should be comparable with type \p Q.
-
- Return \p true if key is found and deleted, \p false otherwise
- */
template <typename Q, typename Func>
bool erase( const Q& key, Func f )
{
return true;
}
- /// Find the key \p val
- /**
- 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& val );
- };
- \endcode
- where \p item is the item found, \p val is the <tt>find</tt> function argument.
-
- The functor may change non-key fields of \p item.
- 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.
-
- The type \p Q may differ from \ref value_type of items storing in the container.
- Therefore, the \p value_type should be comparable with type \p Q.
-
- The function returns \p true if \p val is found, \p false otherwise.
- */
template <typename Q, typename Func>
bool find( Q& val, Func f )
{
};
}}} // namespace cds::intrusive::striped_set
-
-
//@endcond
#endif // #ifndef CDSLIB_CONTAINER_STRIPED_SET_BOOST_STABLE_VECTOR_ADAPTER_H
}
template <typename Q, typename Func>
- std::pair<bool, bool> ensure( const Q& val, Func func )
+ std::pair<bool, bool> update( const Q& val, Func func, bool bAllowInsert )
{
iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), val, find_predicate() );
if ( it == m_Vector.end() || key_comparator()( val, *it ) != 0 ) {
// insert new
+ if ( !bAllowInsert )
+ return std::make_pair( false, false );
+
value_type newItem( val );
it = m_Vector.insert( it, newItem );
func( true, *it, val );
}
template <typename Q, typename Func>
- std::pair<bool, bool> ensure( const Q& val, Func func )
+ std::pair<bool, bool> update( const Q& val, Func func, bool bAllowInsert )
{
- std::pair<iterator, bool> res = m_Set.insert( value_type(val) );
- func( res.second, const_cast<value_type&>(*res.first), val );
- return std::make_pair( true, res.second );
+ if ( bAllowInsert ) {
+ std::pair<iterator, bool> res = m_Set.insert( value_type(val) );
+ func( res.second, const_cast<value_type&>(*res.first), val );
+ return std::make_pair( true, res.second );
+ }
+ else {
+ auto it = m_Set.find( value_type(val));
+ if ( it = m_Set.end() )
+ return std::make_pair( false, false );
+
+ func( false, *it, val );
+ return std::make_pair( true, false );
+ }
}
template <typename Q, typename Func>
}
template <typename Q, typename Func>
- std::pair<bool, bool> ensure( const Q& val, Func func )
+ std::pair<bool, bool> update( const Q& val, Func func, bool bAllowInsert )
{
iterator it = std::lower_bound( m_List.begin(), m_List.end(), val, find_predicate() );
if ( it == m_List.end() || key_comparator()( val, *it ) != 0 ) {
// insert new
+ if ( !bAllowInsert )
+ return std::make_pair( false, false );
+
value_type newItem( val );
it = m_List.insert( it, newItem );
func( true, *it, val );
}
template <typename Q, typename Func>
- std::pair<bool, bool> ensure( const Q& val, Func func )
+ std::pair<bool, bool> update( const Q& val, Func func, bool bAllowInsert )
{
- std::pair<iterator, bool> res = m_Set.insert( value_type(val) );
- func( res.second, const_cast<value_type&>(*res.first), val );
- return std::make_pair( true, res.second );
+ if ( bAllowInsert ) {
+ std::pair<iterator, bool> res = m_Set.insert( value_type(val) );
+ func( res.second, const_cast<value_type&>(*res.first), val );
+ return std::make_pair( true, res.second );
+ }
+ else {
+ auto it = m_Set.find(value_type(val));
+ if ( it == m_Set.end() )
+ return std::make_pair( false, false );
+ func( false, *it, val );
+ return std::make_pair( true, false );
+ }
}
template <typename Q, typename Func>
}
template <typename Q, typename Func>
- std::pair<bool, bool> ensure( const Q& val, Func func )
+ std::pair<bool, bool> update( const Q& val, Func func, bool bAllowInsert )
{
iterator it = std::lower_bound( m_Vector.begin(), m_Vector.end(), val, find_predicate() );
if ( it == m_Vector.end() || key_comparator()( val, *it ) != 0 ) {
// insert new
+ if ( !bAllowInsert )
+ return std::make_pair( false, false );
+
value_type newItem( val );
it = m_Vector.insert( it, newItem );
func( true, *it, val );
The functor may change non-key fields of the \p item.
Returns std::pair<bool, bool> where \p first is \p true if operation is successfull,
- \p second is \p true if new item has been added or \p false if the item with \p key
+ \p second is \p true if new item has been added or \p false if the item with \p val
already is in the list.
@warning For \ref cds_intrusive_MichaelList_hp "MichaelList" as the bucket see \ref cds_intrusive_item_creating "insert item troubleshooting".
return bOk;
}
- /// Ensures that the \p val exists in the set
+ /// Updates the node
/**
The operation performs inserting or changing data with lock-free manner.
- If the item \p val not found in the set, then \p val is inserted into the set.
+ If the item \p val is not found in the set, then \p val is inserted
+ iff \p bAllowInsert is \p true.
Otherwise, the functor \p func is called with item found.
The functor signature is:
\code
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 update() function
If new item has been inserted (i.e. \p bNew is \p true) then \p item and \p val arguments
refers to the same thing.
The functor may change non-key fields of the \p item.
- Returns <tt> std::pair<bool, bool> </tt> where \p first is \p true if operation is successful,
- \p second is \p true if new item has been added or \p false if the item with \p key
+ Returns std::pair<bool, bool> where \p first is \p true if operation is successfull,
+ \p second is \p true if new item has been added or \p false if the item with \p val
already is in the set.
*/
template <typename Func>
- std::pair<bool, bool> ensure( value_type& val, Func func )
+ std::pair<bool, bool> update( value_type& val, Func func, bool bAllowInsert = true )
{
std::pair<bool, bool> result;
bool bResize;
scoped_cell_lock sl( m_MutexPolicy, nHash );
pBucket = bucket( nHash );
- result = pBucket->ensure( val, func );
+ result = pBucket->update( val, func, bAllowInsert );
bResize = result.first && result.second && m_ResizingPolicy( ++m_ItemCounter, *this, *pBucket );
}
resize();
return result;
}
+ //@cond
+ template <typename Func>
+ std::pair<bool, bool> ensure( value_type& val, Func func )
+ {
+ return update( val, func, true );
+ }
+ //@endcond
/// Unlink the item \p val from the set
/**
return find_with_( val, pred, f );
}
- /// Find the key \p val
- /** \anchor cds_intrusive_StripedSet_find_val
- The function searches the item with key equal to \p val
+ /// Checks whether the set contains \p key
+ /**
+ 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 \p value_type.
+ Otherwise, you may use \p contains( Q const&, Less pred ) functions with explicit predicate for key comparing.
*/
template <typename Q>
+ bool contains( Q const& key )
+ {
+ return find( key, [](value_type&, Q const& ) {} );
+ }
+ //@cond
+ template <typename Q>
+ CDS_DEPRECATED("use contains()")
bool find( Q const& val )
{
- return find( val, [](value_type&, Q const& ) {} );
+ return contains( val ;)
}
+ //@endcond
- /// Find the key \p val using \p pred predicate
+ /// Checks whether the set contains \p key using \p pred predicate for searching
/**
- The function is an analog of \ref cds_intrusive_StripedSet_find_val "find(Q const&)"
- but \p pred is used for key comparing
- \p Less has the interface like \p std::less.
- \p pred must imply the same element order as the comparator used for building the set.
+ The function is an analog of <tt>contains( key )</tt> 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.
*/
template <typename Q, typename Less>
+ bool contains( Q const& key, Less pred )
+ {
+ return find_with( key, pred, [](value_type& , Q const& ) {} );
+ }
+ //@cond
+ template <typename Q, typename Less>
+ CDS_DEPRECATED("use contains()")
bool find_with( Q const& val, Less pred )
{
- return find_with( val, pred, [](value_type& , Q const& ) {} );
+ return contains( val, pred );
}
+ //@endcond
/// Clears the set
/**
The user-defined functor \p f is called only if the inserting is success.
<hr>
- <b>Ensures that the \p item exists in the container</b>
- \code template <typename Func> std::pair<bool, bool> ensure( value_type& val, Func f ) \endcode
+ <b>Updates the item in the container</b>
+ \code template <typename Func> std::pair<bool, bool> update( value_type& val, Func f, bool bAllowInsert = true ) \endcode
The operation performs inserting or changing data.
- If the \p val key not found in the container, then \p val is inserted.
+ If the \p val key not found in the container, then \p val is inserted iff \p bAllowInsert is \p true.
Otherwise, the functor \p f is called with the item found.
The \p Func functor has the following interface:
where arguments are:
- \p bNew - \p true if the item has been inserted, \p false otherwise
- \p item - container's item
- - \p val - argument \p val passed into the \p ensure function
+ - \p val - argument \p val passed into the \p update() function
If \p val has been inserted (i.e. <tt>bNew == true</tt>) then \p item and \p val
are the same element: <tt>&item == &val</tt>. Otherwise, they are different.
}
template <typename Func>
- std::pair<bool, bool> ensure( value_type& val, Func f )
+ std::pair<bool, bool> update( value_type& val, Func f, bool bAllowInsert )
{
- std::pair<iterator, bool> res = m_Set.insert( val );
- f( res.second, *res.first, val );
- return std::make_pair( true, res.second );
+ if ( bAllowInsert ) {
+ std::pair<iterator, bool> res = m_Set.insert( val );
+ f( res.second, *res.first, val );
+ return std::make_pair( true, res.second );
+ }
+ else {
+ auto it = m_Set.find( val );
+ if ( it == m_Set.end() )
+ return std::make_pair( false, false );
+ f( false, *it, val );
+ return std::make_pair( true, false );
+ }
}
bool unlink( value_type& val )
}
template <typename Func>
- std::pair<bool, bool> ensure( value_type& val, Func f )
+ std::pair<bool, bool> update( value_type& val, Func f, bool bAllowInsert )
{
iterator it = find_key( val, find_predicate() );
if ( it == m_List.end() || key_comparator()(val, *it) != 0 ) {
// insert new
+ if ( !bAllowInsert )
+ return std::make_pair( false, false );
+
m_List.insert( it, val );
f( true, val, val );
return std::make_pair( true, true );
}
template <typename Func>
- std::pair<bool, bool> ensure( value_type& val, Func f )
+ std::pair<bool, bool> update( value_type& val, Func f, bool bAllowInsert )
{
std::pair< iterator, bool > pos = find_prev_item( val );
if ( !pos.second ) {
// insert new
+ if ( !bAllowInsert )
+ return std::make_pair( false, false );
+
m_List.insert_after( pos.first, val );
f( true, val, val );
return std::make_pair( true, true );
}
template <typename Func>
- std::pair<bool, bool> ensure( value_type& val, Func f )
+ std::pair<bool, bool> update( value_type& val, Func f, bool bAllowInsert )
{
- std::pair<iterator, bool> res = m_Set.insert( val );
- f( res.second, *res.first, val );
- return std::make_pair( true, res.second );
+ if ( bAllowInsert ) {
+ std::pair<iterator, bool> res = m_Set.insert( val );
+ f( res.second, *res.first, val );
+ return std::make_pair( true, res.second );
+ }
+ else {
+ auto it = m_Set.find( val );
+ if ( it == m_Set.end() )
+ return std::make_pair( false, false );
+ f( false, *it, val );
+ return std::make_pair( true, false );
+ }
}
bool unlink( value_type& val )
<ClCompile Include="..\..\..\tests\unit\map2\map_find_int_cuckoo.cpp" />\r
<ClCompile Include="..\..\..\tests\unit\map2\map_find_int_ellentree.cpp" />\r
<ClCompile Include="..\..\..\tests\unit\map2\map_find_int_michael.cpp" />\r
- <ClCompile Include="..\..\..\tests\unit\map2\map_find_int_refinable.cpp" />\r
+ <ClCompile Include="..\..\..\tests\unit\map2\map_find_int_multilevelhashmap.cpp" />\r
<ClCompile Include="..\..\..\tests\unit\map2\map_find_int_skip.cpp" />\r
<ClCompile Include="..\..\..\tests\unit\map2\map_find_int_split.cpp" />\r
<ClCompile Include="..\..\..\tests\unit\map2\map_find_int_std.cpp" />\r
<ClCompile Include="..\..\..\tests\unit\map2\map_find_int_michael.cpp">\r
<Filter>map_find_int</Filter>\r
</ClCompile>\r
- <ClCompile Include="..\..\..\tests\unit\map2\map_find_int_refinable.cpp">\r
- <Filter>map_find_int</Filter>\r
- </ClCompile>\r
<ClCompile Include="..\..\..\tests\unit\map2\map_find_int_skip.cpp">\r
<Filter>map_find_int</Filter>\r
</ClCompile>\r
<ClCompile Include="..\..\..\tests\unit\map2\map_insfind_int_striped.cpp">\r
<Filter>map_insfind_int</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\tests\unit\map2\map_find_int_multilevelhashmap.cpp">\r
+ <Filter>map_find_int</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<ClInclude Include="..\..\..\tests\unit\map2\map_find_int.h">\r
tests/unit/map2/map_find_int_cuckoo.cpp \
tests/unit/map2/map_find_int_ellentree.cpp \
tests/unit/map2/map_find_int_michael.cpp \
+ tests/unit/map2/map_find_int_multilevelhashmap.cpp \
tests/unit/map2/map_find_int_skip.cpp \
tests/unit/map2/map_find_int_split.cpp \
tests/unit/map2/map_find_int_striped.cpp \
- tests/unit/map2/map_find_int_refinable.cpp \
tests/unit/map2/map_find_int_std.cpp \
tests/unit/map2/map_find_string.cpp \
tests/unit/map2/map_find_string_bronsonavltree.cpp \
map_find_int_cuckoo.cpp
map_find_int_ellentree.cpp
map_find_int_michael.cpp
+ map_find_int_multilevelhashmap.cpp
map_find_int_skip.cpp
map_find_int_split.cpp
map_find_int_striped.cpp
- map_find_int_refinable.cpp
map_find_int_std.cpp
map_find_string.cpp
map_find_string_bronsonavltree.cpp
CPPUNIT_TEST(StdMap_Mutex) \
CPPUNIT_TEST(StdHashMap_Mutex) \
+#define CDSUNIT_DECLARE_StdMap_NoLock \
+ TEST_CASE(tag_StdMap, StdMap_NoLock) \
+ TEST_CASE(tag_StdMap, StdHashMap_NoLock) \
+
+#define CDSUNIT_TEST_StdMap_NoLock \
+ CPPUNIT_TEST(StdMap_NoLock) \
+ CPPUNIT_TEST(StdHashMap_NoLock) \
+
// **************************************************************************************
// MichaelMap
namespace map2 {
CPPUNIT_TEST_SUITE_REGISTRATION( Map_find_int );
- size_t Map_find_int::c_nThreadCount = 8 ; // thread count
- size_t Map_find_int::c_nMapSize = 20000000 ; // map size (count of searching item)
- size_t Map_find_int::c_nPercentExists = 50 ; // percent of existing keys in searching sequence
- size_t Map_find_int::c_nPassCount = 2;
- size_t Map_find_int::c_nMaxLoadFactor = 8 ; // maximum load factor
- bool Map_find_int::c_bPrintGCState = true;
-
void Map_find_int::generateSequence()
{
size_t nPercent = c_nPercentExists;
shuffle( m_Arr.begin(), m_Arr.end() );
}
- void Map_find_int::initTestSequence()
- {
- CPPUNIT_MSG( "Generating test data...");
- cds::OS::Timer timer;
- generateSequence();
- CPPUNIT_MSG( " Duration=" << timer.duration() );
- CPPUNIT_MSG( "Map size=" << m_nRealMapSize << " find key loop=" << m_Arr.size() << " (" << c_nPercentExists << "% success)" );
- CPPUNIT_MSG( "Thread count=" << c_nThreadCount << " Pass count=" << c_nPassCount );
-
- m_bSequenceInitialized = true;
- }
-
void Map_find_int::setUpParams( const CppUnitMini::TestCfg& cfg )
{
c_nThreadCount = cfg.getSizeT("ThreadCount", c_nThreadCount );
c_nPassCount = cfg.getSizeT("PassCount", c_nPassCount);
c_nMaxLoadFactor = cfg.getSizeT("MaxLoadFactor", c_nMaxLoadFactor);
c_bPrintGCState = cfg.getBool("PrintGCStateFlag", c_bPrintGCState );
- }
- void Map_find_int::myRun(const char *in_name, bool invert /*= false*/)
- {
- setUpParams( m_Cfg.get( "Map_find_int" ));
+ c_nCuckooInitialSize = cfg.getSizeT("CuckooInitialSize", c_nCuckooInitialSize);
+ c_nCuckooProbesetSize = cfg.getSizeT("CuckooProbesetSize", c_nCuckooProbesetSize);
+ c_nCuckooProbesetThreshold = cfg.getSizeT("CuckooProbesetThreshold", c_nCuckooProbesetThreshold);
- run_MichaelMap(in_name, invert);
- run_SplitList(in_name, invert);
- run_SkipListMap(in_name, invert);
- run_EllenBinTreeMap(in_name, invert);
- run_BronsonAVLTreeMap(in_name, invert);
- run_StripedMap(in_name, invert);
- run_RefinableMap(in_name, invert);
- run_CuckooMap(in_name, invert);
- run_StdMap(in_name, invert);
+ c_nMultiLevelMap_HeadBits = cfg.getSizeT("MultiLevelMapHeadBits", c_nMultiLevelMap_HeadBits);
+ c_nMultiLevelMap_ArrayBits = cfg.getSizeT("MultiLevelMapArrayBits", c_nMultiLevelMap_ArrayBits);
- endTestCase();
- }
+ if ( c_nThreadCount == 0 )
+ c_nThreadCount = std::thread::hardware_concurrency();
+ CPPUNIT_MSG( "Generating test data...");
+ cds::OS::Timer timer;
+ generateSequence();
+ CPPUNIT_MSG( " Duration=" << timer.duration() );
+ CPPUNIT_MSG( "Map size=" << m_nRealMapSize << " find key loop=" << m_Arr.size() << " (" << c_nPercentExists << "% success)" );
+ CPPUNIT_MSG( "Thread count=" << c_nThreadCount << " Pass count=" << c_nPassCount );
+ }
} // namespace map
// find int test in map<int> in mutithreaded mode
namespace map2 {
-# define TEST_MAP(IMPL, C, X) void C::X() { test<map_type<IMPL, key_type, value_type>::X >(); }
-# define TEST_MAP_NOLF(IMPL, C, X) void C::X() { test_nolf<map_type<IMPL, key_type, value_type>::X >(); }
-# define TEST_MAP_EXTRACT(IMPL, C, X) TEST_MAP(IMPL, C, X)
-# define TEST_MAP_NOLF_EXTRACT(IMPL, C, X) TEST_MAP_NOLF(IMPL, C, X)
+#define TEST_CASE(TAG, X) void X();
class Map_find_int: public CppUnitMini::TestCase
{
- static size_t c_nThreadCount; // thread count
- static size_t c_nMapSize; // map size (count of searching item)
- static size_t c_nPercentExists; // percent of existing keys in searching sequence
- static size_t c_nPassCount;
- static size_t c_nMaxLoadFactor; // maximum load factor
- static bool c_bPrintGCState;
+ public:
+ size_t c_nThreadCount = 8; // thread count
+ size_t c_nMapSize = 10000000; // map size (count of searching item)
+ size_t c_nPercentExists = 50; // percent of existing keys in searching sequence
+ size_t c_nPassCount = 2;
+ size_t c_nMaxLoadFactor = 8; // maximum load factor
+ bool c_bPrintGCState = true;
+
+ size_t c_nCuckooInitialSize = 1024;// initial size for CuckooMap
+ size_t c_nCuckooProbesetSize = 16; // CuckooMap probeset size (only for list-based probeset)
+ size_t c_nCuckooProbesetThreshold = 0; // CUckooMap probeset threshold (o - use default)
+
+ size_t c_nMultiLevelMap_HeadBits = 10;
+ size_t c_nMultiLevelMap_ArrayBits = 4;
+
+ size_t c_nLoadFactor; // current load factor
+ private:
typedef CppUnitMini::TestCase Base;
typedef size_t key_type;
struct value_type {
typedef std::vector<value_type> ValueVector;
ValueVector m_Arr;
size_t m_nRealMapSize;
- bool m_bSequenceInitialized;
void generateSequence();
virtual void test()
{
ValueVector& arr = getTest().m_Arr;
- //size_t nSize = arr.size();
+ size_t const nPassCount = getTest().c_nPassCount;
Map& rMap = m_Map;
- for ( size_t nPass = 0; nPass < c_nPassCount; ++nPass ) {
+ for ( size_t nPass = 0; nPass < nPassCount; ++nPass ) {
if ( m_nThreadNo & 1 ) {
ValueVector::const_iterator itEnd = arr.end();
for ( ValueVector::const_iterator it = arr.begin(); it != itEnd; ++it ) {
- auto bFound = rMap.find( it->nKey );
+ auto bFound = rMap.contains( it->nKey );
if ( it->bExists ) {
if ( check_result( bFound, rMap ))
++m_KeyExists.nSuccess;
else {
ValueVector::const_reverse_iterator itEnd = arr.rend();
for ( ValueVector::const_reverse_iterator it = arr.rbegin(); it != itEnd; ++it ) {
- auto bFound = rMap.find( it->nKey );
+ auto bFound = rMap.contains( it->nKey );
if ( it->bExists ) {
if ( check_result( bFound, rMap ))
++m_KeyExists.nSuccess;
additional_cleanup( testMap );
}
- void initTestSequence();
-
template <class Map>
- void test()
+ void run_test()
{
- if ( !m_bSequenceInitialized )
- initTestSequence();
-
- for ( size_t nLoadFactor = 1; nLoadFactor <= c_nMaxLoadFactor; nLoadFactor *= 2 ) {
- CPPUNIT_MSG( "Load factor=" << nLoadFactor );
- Map testMap( c_nMapSize, nLoadFactor );
+ if ( Map::c_bLoadFactorDepended ) {
+ for ( c_nLoadFactor = 1; c_nLoadFactor <= c_nMaxLoadFactor; c_nLoadFactor *= 2 ) {
+ CPPUNIT_MSG( "Load factor=" << c_nLoadFactor );
+ Map testMap( *this );
+ find_int_test( testMap );
+ if ( c_bPrintGCState )
+ print_gc_state();
+ }
+ }
+ else {
+ Map testMap( *this );
find_int_test( testMap );
if ( c_bPrintGCState )
print_gc_state();
}
}
- template <class Map>
- void test_nolf()
- {
- if ( !m_bSequenceInitialized )
- initTestSequence();
-
- Map testMap;
- find_int_test( testMap );
- if ( c_bPrintGCState )
- print_gc_state();
- }
-
void setUpParams( const CppUnitMini::TestCfg& cfg );
- void run_MichaelMap(const char *in_name, bool invert = false);
- void run_SplitList(const char *in_name, bool invert = false);
- void run_StripedMap(const char *in_name, bool invert = false);
- void run_RefinableMap(const char *in_name, bool invert = false);
- void run_CuckooMap(const char *in_name, bool invert = false);
- void run_SkipListMap(const char *in_name, bool invert = false);
- void run_EllenBinTreeMap(const char *in_name, bool invert = false);
- void run_BronsonAVLTreeMap(const char *in_name, bool invert = false);
- void run_StdMap(const char *in_name, bool invert = false);
-
- virtual void myRun(const char *in_name, bool invert = false);
-
public:
Map_find_int()
- : m_bSequenceInitialized( false )
+ : c_nLoadFactor(2)
{}
# include "map2/map_defs.h"
CDSUNIT_DECLARE_SkipListMap_nogc
CDSUNIT_DECLARE_EllenBinTreeMap
CDSUNIT_DECLARE_BronsonAVLTreeMap
+ CDSUNIT_DECLARE_MultiLevelHashMap
CDSUNIT_DECLARE_StripedMap
CDSUNIT_DECLARE_RefinableMap
CDSUNIT_DECLARE_CuckooMap
CDSUNIT_DECLARE_StdMap
+ CDSUNIT_DECLARE_StdMap_NoLock
+
+ CPPUNIT_TEST_SUITE(Map_find_int)
+ CDSUNIT_TEST_MichaelMap
+ CDSUNIT_TEST_MichaelMap_nogc
+ CDSUNIT_TEST_SplitList
+ CDSUNIT_TEST_SplitList_nogc
+ CDSUNIT_TEST_SkipListMap
+ CDSUNIT_TEST_SkipListMap_nogc
+ CDSUNIT_TEST_EllenBinTreeMap
+ CDSUNIT_TEST_BronsonAVLTreeMap
+ CDSUNIT_TEST_MultiLevelHashMap
+ CDSUNIT_TEST_CuckooMap
+ CDSUNIT_TEST_StripedMap
+ CDSUNIT_TEST_RefinableMap
+ CDSUNIT_TEST_StdMap
+ CDSUNIT_TEST_StdMap_NoLock
+ CPPUNIT_TEST_SUITE_END();
};
} // namespace map
#include "map2/map_find_int.h"
#include "map2/map_type_bronson_avltree.h"
-namespace map2 {
- CDSUNIT_DEFINE_BronsonAVLTreeMap( cc::bronson_avltree::implementation_tag, Map_find_int)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X) void Map_find_int::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
- CPPUNIT_TEST_SUITE_PART( Map_find_int, run_BronsonAVLTreeMap )
- CDSUNIT_TEST_BronsonAVLTreeMap
- CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+ CDSUNIT_DECLARE_BronsonAVLTreeMap
} // namespace map2
#include "map2/map_find_int.h"
#include "map2/map_type_cuckoo.h"
-namespace map2 {
- CDSUNIT_DEFINE_CuckooMap(cds::intrusive::cuckoo::implementation_tag, Map_find_int)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X) void Map_find_int::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
- CPPUNIT_TEST_SUITE_PART( Map_find_int, run_CuckooMap )
- CDSUNIT_TEST_CuckooMap
- CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+ CDSUNIT_DECLARE_CuckooMap
} // namespace map2
#include "map2/map_find_int.h"
#include "map2/map_type_ellen_bintree.h"
-namespace map2 {
- CDSUNIT_DEFINE_EllenBinTreeMap( cc::ellen_bintree::implementation_tag, Map_find_int)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X) void Map_find_int::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
- CPPUNIT_TEST_SUITE_PART( Map_find_int, run_EllenBinTreeMap )
- CDSUNIT_TEST_EllenBinTreeMap
- CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+ CDSUNIT_DECLARE_EllenBinTreeMap
} // namespace map2
#include "map2/map_find_int.h"
#include "map2/map_type_michael.h"
-namespace map2 {
- CDSUNIT_DEFINE_MichaelMap( cc::michael_map::implementation_tag, Map_find_int )
- CDSUNIT_DEFINE_MichaelMap_nogc( cc::michael_map::implementation_tag, Map_find_int )
+#undef TEST_CASE
+#define TEST_CASE(TAG, X) void Map_find_int::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
- CPPUNIT_TEST_SUITE_PART( Map_find_int, run_MichaelMap )
- CDSUNIT_TEST_MichaelMap
- CDSUNIT_TEST_MichaelMap_nogc
- CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+ CDSUNIT_DECLARE_MichaelMap
+ CDSUNIT_DECLARE_MichaelMap_nogc
} // namespace map2
--- /dev/null
+//$$CDS-header$$
+
+#include "map2/map_find_int.h"
+#include "map2/map_type_multilevel_hashmap.h"
+
+#undef TEST_CASE
+#define TEST_CASE(TAG, X) void Map_find_int::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
+
+namespace map2 {
+ CDSUNIT_DECLARE_MultiLevelHashMap
+} // namespace map2
+++ /dev/null
-//$$CDS-header$$
-
-#include "map2/map_find_int.h"
-#include "map2/map_type_striped.h"
-
-namespace map2 {
- CDSUNIT_DEFINE_RefinableMap(cc::striped_set::implementation_tag, Map_find_int)
-
- CPPUNIT_TEST_SUITE_PART( Map_find_int, run_RefinableMap )
- CDSUNIT_TEST_RefinableMap
- CPPUNIT_TEST_SUITE_END_PART()
-} // namespace map2
#include "map2/map_find_int.h"
#include "map2/map_type_skip_list.h"
-namespace map2 {
- CDSUNIT_DEFINE_SkipListMap( cc::skip_list::implementation_tag, Map_find_int)
- CDSUNIT_DEFINE_SkipListMap_nogc( cc::skip_list::implementation_tag, Map_find_int)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X) void Map_find_int::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
- CPPUNIT_TEST_SUITE_PART( Map_find_int, run_SkipListMap )
- CDSUNIT_TEST_SkipListMap
- CDSUNIT_TEST_SkipListMap_nogc
- CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+ CDSUNIT_DECLARE_SkipListMap
+ CDSUNIT_DECLARE_SkipListMap_nogc
} // namespace map2
#include "map2/map_find_int.h"
#include "map2/map_type_split_list.h"
-namespace map2 {
- CDSUNIT_DEFINE_SplitList( cc::split_list::implementation_tag, Map_find_int )
- CDSUNIT_DEFINE_SplitList_nogc( cc::split_list::implementation_tag, Map_find_int )
+#undef TEST_CASE
+#define TEST_CASE(TAG, X) void Map_find_int::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
- CPPUNIT_TEST_SUITE_PART( Map_find_int, run_SplitList )
- CDSUNIT_TEST_SplitList
- CDSUNIT_TEST_SplitList_nogc
- CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+ CDSUNIT_DECLARE_SplitList
+ CDSUNIT_DECLARE_SplitList_nogc
} // namespace map2
#include "map2/map_find_int.h"
#include "map2/map_type_std.h"
-namespace map2 {
- CDSUNIT_DEFINE_StdMap( map2::std_implementation_tag, Map_find_int)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X) void Map_find_int::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
- CPPUNIT_TEST_SUITE_PART( Map_find_int, run_StdMap )
- CDSUNIT_TEST_StdMap
- CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+ CDSUNIT_DECLARE_StdMap
+ CDSUNIT_DECLARE_StdMap_NoLock
} // namespace map2
#include "map2/map_find_int.h"
#include "map2/map_type_striped.h"
-namespace map2 {
- CDSUNIT_DEFINE_StripedMap(cc::striped_set::implementation_tag, Map_find_int)
+#undef TEST_CASE
+#define TEST_CASE(TAG, X) void Map_find_int::X() { run_test<typename map_type< TAG, key_type, value_type>::X>(); }
+#include "map2/map_defs.h"
- CPPUNIT_TEST_SUITE_PART( Map_find_int, run_StripedMap )
- CDSUNIT_TEST_StripedMap
- CPPUNIT_TEST_SUITE_END_PART()
+namespace map2 {
+ CDSUNIT_DECLARE_StripedMap
+ CDSUNIT_DECLARE_RefinableMap
} // namespace map2
namespace map2 {
-# define TEST_CASE(TAG, X) void X();
-
-//# define TEST_MAP(IMPL, C, X) void C::X() { test<map_type<IMPL, key_type, value_type>::X >() ; }
-//# define TEST_MAP_EXTRACT(IMPL, C, X) TEST_MAP(IMPL, C, X)
-//# define TEST_MAP_NOLF(IMPL, C, X) void C::X() { test_nolf<map_type<IMPL, key_type, value_type>::X >() ; }
-//# define TEST_MAP_NOLF_EXTRACT(IMPL, C, X) TEST_MAP_NOLF(IMPL, C, X)
+#define TEST_CASE(TAG, X) void X();
class Map_InsDel_func: public CppUnitMini::TestCase
{
);
if ( Map::c_bLoadFactorDepended ) {
- for ( size_t c_nLoadFactor = 1; c_nLoadFactor <= c_nMaxLoadFactor; c_nLoadFactor *= 2 ) {
+ for ( c_nLoadFactor = 1; c_nLoadFactor <= c_nMaxLoadFactor; c_nLoadFactor *= 2 ) {
CPPUNIT_MSG( "Load factor=" << c_nLoadFactor );
Map testMap( *this );
do_test( testMap );
#define TEST_CASE(TAG, X) void X();
-//# define TEST_MAP(IMPL, C, X) void C::X() { test<map_type<IMPL, key_type, value_type>::X >(); }
-//# define TEST_MAP_NOLF(IMPL, C, X) void C::X() { test_nolf<map_type<IMPL, key_type, value_type>::X >(); }
-//# define TEST_MAP_EXTRACT(IMPL, C, X) TEST_MAP(IMPL, C, X)
-//# define TEST_MAP_NOLF_EXTRACT(IMPL, C, X) TEST_MAP_NOLF(IMPL, C, X)
-
class Map_InsDel_string: public CppUnitMini::TestCase
{
public:
);
if ( Map::c_bLoadFactorDepended ) {
- for ( size_t nLoadFactor = 1; nLoadFactor <= c_nMaxLoadFactor; nLoadFactor *= 2 ) {
- CPPUNIT_MSG( "Load factor=" << nLoadFactor );
+ for ( c_nLoadFactor = 1; c_nLoadFactor <= c_nMaxLoadFactor; c_nLoadFactor *= 2 ) {
+ CPPUNIT_MSG( "Load factor=" << c_nLoadFactor );
Map testMap( *this );
do_test( testMap );
if ( c_bPrintGCState )
StdHashMap( Config const& )
{}
- bool find( const Key& key )
+ bool contains( const Key& key )
{
scoped_lock al( m_lock );
return base_class::find( key ) != base_class::end();
StdMap( Config const& )
{}
- bool find( const Key& key )
+ bool contains( const Key& key )
{
scoped_lock al( m_lock );
return base_class::find( key ) != base_class::end();