static CDS_CONSTEXPR const bool c_bExtractLockExternal = base_class::c_bExtractLockExternal;
/// pointer to extracted node
- typedef cds::urcu::exempt_ptr< gc, node_type, value_type, typename maker::intrusive_type_traits::disposer > exempt_ptr;
+ using exempt_ptr = cds::urcu::exempt_ptr< gc, node_type, value_type, typename maker::intrusive_type_traits::disposer >;
protected:
//@cond
/// Extracts the item from the map with specified \p key
/** \anchor cds_nonintrusive_SkipListMap_rcu_extract
The function searches an item with key equal to \p key in the map,
- unlinks it from the set, and returns it in \p result parameter.
- If the item with key equal to \p key is not found the function returns \p false.
+ unlinks it from the set, and returns \ref cds::urcu::exempt_ptr "exempt_ptr" pointer to the item found.
+ If the item is not found the function returns an empty \p exempt_ptr
Note the compare functor from \p Traits class' template argument
should accept a parameter of type \p K that can be not the same as \p key_type.
RCU \p synchronize() method can be called. RCU should NOT be locked.
The function does not free the item found.
- The item will be implicitly freed when \p result object is destroyed or when
- <tt>result.release()</tt> is called, see cds::urcu::exempt_ptr for explanation.
- @note Before reusing \p result object you should call its \p release() method.
+ The item will be implicitly freed when the returned object is destroyed or when
+ its \p release() member function is called.
*/
template <typename K>
- bool extract( exempt_ptr& result, K const& key )
+ exempt_ptr extract( K const& key )
{
- return base_class::do_extract( result, key );
+ return exempt_ptr( base_class::do_extract( key ));
}
/// 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( exempt_ptr& result, K const& key, Less pred )
+ exempt_ptr extract_with( K const& key, Less pred )
{
- return base_class::do_extract_with( result, key, cds::details::predicate_wrapper< node_type, Less, typename maker::key_accessor >());
+ return exempt_ptr( base_class::do_extract_with( key, cds::details::predicate_wrapper< node_type, Less, typename maker::key_accessor >()));
}
/// 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 result parameter.
- If the skip-list is empty the function returns \p false.
+ The function searches an item with minimal key, unlinks it,
+ and returns \ref cds::urcu::exempt_ptr "exempt_ptr" pointer to the item.
+ If the skip-list is empty the function returns an empty \p exempt_ptr.
RCU \p synchronize method can be called. RCU should NOT be locked.
The function does not free the item found.
- The item will be implicitly freed when \p result object is destroyed or when
- <tt>result.release()</tt> is called, see cds::urcu::exempt_ptr for explanation.
- @note Before reusing \p result object you should call its \p release() method.
+ The item will be implicitly freed when the returned object is destroyed or when
+ its \p release() member function is called.
*/
- bool extract_min( exempt_ptr& result )
+ exempt_ptr extract_min()
{
- return base_class::do_extract_min(result);
+ return exempt_ptr( base_class::do_extract_min());
}
/// Extracts an item with maximal key from the map
/**
- The function searches an item with maximal key, unlinks it from the set, and returns the item found
- in \p result parameter. If the skip-list is empty the function returns \p false.
+ The function searches an item with maximal key, unlinks it from the set,
+ and returns \ref cds::urcu::exempt_ptr "exempt_ptr" pointer to the item.
+ If the skip-list is empty the function returns an empty \p exempt_ptr.
RCU \p synchronize method can be called. RCU should NOT be locked.
The function does not free the item found.
- The item will be implicitly freed when \p result object is destroyed or when
- <tt>result.release()</tt> is called, see cds::urcu::exempt_ptr for explanation.
- @note Before reusing \p result object you should call its \p release() method.
- */
- bool extract_max( exempt_ptr& result )
+ The item will be implicitly freed when the returned object is destroyed or when
+ its \p release() member function is called.
+ */
+ exempt_ptr extract_max()
{
- return base_class::do_extract_max(result);
+ return exempt_ptr( base_class::do_extract_max());
}
/// Find the key \p key
static CDS_CONSTEXPR const bool c_bExtractLockExternal = base_class::c_bExtractLockExternal;
/// pointer to extracted node
- typedef cds::urcu::exempt_ptr< gc, node_type, value_type, typename maker::intrusive_traits::disposer > exempt_ptr;
+ using exempt_ptr = cds::urcu::exempt_ptr< gc, node_type, value_type, typename maker::intrusive_traits::disposer >;
protected:
//@cond
/// Extracts the item from the set with specified \p key
/** \anchor cds_nonintrusive_SkipListSet_rcu_extract
The function searches an item with key equal to \p key in the set,
- unlinks it from the set, and returns it in \p result parameter.
- If the item with key equal to \p key is not found the function returns \p false.
+ unlinks it from the set, and returns \ref cds::urcu::exempt_ptr "exempt_ptr" pointer to the item found.
+ If the item is not found the function returns an empty \p exempt_ptr
Note the compare functor from \p Traits class' template argument
should accept a parameter of type \p Q that can be not the same as \p value_type.
RCU \p synchronize method can be called. RCU should NOT be locked.
+
The function does not free the item found.
- The item will be implicitly freed when \p result object is destroyed or when
- <tt>result.release()</tt> is called, see \p cds::urcu::exempt_ptr for explanation.
- @note Before reusing \p result object you should call its \p release() method.
+ The item will be implicitly freed when the returned object is destroyed or when
+ its \p release() member function is called.
*/
template <typename Q>
- bool extract( exempt_ptr& result, Q const& key )
+ exempt_ptr extract( Q const& key )
{
- return base_class::do_extract( result, key );
+ return exempt_ptr( base_class::do_extract( key ));
}
/// Extracts the item from the set with comparing functor \p pred
\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& result, Q const& key, Less pred )
+ exempt_ptr extract_with( Q const& key, Less pred )
{
- return base_class::do_extract_with( result, key, cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor >());
+ return exempt_ptr( base_class::do_extract_with( key, cds::details::predicate_wrapper< node_type, Less, typename maker::value_accessor >()));
}
/// Extracts an item with minimal key from the set
/**
- The function searches an item with minimal key, unlinks it, and returns the item found in \p result parameter.
- If the skip-list is empty the function returns \p false.
+ The function searches an item with minimal key, unlinks it,
+ and returns \ref cds::urcu::exempt_ptr "exempt_ptr" pointer to the item.
+ If the skip-list is empty the function returns an empty \p exempt_ptr.
RCU \p synchronize method can be called. RCU should NOT be locked.
+
The function does not free the item found.
- The item will be implicitly freed when \p result object is destroyed or when
- <tt>result.release()</tt> is called, see cds::urcu::exempt_ptr for explanation.
- @note Before reusing \p result object you should call its \p release() method.
+ The item will be implicitly freed when the returned object is destroyed or when
+ its \p release() member function is called.
*/
- bool extract_min( exempt_ptr& result )
+ exempt_ptr extract_min()
{
- return base_class::do_extract_min(result);
+ return exempt_ptr( base_class::do_extract_min());
}
/// Extracts an item with maximal key from the set
/**
- The function searches an item with maximal key, unlinks it from the set, and returns the item found
- in \p result parameter. If the skip-list is empty the function returns \p false.
+ The function searches an item with maximal key, unlinks it from the set,
+ and returns \ref cds::urcu::exempt_ptr "exempt_ptr" pointer to the item.
+ If the skip-list is empty the function returns an empty \p exempt_ptr.
RCU \p synchronize method can be called. RCU should NOT be locked.
+
The function does not free the item found.
- The item will be implicitly freed when \p result object is destroyed or when
- <tt>result.release()</tt> is called, see cds::urcu::exempt_ptr for explanation.
- @note Before reusing \p result object you should call its \p release() method.
+ The item will be implicitly freed when the returned object is destroyed or when
+ its \p release() member function is called.
*/
- bool extract_max(exempt_ptr& result)
+ exempt_ptr extract_max()
{
- return base_class::do_extract_max(result);
+ return exempt_ptr( base_class::do_extract_max());
}
/// Find the key \p val
//@endcond
public:
- typedef cds::urcu::exempt_ptr< gc, value_type, value_type, node_disposer, void > exempt_ptr; ///< pointer to extracted node
+ using exempt_ptr = cds::urcu::exempt_ptr< gc, value_type, value_type, node_disposer, void >; ///< pointer to extracted node
protected:
//@cond
return pDel ? node_traits::to_value_ptr( pDel ) : nullptr;
}
- template <typename ExemptPtr, typename Q>
- bool do_extract( ExemptPtr& result, Q const& key )
+ template <typename Q>
+ value_type * do_extract( Q const& key )
{
check_deadlock_policy::check();
-
- bool bReturn;
+ value_type * pDel = nullptr;
{
rcu_lock l;
- value_type * pDel = do_extract_key( key, key_comparator() );
- bReturn = pDel != nullptr;
- if ( bReturn )
- result = pDel;
+ pDel = do_extract_key( key, key_comparator() );
}
dispose_deferred();
- return bReturn;
+ return pDel;
}
- template <typename ExemptPtr, typename Q, typename Less>
- bool do_extract_with( ExemptPtr& result, Q const& key, Less pred )
+ template <typename Q, typename Less>
+ value_type * do_extract_with( Q const& key, Less pred )
{
check_deadlock_policy::check();
+ value_type * pDel = nullptr;
- bool bReturn;
{
rcu_lock l;
- value_type * pDel = do_extract_key( key, cds::opt::details::make_comparator_from_less<Less>() );
- bReturn = pDel != nullptr;
- if ( bReturn )
- result = pDel;
+ pDel = do_extract_key( key, cds::opt::details::make_comparator_from_less<Less>() );
}
dispose_deferred();
- return bReturn;
+ return pDel;
}
- node_type * do_extract_min()
+ value_type * do_extract_min()
{
- assert( gc::is_locked() );
+ assert( !gc::is_locked() );
position pos;
node_type * pDel;
- if ( !find_min_position( pos ) ) {
- m_Stat.onExtractMinFailed();
- pDel = nullptr;
- }
- else {
- pDel = pos.pCur;
- unsigned int const nHeight = pDel->height();
+ {
+ rcu_lock l;
- if ( try_remove_at( pDel, pos, [](value_type const&) {}, true )) {
- --m_ItemCounter;
- m_Stat.onRemoveNode( nHeight );
- m_Stat.onExtractMinSuccess();
- }
- else {
+ if ( !find_min_position( pos ) ) {
m_Stat.onExtractMinFailed();
pDel = nullptr;
}
- }
-
- defer_chain( pos );
- return pDel;
- }
+ else {
+ pDel = pos.pCur;
+ unsigned int const nHeight = pDel->height();
- template <typename ExemptPtr>
- bool do_extract_min( ExemptPtr& result )
- {
- check_deadlock_policy::check();
+ if ( try_remove_at( pDel, pos, []( value_type const& ) {}, true ) ) {
+ --m_ItemCounter;
+ m_Stat.onRemoveNode( nHeight );
+ m_Stat.onExtractMinSuccess();
+ }
+ else {
+ m_Stat.onExtractMinFailed();
+ pDel = nullptr;
+ }
+ }
- bool bReturn;
- {
- rcu_lock l;
- node_type * pDel = do_extract_min();
- bReturn = pDel != nullptr;
- if ( bReturn )
- result = node_traits::to_value_ptr(pDel);
+ defer_chain( pos );
}
dispose_deferred();
- return bReturn;
+ return pDel ? node_traits::to_value_ptr( pDel ) : nullptr;
}
- node_type * do_extract_max()
+ value_type * do_extract_max()
{
- assert( gc::is_locked() );
+ assert( !gc::is_locked() );
position pos;
node_type * pDel;
- if ( !find_max_position( pos ) ) {
- m_Stat.onExtractMaxFailed();
- pDel = nullptr;
- }
- else {
- pDel = pos.pCur;
- unsigned int const nHeight = pDel->height();
+ {
+ rcu_lock l;
- if ( try_remove_at( pDel, pos, [](value_type const&) {}, true )) {
- --m_ItemCounter;
- m_Stat.onRemoveNode( nHeight );
- m_Stat.onExtractMaxSuccess();
- }
- else {
+ if ( !find_max_position( pos ) ) {
m_Stat.onExtractMaxFailed();
pDel = nullptr;
}
- }
-
- defer_chain( pos );
- return pDel;
- }
+ else {
+ pDel = pos.pCur;
+ unsigned int const nHeight = pDel->height();
- template <typename ExemptPtr>
- bool do_extract_max( ExemptPtr& result )
- {
- check_deadlock_policy::check();
+ if ( try_remove_at( pDel, pos, []( value_type const& ) {}, true ) ) {
+ --m_ItemCounter;
+ m_Stat.onRemoveNode( nHeight );
+ m_Stat.onExtractMaxSuccess();
+ }
+ else {
+ m_Stat.onExtractMaxFailed();
+ pDel = nullptr;
+ }
+ }
- bool bReturn;
- {
- rcu_lock l;
- node_type * pDel = do_extract_max();
- bReturn = pDel != nullptr;
- if ( bReturn )
- result = node_traits::to_value_ptr(pDel);
+ defer_chain( pos );
}
dispose_deferred();
- return bReturn;
+ return pDel ? node_traits::to_value_ptr( pDel ) : nullptr;
}
void increase_height( unsigned int nHeight )
/// Extracts the item from the set with specified \p key
/** \anchor cds_intrusive_SkipListSet_rcu_extract
The function searches an item with key equal to \p key in the set,
- unlinks it from the set, places it to \p result parameter, and returns \p true.
- If the item with key equal to \p key is not found the function returns \p false.
+ unlinks it from the set, and returns \ref cds::urcu::exempt_ptr "exempt_ptr" pointer to the item found.
+ If the item with key equal to \p key is not found the function returns an empty \p exempt_ptr.
Note the compare functor should accept a parameter of type \p Q that can be not the same as \p value_type.
RCU \p synchronize method can be called. RCU should NOT be locked.
The function does not call the disposer for the item found.
- The disposer will be implicitly invoked when \p result object is destroyed or when
- <tt>result.release()</tt> is called, see cds::urcu::exempt_ptr for explanation.
- @note Before reusing \p result object you should call its \p release() method.
+ The disposer will be implicitly invoked when the returned object is destroyed or when
+ its \p release() member function is called.
Example:
\code
typedef cds::intrusive::SkipListSet< cds::urcu::gc< cds::urcu::general_buffered<> >, foo, my_traits > skip_list;
skip_list theList;
// ...
- typename skip_list::exempt_ptr ep;
- if ( theList.extract( ep, 5 ) ) {
+ typename skip_list::exempt_ptr ep( theList.extract( 5 ));
+ if ( ep ) {
// Deal with ep
//...
\endcode
*/
template <typename Q>
- bool extract( exempt_ptr& result, Q const& key )
+ exempt_ptr extract( Q const& key )
{
- return do_extract( result, key );
+ return exempt_ptr( do_extract( key ));
}
/// Extracts the item from the set with comparing functor \p pred
\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& result, Q const& key, Less pred )
+ exempt_ptr extract_with( Q const& key, Less pred )
{
- return do_extract_with( result, key, pred );
+ return exempt_ptr( do_extract_with( key, pred ));
}
/// Extracts an item with minimal key from the list
/**
- The function searches an item with minimal key, unlinks it, and returns the item found in \p result parameter.
- If the skip-list is empty the function returns \p false.
+ The function searches an item with minimal key, unlinks it, and returns \ref cds::urcu::exempt_ptr "exempt_ptr" pointer to the item.
+ If the skip-list is empty the function returns an empty \p exempt_ptr.
RCU \p synchronize method can be called. RCU should NOT be locked.
The function does not call the disposer for the item found.
- The disposer will be implicitly invoked when \p result object is destroyed or when
- <tt>result.release()</tt> is called, see cds::urcu::exempt_ptr for explanation.
- @note Before reusing \p result object you should call its \p release() method.
+ The disposer will be implicitly invoked when the returned object is destroyed or when
+ its \p release() member function is manually called.
Example:
\code
typedef cds::intrusive::SkipListSet< cds::urcu::gc< cds::urcu::general_buffered<> >, foo, my_traits > skip_list;
skip_list theList;
// ...
- typename skip_list::exempt_ptr ep;
- if ( theList.extract_min(ep)) {
+ typename skip_list::exempt_ptr ep(theList.extract_min());
+ if ( ep ) {
// Deal with ep
//...
During unlinking, a concurrent thread may insert an item with key less than leftmost item's key.
So, the function returns the item with minimum key at the moment of list traversing.
*/
- bool extract_min( exempt_ptr& result )
+ exempt_ptr extract_min()
{
- return do_extract_min( result );
+ return exempt_ptr( do_extract_min());
}
/// Extracts an item with maximal key from the list
/**
- The function searches an item with maximal key, unlinks it, and returns the item found in \p result parameter.
- If the skip-list is empty the function returns \p false.
+ The function searches an item with maximal key, unlinks it, and returns \ref cds::urcu::exempt_ptr "exempt_ptr" pointer to the item.
+ If the skip-list is empty the function returns an empty \p exempt_ptr.
RCU \p synchronize method can be called. RCU should NOT be locked.
The function does not call the disposer for the item found.
- The disposer will be implicitly invoked when \p result object is destroyed or when
- <tt>result.release()</tt> is called, see cds::urcu::exempt_ptr for explanation.
- @note Before reusing \p result object you should call its \p release() method.
+ The disposer will be implicitly invoked when the returned object is destroyed or when
+ its \p release() member function is manually called.
Example:
\code
typedef cds::intrusive::SkipListSet< cds::urcu::gc< cds::urcu::general_buffered<> >, foo, my_traits > skip_list;
skip_list theList;
// ...
- typename skip_list::exempt_ptr ep;
- if ( theList.extract_max(ep) ) {
+ typename skip_list::exempt_ptr ep( theList.extract_max() );
+ if ( ep ) {
// Deal with ep
//...
// Dispose returned item.
During unlinking, a concurrent thread can insert an item with key greater than rightmost item's key.
So, the function returns the item with maximum key at the moment of list traversing.
*/
- bool extract_max( exempt_ptr& result )
+ exempt_ptr extract_max()
{
- return do_extract_max( result );
+ return exempt_ptr( do_extract_max());
}
/// Deletes the item from the set
void clear()
{
exempt_ptr ep;
- while ( extract_min(ep) )
- ep.release();
+ while ( (ep = extract_min()) );
}
/// Returns maximum height of skip-list. The max height is a constant for each object and does not exceed 32.
CPPUNIT_CHECK( pVal->second.m_val == nKey * 2 );
}
- CPPUNIT_ASSERT( m.extract( ep, nKey ));
+ ep = m.extract( nKey );
+ CPPUNIT_ASSERT( ep );
CPPUNIT_ASSERT( !ep.empty() );
CPPUNIT_CHECK( ep->first == nKey );
CPPUNIT_CHECK( ep->second.m_val == nKey * 2 );
- ep.release();
{
rcu_lock l;
CPPUNIT_CHECK( m.get( nKey ) == nullptr );
}
- CPPUNIT_CHECK( !m.extract(ep, nKey) );
+ ep = m.extract( nKey );
+ CPPUNIT_CHECK( !ep );
}
CPPUNIT_ASSERT( m.empty() );
CPPUNIT_CHECK( pVal->second.m_val == nKey * 2 );
}
- CPPUNIT_ASSERT( m.extract_with( ep, wrapped_item(nKey), wrapped_less() ));
+ ep = m.extract_with( wrapped_item( nKey ), wrapped_less() );
+ CPPUNIT_ASSERT( ep );
CPPUNIT_ASSERT( !ep.empty() );
CPPUNIT_CHECK( ep->first == nKey );
CPPUNIT_CHECK( ep->second.m_val == nKey * 2 );
- ep.release();
{
rcu_lock l;
CPPUNIT_CHECK( m.get_with( wrapped_item(nKey), wrapped_less() ) == nullptr );
}
- CPPUNIT_CHECK( !m.extract_with(ep, wrapped_item(nKey), wrapped_less()) );
+ ep = m.extract_with( wrapped_item( nKey ), wrapped_less() );
+ CPPUNIT_CHECK( !ep );
}
CPPUNIT_ASSERT( m.empty() );
for ( int i = 0; i < nLimit; ++i )
CPPUNIT_ASSERT( m.insert(arrItem[i], arrItem[i]*2) );
for ( int i = 0; i < nLimit; ++i ) {
- CPPUNIT_ASSERT( m.extract_min(ep));
+ ep = m.extract_min();
+ CPPUNIT_ASSERT( ep );
CPPUNIT_ASSERT( !ep.empty() );
CPPUNIT_CHECK( ep->first == i );
CPPUNIT_CHECK( ep->second.m_val == i * 2 );
- ep.release();
}
CPPUNIT_ASSERT( m.empty() );
- CPPUNIT_CHECK( !m.extract_min(ep) );
+ ep = m.extract_min();
+ CPPUNIT_CHECK( !ep );
// extract_max
for ( int i = 0; i < nLimit; ++i )
CPPUNIT_ASSERT( m.insert(arrItem[i], arrItem[i]*2) );
for ( int i = nLimit-1; i >= 0; --i ) {
- CPPUNIT_ASSERT( m.extract_max(ep));
+ ep = m.extract_max();
+ CPPUNIT_ASSERT( ep );
CPPUNIT_ASSERT( !ep.empty() );
CPPUNIT_CHECK( ep->first == i );
CPPUNIT_CHECK( ep->second.m_val == i * 2 );
- ep.release();
}
CPPUNIT_ASSERT( m.empty() );
- CPPUNIT_CHECK( !m.extract_max(ep) );
+ ep = m.extract_max();
+ CPPUNIT_CHECK( !ep );
}
CPPUNIT_MSG( PrintStat()(m, nullptr) );
pVal->nVal *= 2;
}
- CPPUNIT_ASSERT( s.extract( ep, i ));
+ ep = s.extract( i );
+ CPPUNIT_ASSERT( ep );
CPPUNIT_ASSERT( !ep.empty() );
CPPUNIT_CHECK( ep->nKey == i );
CPPUNIT_CHECK( ep->nVal == i * 4 );
- ep.release();
+ //ep.release();
{
rcu_lock l;
CPPUNIT_CHECK( s.get( i ) == nullptr );
}
- CPPUNIT_CHECK( !s.extract( ep, i ) );
+ ep = s.extract( i );
+ CPPUNIT_CHECK( !ep );
CPPUNIT_ASSERT( ep.empty() );
}
CPPUNIT_CHECK( s.empty() );
pVal->nVal *= 2;
}
- CPPUNIT_ASSERT( s.extract_with( ep, other_key(i), other_key_less<typename Set::value_type>() ));
+ ep = s.extract_with( other_key( i ), other_key_less<typename Set::value_type>() );
+ CPPUNIT_ASSERT( ep );
CPPUNIT_ASSERT( !ep.empty() );
CPPUNIT_CHECK( ep->nKey == i );
CPPUNIT_CHECK( ep->nVal == i * 4 );
- ep.release();
+ //ep.release();
{
rcu_lock l;
CPPUNIT_CHECK( s.get_with( other_key( i ), other_key_less<typename Set::value_type>() ) == nullptr );
}
- CPPUNIT_CHECK( !s.extract_with( ep, other_key(i), other_key_less<typename Set::value_type>() ));
+ ep = s.extract_with( other_key( i ), other_key_less<typename Set::value_type>() );
+ CPPUNIT_CHECK( !ep );
}
CPPUNIT_CHECK( s.empty() );
}
fill_skiplist( s, v );
int nPrevKey;
- CPPUNIT_ASSERT( s.extract_min(ep));
+ ep = s.extract_min();
+ CPPUNIT_ASSERT( ep );
CPPUNIT_ASSERT( !ep.empty());
nPrevKey = ep->nKey;
- ep.release();
+ //ep.release();
while ( !s.empty() ) {
- CPPUNIT_ASSERT( s.extract_min(ep) );
+ ep = s.extract_min();
+ CPPUNIT_ASSERT( ep );
CPPUNIT_ASSERT( !ep.empty());
CPPUNIT_CHECK( ep->nKey == nPrevKey + 1 );
CPPUNIT_CHECK( ep->nVal == (nPrevKey + 1) * 2 );
nPrevKey = ep->nKey;
- ep.release();
+ //ep.release();
}
- CPPUNIT_CHECK( !s.extract_min(ep) );
- CPPUNIT_CHECK( !s.extract_max(ep) );
+ ep = s.extract_min();
+ CPPUNIT_CHECK( !ep );
+ CPPUNIT_CHECK( !s.extract_max() );
}
Set::gc::force_dispose();
fill_skiplist( s, v );
int nPrevKey;
- CPPUNIT_ASSERT( s.extract_max(ep));
+ ep = s.extract_max();
+ CPPUNIT_ASSERT( ep );
CPPUNIT_ASSERT( !ep.empty());
nPrevKey = ep->nKey;
- ep.release();
+ //ep.release();
while ( !s.empty() ) {
- CPPUNIT_ASSERT( s.extract_max(ep));
+ ep = s.extract_max();
+ CPPUNIT_ASSERT( ep );
CPPUNIT_ASSERT( !ep.empty());
CPPUNIT_CHECK( ep->nKey == nPrevKey - 1 );
CPPUNIT_CHECK( ep->nVal == (nPrevKey - 1) * 2 );
nPrevKey = ep->nKey;
- ep.release();
+ //ep.release();
}
+ ep = s.extract_min();
+ CPPUNIT_CHECK( !ep );
+ CPPUNIT_CHECK( !s.extract_max() );
}
Set::gc::force_dispose();
- CPPUNIT_CHECK( !s.extract_min(ep) );
- CPPUNIT_CHECK( !s.extract_max(ep) );
}
CPPUNIT_MSG( PrintStat()(s, nullptr) );
CPPUNIT_CHECK( pVal->nVal == nKey * 2 );
}
- CPPUNIT_ASSERT( s.extract( ep, nKey ));
+ ep = s.extract( nKey );
+ CPPUNIT_ASSERT( ep );
CPPUNIT_ASSERT( !ep.empty() );
CPPUNIT_CHECK( ep->nKey == nKey );
CPPUNIT_CHECK( ep->nVal == nKey * 2 );
- ep.release();
{
rcu_lock l;
CPPUNIT_CHECK( s.get( nKey ) == nullptr );
}
- CPPUNIT_CHECK( !s.extract( ep, nKey ));
+ ep = s.extract( nKey );
+ CPPUNIT_CHECK( !ep );
}
CPPUNIT_CHECK( s.empty());
CPPUNIT_CHECK( pVal->nVal == nKey );
}
- CPPUNIT_ASSERT( s.extract_with( ep, wrapped_item(nKey), wrapped_less() ));
+ ep = s.extract_with( wrapped_item( nKey ), wrapped_less() );
+ CPPUNIT_ASSERT( ep );
CPPUNIT_ASSERT( !ep.empty() );
CPPUNIT_CHECK( ep->nKey == nKey );
CPPUNIT_CHECK( ep->nVal == nKey );
- ep.release();
{
rcu_lock l;
CPPUNIT_CHECK( s.get_with( wrapped_item( nKey ), wrapped_less() ) == nullptr );
}
- CPPUNIT_CHECK( !s.extract_with( ep, wrapped_item(nKey), wrapped_less() ));
+ ep = s.extract_with( wrapped_item( nKey ), wrapped_less() );
+ CPPUNIT_CHECK( !ep );
}
CPPUNIT_CHECK( s.empty());
CPPUNIT_ASSERT( s.insert( arrRandom[i]) );
for ( int i = 0; i < nLimit; ++i ) {
- CPPUNIT_ASSERT( s.extract_min(ep) );
+ ep = s.extract_min();
+ CPPUNIT_ASSERT( ep );
CPPUNIT_ASSERT( !ep.empty() );
CPPUNIT_CHECK( ep->nKey == i );
CPPUNIT_CHECK( ep->nVal == i );
CPPUNIT_CHECK( !s.find(i) );
- ep.release();
}
CPPUNIT_CHECK( s.empty());
CPPUNIT_ASSERT( s.insert( arrRandom[i]) );
for ( int i = nLimit-1; i >= 0; --i ) {
- CPPUNIT_ASSERT( s.extract_max(ep) );
+ ep = s.extract_max();
+ CPPUNIT_ASSERT( ep );
CPPUNIT_ASSERT( !ep.empty() );
CPPUNIT_CHECK( ep->nKey == i );
CPPUNIT_CHECK( ep->nVal == i );
CPPUNIT_CHECK( !s.find(i) );
- ep.release();
}
CPPUNIT_CHECK( s.empty());
- CPPUNIT_CHECK( !s.extract_min(ep) );
- CPPUNIT_CHECK( !s.extract_max(ep) );
+ ep = s.extract_min();
+ CPPUNIT_CHECK( !ep );
+ CPPUNIT_CHECK( !s.extract_max() );
}
CPPUNIT_MSG( PrintStat()(s, nullptr) );
if ( Map::c_bExtractLockExternal ) {
{
typename Map::rcu_lock l;
- if ( rMap.extract_with( xp, arrData[i], key_less() )) {
+ xp = rMap.extract_with( arrData[i], key_less() );
+ if ( xp )
++m_nDeleteSuccess;
- }
else
++m_nDeleteFailed;
}
- xp.release();
}
else {
- if ( rMap.extract_with( xp, arrData[i], key_less() )) {
+ xp = rMap.extract_with( arrData[i], key_less() );
+ if ( xp )
++m_nDeleteSuccess;
- xp.release();
- }
else
++m_nDeleteFailed;
}
+ xp.release();
}
}
if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 )
if ( Map::c_bExtractLockExternal ) {
{
typename Map::rcu_lock l;
- if ( rMap.extract_with( xp, arrData[i], key_less() ))
+ xp = rMap.extract_with( arrData[i], key_less() );
+ if ( xp )
++m_nDeleteSuccess;
else
++m_nDeleteFailed;
}
- xp.release();
}
else {
- if ( rMap.extract_with( xp, arrData[i], key_less() )) {
+ xp = rMap.extract_with( arrData[i], key_less() );
+ if ( xp )
++m_nDeleteSuccess;
- xp.release();
- }
else
++m_nDeleteFailed;
}
+ xp.release();
}
}
if ( getTest().m_nInsThreadCount.load( atomics::memory_order_acquire ) == 0 )
if ( arrData[i] & 1 ) {
if ( Set::c_bExtractLockExternal ) {
typename Set::rcu_lock l;
- if ( rSet.extract_with( xp, arrData[i], key_less() ))
+ xp = rSet.extract_with( arrData[i], key_less() );
+ if ( xp )
++m_nExtractSuccess;
else
++m_nExtractFailed;
}
else {
- if ( rSet.extract_with( xp, arrData[i], key_less() ))
+ xp = rSet.extract_with( arrData[i], key_less() );
+ if ( xp )
++m_nExtractSuccess;
else
++m_nExtractFailed;
if ( arrData[i] & 1 ) {
if ( Set::c_bExtractLockExternal ) {
typename Set::rcu_lock l;
- if ( rSet.extract_with( xp, arrData[i], key_less() ))
+ xp = rSet.extract_with( arrData[i], key_less() );
+ if ( xp )
++m_nExtractSuccess;
else
++m_nExtractFailed;
}
else {
- if ( rSet.extract_with( xp, arrData[i], key_less() ))
+ xp = rSet.extract_with( arrData[i], key_less() );
+ if ( xp )
++m_nExtractSuccess;
else
++m_nExtractFailed;
if ( Set::c_bExtractLockExternal ) {
{
typename Set::rcu_lock l;
- if ( rSet.extract( xp, arrString[nItem % nArrSize] ) )
+ xp = rSet.extract( arrString[nItem % nArrSize] );
+ if ( xp )
++m_nDeleteSuccess;
else
++m_nDeleteFailed;
}
- xp.release();
}
else {
- if ( rSet.extract( xp, arrString[nItem % nArrSize] ) ) {
+ xp = rSet.extract( arrString[nItem % nArrSize] );
+ if ( xp )
++m_nDeleteSuccess;
- xp.release();
- }
else
++m_nDeleteFailed;
}
+ xp.release();
}
}
}
if ( Set::c_bExtractLockExternal ) {
{
typename Set::rcu_lock l;
- if ( rSet.extract( xp, arrString[nItem % nArrSize] ) )
+ xp = rSet.extract( arrString[nItem % nArrSize] );
+ if ( xp )
++m_nDeleteSuccess;
else
++m_nDeleteFailed;
}
- xp.release();
}
else {
- if ( rSet.extract( xp, arrString[nItem % nArrSize] ) ) {
+ xp = rSet.extract( arrString[nItem % nArrSize] );
+ if ( xp )
++m_nDeleteSuccess;
- xp.release();
- }
else
++m_nDeleteFailed;
}
+ xp.release();
}
}
}