event_counter m_nFindWaitShrinking; ///< Count of waiting until shrinking completed duting \p find() call
event_counter m_nInsertSuccess; ///< Count of inserting data node
+ event_counter m_nInsertFailed; ///< Count of insert failures
event_counter m_nRelaxedInsertFailed; ///< Count of false creating of data nodes (only if @ref bronson_avltree::relaxed_insert "relaxed insertion" is enabled)
event_counter m_nInsertRetry; ///< Count of insert retries via concurrent operations
event_counter m_nUpdateWaitShrinking; ///< Count of waiting until shrinking completed during \p update() call
void onFindRetry() { ++m_nFindRetry ; }
void onFindWaitShrinking() { ++m_nFindWaitShrinking; }
- void onInsertSuccess() { ++m_nInsertSuccess ; }
+ void onInsertSuccess() { ++m_nInsertSuccess; }
+ void onInsertFailed() { ++m_nInsertFailed; }
void onRelaxedInsertFailed() { ++m_nRelaxedInsertFailed; }
void onInsertRetry() { ++m_nInsertRetry ; }
void onUpdateWaitShrinking() { ++m_nUpdateWaitShrinking; }
void onFindWaitShrinking() const {}
void onInsertSuccess() const {}
+ void onInsertFailed() const {}
void onRelaxedInsertFailed() const {}
void onInsertRetry() const {}
void onUpdateWaitShrinking() const {}
assert( nVersion != node_type::unlinked );
int nCmp = cmp( key, pNode->m_key );
- if ( nCmp == 0 ) {
- if ( nFlags & update_flags::allow_update )
- return try_update_node( funcUpdate, pNode, nVersion, disp );
- return update_flags::failed;
- }
+ if ( nCmp == 0 )
+ return try_update_node( nFlags, funcUpdate, pNode, nVersion, disp );
while ( true ) {
int result;
}
template <typename Func>
- int try_update_node( Func funcUpdate, node_type * pNode, version_type nVersion, rcu_disposer& disp )
+ int try_update_node( int nFlags, Func funcUpdate, node_type * pNode, version_type nVersion, rcu_disposer& disp )
{
mapped_type pOld;
assert( pNode != nullptr );
return update_flags::retry;
}
+ if ( pNode->is_valued( memory_model::memory_order_relaxed ) && !(nFlags & update_flags::allow_update) ) {
+ m_stat.onInsertFailed();
+ return update_flags::failed;
+ }
+
+
pOld = pNode->value( memory_model::memory_order_relaxed );
mapped_type pVal = funcUpdate( pNode );
if ( pVal == pOld )
<< "\t\t m_nFindRetry: " << s.m_nFindRetry.get() << "\n"
<< "\t\t m_nFindWaitShrinking: " << s.m_nFindWaitShrinking.get() << "\n"
<< "\t\t m_nInsertSuccess: " << s.m_nInsertSuccess.get() << "\n"
+ << "\t\t m_nInsertFailed: " << s.m_nInsertFailed.get() << "\n"
<< "\t\t m_nRelaxedInsertFailed: " << s.m_nRelaxedInsertFailed.get() << "\n"
<< "\t\t m_nInsertRetry: " << s.m_nInsertRetry.get() << "\n"
<< "\t\t m_nUpdateWaitShrinking: " << s.m_nUpdateWaitShrinking.get() << "\n"