if ( pChild ) {
version_type nChildVersion = pChild->version( memory_model::memory_order_relaxed );
if ( nChildVersion & node_type::shrinking ) {
if ( pChild ) {
version_type nChildVersion = pChild->version( memory_model::memory_order_relaxed );
if ( nChildVersion & node_type::shrinking ) {
pChild->template wait_until_shrink_completed<back_off>( memory_model::memory_order_relaxed );
result = update_flags::retry;
}
pChild->template wait_until_shrink_completed<back_off>( memory_model::memory_order_relaxed );
result = update_flags::retry;
}
result = try_update( key, cmp, nFlags, funcUpdate, m_pRoot, pChild, nChildVersion, disp );
}
}
result = try_update( key, cmp, nFlags, funcUpdate, m_pRoot, pChild, nChildVersion, disp );
}
}
// insert into tree as right child of the root
{
node_scoped_lock l( m_Monitor, *m_pRoot );
// insert into tree as right child of the root
{
node_scoped_lock l( m_Monitor, *m_pRoot );
node_type * pNew = alloc_node( key, 1, 0, m_pRoot, nullptr, nullptr );
mapped_type pVal = funcUpdate( pNew );
assert( pVal != nullptr );
pNew->m_pValue.store( pVal, memory_model::memory_order_release );
node_type * pNew = alloc_node( key, 1, 0, m_pRoot, nullptr, nullptr );
mapped_type pVal = funcUpdate( pNew );
assert( pVal != nullptr );
pNew->m_pValue.store( pVal, memory_model::memory_order_release );
if ( pChild ) {
version_type nChildVersion = pChild->version( memory_model::memory_order_relaxed );
if ( nChildVersion & node_type::shrinking ) {
if ( pChild ) {
version_type nChildVersion = pChild->version( memory_model::memory_order_relaxed );
if ( nChildVersion & node_type::shrinking ) {
pChild->template wait_until_shrink_completed<back_off>( memory_model::memory_order_relaxed );
result = update_flags::retry;
}
pChild->template wait_until_shrink_completed<back_off>( memory_model::memory_order_relaxed );
result = update_flags::retry;
}
result = try_remove( key, cmp, func, m_pRoot, pChild, nChildVersion, disp );
}
}
result = try_remove( key, cmp, func, m_pRoot, pChild, nChildVersion, disp );
}
}
pNode->child( pNew, nDir, memory_model::memory_order_relaxed );
pDamaged = fix_height_locked( pNode );
}
pNode->child( pNew, nDir, memory_model::memory_order_relaxed );
pDamaged = fix_height_locked( pNode );
}
m_stat.onInsertSuccess();
fix_height_and_rebalance( pDamaged, disp );
m_stat.onInsertSuccess();
fix_height_and_rebalance( pDamaged, disp );
- if ( pNode->child( -1 ).load( atomics::memory_order_relaxed ) == nullptr
- || pNode->child( 1 ).load( atomics::memory_order_relaxed ) == nullptr )
+ if ( pNode->child( left_child ).load( atomics::memory_order_relaxed ) == nullptr
+ || pNode->child( right_child ).load( atomics::memory_order_relaxed ) == nullptr )
- func( pOld ); // calls pOld disposer inside
- m_stat.onDisposeValue();
+ --m_ItemCounter;
+ if ( func( pOld )) // calls pOld disposer inside
+ m_stat.onDisposeValue();
+ else
+ m_stat.onExtractValue();
// pParent and pNode must be locked
assert( !pParent->is_unlinked(memory_model::memory_order_relaxed) );
// pParent and pNode must be locked
assert( !pParent->is_unlinked(memory_model::memory_order_relaxed) );
- node_type * pParentLeft = child( pParent, -1, memory_model::memory_order_relaxed );
- node_type * pParentRight = child( pParent, 1, memory_model::memory_order_relaxed );
+ node_type * pParentLeft = child( pParent, left_child, memory_model::memory_order_relaxed );
+ node_type * pParentRight = child( pParent, right_child, memory_model::memory_order_relaxed );
assert( !pNode->is_unlinked( memory_model::memory_order_relaxed ) );
assert( pParent == parent( pNode, memory_model::memory_order_relaxed));
assert( !pNode->is_unlinked( memory_model::memory_order_relaxed ) );
assert( pParent == parent( pNode, memory_model::memory_order_relaxed));
- node_type * pLeft = child( pNode, -1, memory_model::memory_order_relaxed );
- node_type * pRight = child( pNode, 1, memory_model::memory_order_relaxed );
+ node_type * pLeft = child( pNode, left_child, memory_model::memory_order_relaxed );
+ node_type * pRight = child( pNode, right_child, memory_model::memory_order_relaxed );
- node_type * pLeft = child( pNode, -1, memory_model::memory_order_relaxed );
- node_type * pRight = child( pNode, 1, memory_model::memory_order_relaxed );
+ node_type * pLeft = child( pNode, left_child, memory_model::memory_order_relaxed );
+ node_type * pRight = child( pNode, right_child, memory_model::memory_order_relaxed );
// pParent and pNode should be locked.
// Returns a damaged node, or nullptr if no more rebalancing is necessary
assert( parent( pNode, memory_model::memory_order_relaxed ) == pParent );
// pParent and pNode should be locked.
// Returns a damaged node, or nullptr if no more rebalancing is necessary
assert( parent( pNode, memory_model::memory_order_relaxed ) == pParent );
- assert( child( pParent, -1, memory_model::memory_order_relaxed ) == pNode
- || child( pParent, 1, memory_model::memory_order_relaxed ) == pNode );
+ assert( child( pParent, left_child, memory_model::memory_order_relaxed ) == pNode
+ || child( pParent, right_child, memory_model::memory_order_relaxed ) == pNode );
- node_type * pLeft = child( pNode, -1, memory_model::memory_order_relaxed );
- node_type * pRight = child( pNode, 1, memory_model::memory_order_relaxed );
+ node_type * pLeft = child( pNode, left_child, memory_model::memory_order_relaxed );
+ node_type * pRight = child( pNode, right_child, memory_model::memory_order_relaxed );
if ( (pLeft == nullptr || pRight == nullptr) && !pNode->is_valued( memory_model::memory_order_relaxed )) {
if ( try_unlink_locked( pParent, pNode, disp ))
if ( (pLeft == nullptr || pRight == nullptr) && !pNode->is_valued( memory_model::memory_order_relaxed )) {
if ( try_unlink_locked( pParent, pNode, disp ))
node_type * rebalance_to_right_locked( node_type * pParent, node_type * pNode, node_type * pLeft, int hR )
{
assert( parent( pNode, memory_model::memory_order_relaxed ) == pParent );
node_type * rebalance_to_right_locked( node_type * pParent, node_type * pNode, node_type * pLeft, int hR )
{
assert( parent( pNode, memory_model::memory_order_relaxed ) == pParent );
- assert( child( pParent, -1, memory_model::memory_order_relaxed ) == pNode
- || child( pParent, 1, memory_model::memory_order_relaxed ) == pNode );
+ assert( child( pParent, left_child, memory_model::memory_order_relaxed ) == pNode
+ || child( pParent, right_child, memory_model::memory_order_relaxed ) == pNode );
// pParent and pNode is locked yet
// pNode->pLeft is too large, we will rotate-right.
// pParent and pNode is locked yet
// pNode->pLeft is too large, we will rotate-right.
if ( hLL > hLR )
return rotate_right_locked( pParent, pNode, pLeft, hR, hLL, pLRight, hLR );
if ( hLL > hLR )
return rotate_right_locked( pParent, pNode, pLeft, hR, hLL, pLRight, hLR );
int hLRL = pLRLeft ? pLRLeft->height( memory_model::memory_order_relaxed ) : 0;
int balance = hLL - hLRL;
if ( balance >= -1 && balance <= 1 && !((hLL == 0 || hLRL == 0) && !pLeft->is_valued(memory_model::memory_order_relaxed))) {
int hLRL = pLRLeft ? pLRLeft->height( memory_model::memory_order_relaxed ) : 0;
int balance = hLL - hLRL;
if ( balance >= -1 && balance <= 1 && !((hLL == 0 || hLRL == 0) && !pLeft->is_valued(memory_model::memory_order_relaxed))) {
node_type * rebalance_to_left_locked( node_type * pParent, node_type * pNode, node_type * pRight, int hL )
{
assert( parent( pNode, memory_model::memory_order_relaxed ) == pParent );
node_type * rebalance_to_left_locked( node_type * pParent, node_type * pNode, node_type * pRight, int hL )
{
assert( parent( pNode, memory_model::memory_order_relaxed ) == pParent );
- assert( child( pParent, -1, memory_model::memory_order_relaxed ) == pNode
- || child( pParent, 1, memory_model::memory_order_relaxed ) == pNode );
+ assert( child( pParent, left_child, memory_model::memory_order_relaxed ) == pNode
+ || child( pParent, right_child, memory_model::memory_order_relaxed ) == pNode );
int hRR = pRRight ? pRRight->height( memory_model::memory_order_relaxed ) : 0;
if ( hRR > hRL )
return rotate_left_locked( pParent, pNode, hL, pRight, pRLeft, hRL, hRR );
int hRR = pRRight ? pRRight->height( memory_model::memory_order_relaxed ) : 0;
if ( hRR > hRL )
return rotate_left_locked( pParent, pNode, hL, pRight, pRLeft, hRL, hRR );
if ( hRR >= hRL )
return rotate_left_locked( pParent, pNode, hL, pRight, pRLeft, hRL, hRR );
if ( hRR >= hRL )
return rotate_left_locked( pParent, pNode, hL, pRight, pRLeft, hRL, hRR );
int hRLR = pRLRight ? pRLRight->height( memory_model::memory_order_relaxed ) : 0;
int balance = hRR - hRLR;
if ( balance >= -1 && balance <= 1 && !((hRR == 0 || hRLR == 0) && !pRight->is_valued( memory_model::memory_order_relaxed )))
int hRLR = pRLRight ? pRLRight->height( memory_model::memory_order_relaxed ) : 0;
int balance = hRR - hRLR;
if ( balance >= -1 && balance <= 1 && !((hRR == 0 || hRLR == 0) && !pRight->is_valued( memory_model::memory_order_relaxed )))
node_type * rotate_right_locked( node_type * pParent, node_type * pNode, node_type * pLeft, int hR, int hLL, node_type * pLRight, int hLR )
{
version_type nodeVersion = pNode->version( memory_model::memory_order_relaxed );
node_type * rotate_right_locked( node_type * pParent, node_type * pNode, node_type * pLeft, int hR, int hLL, node_type * pLRight, int hLR )
{
version_type nodeVersion = pNode->version( memory_model::memory_order_relaxed );
node_type * rotate_left_locked( node_type * pParent, node_type * pNode, int hL, node_type * pRight, node_type * pRLeft, int hRL, int hRR )
{
version_type nodeVersion = pNode->version( memory_model::memory_order_relaxed );
node_type * rotate_left_locked( node_type * pParent, node_type * pNode, int hL, node_type * pRight, node_type * pRLeft, int hRL, int hRR )
{
version_type nodeVersion = pNode->version( memory_model::memory_order_relaxed );
version_type nodeVersion = pNode->version( memory_model::memory_order_relaxed );
version_type leftVersion = pLeft->version( memory_model::memory_order_relaxed );
version_type nodeVersion = pNode->version( memory_model::memory_order_relaxed );
version_type leftVersion = pLeft->version( memory_model::memory_order_relaxed );
- node_type * pPL = child( pParent, -1, memory_model::memory_order_relaxed );
- node_type * pLRL = child( pLRight, -1, memory_model::memory_order_relaxed );
- node_type * pLRR = child( pLRight, 1, memory_model::memory_order_relaxed );
+ node_type * pPL = child( pParent, left_child, memory_model::memory_order_relaxed );
+ node_type * pLRL = child( pLRight, left_child, memory_model::memory_order_relaxed );
+ node_type * pLRR = child( pLRight, right_child, memory_model::memory_order_relaxed );
int hLRR = pLRR ? pLRR->height( memory_model::memory_order_relaxed ) : 0;
begin_change( pNode, nodeVersion );
int hLRR = pLRR ? pLRR->height( memory_model::memory_order_relaxed ) : 0;
begin_change( pNode, nodeVersion );
pParent->m_pRight.store( pLRight, memory_model::memory_order_relaxed );
}
pLRight->m_pParent.store( pParent, memory_model::memory_order_relaxed );
pParent->m_pRight.store( pLRight, memory_model::memory_order_relaxed );
}
pLRight->m_pParent.store( pParent, memory_model::memory_order_relaxed );
version_type nodeVersion = pNode->version( memory_model::memory_order_relaxed );
version_type rightVersion = pRight->version( memory_model::memory_order_relaxed );
version_type nodeVersion = pNode->version( memory_model::memory_order_relaxed );
version_type rightVersion = pRight->version( memory_model::memory_order_relaxed );
- node_type * pPL = child( pParent, -1, memory_model::memory_order_relaxed );
- node_type * pRLL = child( pRLeft, -1, memory_model::memory_order_relaxed );
- node_type * pRLR = child( pRLeft, 1, memory_model::memory_order_relaxed );
+ node_type * pPL = child( pParent, left_child, memory_model::memory_order_relaxed );
+ node_type * pRLL = child( pRLeft, left_child, memory_model::memory_order_relaxed );
+ node_type * pRLR = child( pRLeft, right_child, memory_model::memory_order_relaxed );
int hRLL = pRLL ? pRLL->height( memory_model::memory_order_relaxed ) : 0;
begin_change( pNode, nodeVersion );
int hRLL = pRLL ? pRLL->height( memory_model::memory_order_relaxed ) : 0;
begin_change( pNode, nodeVersion );