Logo Search packages:      
Sourcecode: maxdb-7.5.00 version File versions  Download package

void cbd500_Tree::bd500PrevNode (  ) 

function: bd500PrevNode description: The internal node is set to the left neighbor node.

The PathInfo is updated. If left neighbor is nil, no further Prev-Operation is possible. If the stop condition (StopKey) is reached, then the internal node is released and no further Prev-Operation is possible.

Definition at line 375 of file vbd500.cpp.

References bd500Print(), cbd600_Node::bd600GetId(), cbd600_Node::bd600IsAccessable(), cbd600_Node::bd600LeafCount(), cbd600_Node::bd600Level(), cbd600_Node::bd600MaxRecIndex(), cbd600_Node::bd600Move(), cbd600_Node::bd600Release(), cbd600_Node::bd600RightNeighbor(), cbd600_Node::m_Current, and cbd600_Node::m_RequestKind.

{
    ROUTINE_DBG_MEO00 ("bd500PrevNode");
    
    if ( // PTS 1103703 AK 30-08-1999 
        (m_Node.m_Current.curr_trans->trRteCommPtr_gg00->to_cancel) &&    
        (
        (m_select == m_Node.m_Current.curr_action) ||
        (m_verify == m_Node.m_Current.curr_action)
        )
        )                     
    {
        m_TrError = e_cancelled;
        g01opmsg (sp3p_knldiag, sp3m_info, csp3_bd_msg, csp3_n_btree,
            "BD500: Prev cancelled   " , m_Node.m_Current.curr_trans->trTaskId_gg00);
        return;
    }
    
    // PTS 1122998 UH 2003-07-09 completely rewritten (was: bd500_SetPathInfoToLeftNeighbor)

    if ( g01vtrace.vtrBdIndex_gg00 )
        bd500Print("bd500PrevNode::BEGIN");

    const tsp00_Int4       TargetLevel    = m_CurrLevel;
    const tbd_node_request NodeRequest    = m_Node.m_RequestKind;
    const tsp00_PageNo     checkId        = m_Node.bd600IsAccessable() ? m_Node.bd600GetId() : NIL_PAGE_NO_GG00;
          bool             bSearchSubNode = false;
          
    if ( m_Node.bd600IsAccessable()
         &&
         m_Node.bd600Level() != m_CurrLevel ) // only check
    {
        m_Node.bd600Release (true);
        m_TrError = e_invalid_index_structure;
        bd500Print("bd500PrevNode: m_CurrLevel is wrong");
        return;
    }

    m_Node.bd600Release (true); // if m_Node is not accessable the iterator has to stop

    // position node to left leaf or to index node to go down again
    while ( m_CurrLevel < m_RootLevel )
    {
        // 1. is left neighbour known ?
        if ( m_PathInfo[m_CurrLevel].piLeftId_bd500 != NIL_PAGE_NO_GG00 )
        {
            if ( m_PathInfo[m_CurrLevel+1].piSubNodeRecIndex_bd500 == FIRST_REC_INDEX_BD00 )
            {
                m_TrError = e_invalid_index_structure;
                bd500Print("bd500PrevNode: Wrong PathInfo1");
                return;
            }
            m_Node.bd600Move(m_PathInfo[m_CurrLevel].piLeftId_bd500);
            if ( e_ok != m_TrError )
            {
                bd500Print("bd500PrevNode::no access to left neighbor");
                return;
            }
            m_PathInfo[m_CurrLevel].piId_bd500              = m_PathInfo[m_CurrLevel].piLeftId_bd500;
            m_PathInfo[m_CurrLevel].piLeftId_bd500          = NIL_PAGE_NO_GG00;
            m_PathInfo[m_CurrLevel].piMaxRecIndex_bd500     = m_Node.bd600MaxRecIndex();
            m_PathInfo[m_CurrLevel].piSubNodeRecIndex_bd500 = m_Node.bd600MaxRecIndex();
            m_PathInfo[m_CurrLevel].piLeafCount_bd500       = m_Node.bd600LeafCount(m_Node.bd600MaxRecIndex(),m_Node.bd600MaxRecIndex());
            --(m_PathInfo[m_CurrLevel+1].piSubNodeRecIndex_bd500); // update index above
            if ( TargetLevel == m_CurrLevel )
            {
                // the simplest way - the left neighbor node is known
                if ( checkId != NIL_PAGE_NO_GG00
                     &&
                     checkId != m_Node.bd600RightNeighbor() )
                {
                    m_TrError = e_invalid_index_structure;
                    bd500Print("bd500PrevNode: Wrong PathInfo2");
                    return;
                }
                if ( g01vtrace.vtrBdIndex_gg00 )
                    bd500Print("bd500PrevNode: FOUND simple");
                return;
            }
            bSearchSubNode = true;
            break;
        }

        // invalidate the pathinfo for this level because we must search for a new way
        m_PathInfo[m_CurrLevel].piId_bd500              = NIL_PAGE_NO_GG00;
        m_PathInfo[m_CurrLevel].piLeftId_bd500          = NIL_PAGE_NO_GG00;
        m_PathInfo[m_CurrLevel].piSubNodeRecIndex_bd500 = NIL_RECINDEX_BD00;
        m_PathInfo[m_CurrLevel].piMaxRecIndex_bd500     = NIL_RECINDEX_BD00;
        m_PathInfo[m_CurrLevel].piLeafCount_bd500       = -1;

        // 2. try to use the next higher index node

        ++m_CurrLevel;

        if ( m_PathInfo[m_CurrLevel].piSubNodeRecIndex_bd500 > FIRST_REC_INDEX_BD00 )
        {
            // This index node can be used to find the leaf again.
            --(m_PathInfo[m_CurrLevel].piSubNodeRecIndex_bd500);
            m_Node.bd600Move(m_PathInfo[m_CurrLevel].piId_bd500);
            bSearchSubNode = true;
            break;
        }
    }//endwhile

    if ( ! bSearchSubNode )
    {
        if ( g01vtrace.vtrBdIndex_gg00 )
            bd500Print("bd500PrevNode: NOT FOUND");
        return; // the loop above did not find any left neighbor
    }

    /* Find leaf node again from found index node */

    // Start with determined Separator
    bd500_NextSubNode (m_PathInfo[m_CurrLevel].piSubNodeRecIndex_bd500, TargetLevel, NodeRequest);
    if ( e_ok != m_TrError )
    {
        bd500Print("bd500PrevNode:no access to subnode1");
        return;
    }
    
    while ( m_CurrLevel > TargetLevel )
    {
        bd500_NextSubNode (m_Node.bd600MaxRecIndex(), TargetLevel, NodeRequest);
        if ( e_ok != m_TrError )
        {
            bd500Print("bd500PrevNode:no access to subnode2");
            return;
        }
    }
    if ( m_CurrLevel != TargetLevel )
    {
        m_TrError = e_invalid_index_structure;
        bd500Print("bd500PrevNode: target level not reached");
        return;
    }
    
    if ( checkId != NIL_PAGE_NO_GG00
         &&
         checkId != m_Node.bd600RightNeighbor() )
    {
        m_TrError = e_invalid_index_structure;
        bd500Print("bd500PrevNode: Wrong PathInfo3");
        return;
    }
    
    if ( g01vtrace.vtrBdIndex_gg00 )
        bd500Print("bd500PrevNode::FOUND complex");

    if ( m_select == m_Node.m_Current.curr_action
         &&
         m_Node.bd600IsAccessable() )
        bd500_CheckStopKeyAndInterrupt (! ASCENDING_GBD500);
}


Generated by  Doxygen 1.6.0   Back to index