+
+ private:
+ //@cond
+ bool insert_at_locked( position& pos, value_type& val )
+ {
+ // RCU lock should be locked!!!
+ assert( gc::is_locked() );
+
+ while ( true ) {
+ if ( search( pos.refHead, val, pos, key_comparator() )) {
+ m_Stat.onInsertFailed();
+ return false;
+ }
+
+ if ( link_node( node_traits::to_node_ptr( val ), pos ) ) {
+ ++m_ItemCounter;
+ m_Stat.onInsertSuccess();
+ return true;
+ }
+
+ // clear next field
+ node_traits::to_node_ptr( val )->m_pNext.store( marked_node_ptr(), memory_model::memory_order_relaxed );
+ m_Stat.onInsertRetry();
+ }
+ }
+
+ template <typename Func>
+ std::pair<iterator, bool> update_at_locked( position& pos, value_type& val, Func func, bool bInsert )
+ {
+ // RCU should be locked!!!
+ assert( gc::is_locked() );
+
+ while ( true ) {
+ if ( search( pos.refHead, val, pos, key_comparator() ) ) {
+ assert( key_comparator()( val, *node_traits::to_value_ptr( *pos.pCur ) ) == 0 );
+
+ func( false, *node_traits::to_value_ptr( *pos.pCur ), val );
+ m_Stat.onUpdateExisting();
+ return std::make_pair( iterator( pos.pCur ), false );
+ }
+ else {
+ if ( !bInsert ) {
+ m_Stat.onUpdateFailed();
+ return std::make_pair( end(), false );
+ }
+
+ if ( link_node( node_traits::to_node_ptr( val ), pos ) ) {
+ ++m_ItemCounter;
+ func( true, val , val );
+ m_Stat.onUpdateNew();
+ return std::make_pair( iterator( node_traits::to_node_ptr( val )), true );
+ }
+
+ // clear the next field
+ node_traits::to_node_ptr( val )->m_pNext.store( marked_node_ptr(), memory_model::memory_order_relaxed );
+ m_Stat.onUpdateRetry();
+ }
+ }
+ }
+
+ template <typename Q, typename Compare>
+ const_iterator find_at_locked( position& pos, Q const& val, Compare cmp )
+ {
+ assert( gc::is_locked() );
+
+ if ( search( pos.refHead, val, pos, cmp ) ) {
+ assert( pos.pCur != nullptr );
+ m_Stat.onFindSuccess();
+ return const_iterator( pos.pCur );
+ }
+
+ m_Stat.onFindFailed();
+ return cend();
+ }
+ //@endcond