.ad 8
.bm 8
.fm 4
.bt $Copyright (c) 2000-2004 SAP AG$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $SQL$Project Distributed Database System$VBD34$
.tt 2 $$$
.tt 3 $JuergenP$b34leafunderflow$2000-09-07$
***********************************************************
.nf
 
 
    ========== licence begin  GPL
    Copyright (c) 2000-2004 SAP AG
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end
 
.fo
.nf
.sp
Module  : b34leafunderflow
=========
.sp
Purpose : underflow handling of leaves
          containing primary data
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :
 
        PROCEDURE
              b34p_leafunderflow (VAR nptr : tbd_node_ptrs;
                    left        : tsp00_PageNo;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b34t_leafunderflow (VAR nptr : tbd_node_ptrs;
                    left        : tsp00_PageNo;
                    VAR current : tbd_current_tree);
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              filesysteminterface_1 : VBD01;
 
        FUNCTION
              b01rec_align (len : tsp00_Int4): tsp00_Int4;
 
      ------------------------------ 
 
        FROM
              error_text_handling : VBD06;
 
        PROCEDURE
              b06dump_bad_page (pid : tsp00_TaskId;
                    page_type_flag : char;
                    file_ext       : tsp00_C4;
                    bad_pno        : tsp00_Int4;
                    buf_ptr        : tbd_nodeptr;
                    curr_buf_cnt   : integer);
 
      ------------------------------ 
 
        FROM
              nodehandling : VBD13;
 
        PROCEDURE
              b13free_node (VAR nptr : tbd_node_ptrs;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              bd13GetNode (VAR Current : tbd_current_tree;
                    Pno       : tsp00_PageNo;
                    PageLockMode : tbd00_PageLockMode;
                    NodeReq   : tbd_node_request;
                    VAR Nptrs : tbd_node_ptrs);
 
        PROCEDURE
              bd13FreePageNo(
                    pageNo               : tsp00_PageNo;
                    pageConverterVersion : tsp00_Int4;
                    VAR current          : tbd_current_tree );
        PROCEDURE
              b13r_release_node (VAR nptr : tbd_node_ptrs;
                    VAR current : tbd_current_tree;
                    lru_info    : tbd_lru_info);
 
        PROCEDURE
              b13w_release_node (VAR nptr : tbd_node_ptrs;
                    VAR current : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              branchnodehandling : VBD51;
 
        PROCEDURE
              b51ldivert_leftnext (right : tsp00_PageNo;
                    new_left    : tsp00_PageNo;
                    VAR current : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              indexupdateorders : VBD54;
 
        PROCEDURE
              b54del_index (pSep       : tsp00_KeyAddr;
                    SepLen             : tsp00_Int4;
                    n_level            : tsp00_Int2;
                    VAR indexorderlist : tbd00_OrderList);
 
        PROCEDURE
              b54repl_index (pOldSep     : tsp00_KeyAddr;
                    OldSepLen            : tsp00_Int4;
                    pNewSep              : tsp00_KeyAddr;
                    NewSepLen            : tsp00_Int4;
                    n_id                 : tsp00_PageNo;
                    n_level              : tsp00_Int2;
                    VAR indexorderlist   : tbd00_OrderList);
 
        PROCEDURE
              b54execute_indexorder (VAR indexorderlist : tbd00_OrderList;
                    VAR current : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              indexing : VBD53;
 
        PROCEDURE
              bd53NewLeafIndex (VAR Nptr : tbd_nodeptr;
                    VAR Nnptr        : tbd_nodeptr;
                    VAR NewSeparator : tgg00_Lkey;
                    t                : tgg00_TransContextPtr);
 
      ------------------------------ 
 
        FROM
              leafhandling : VBD31;
 
        PROCEDURE
              b31sort_entries (VAR nptr : tbd_nodeptr;
                    t : tgg00_TransContextPtr);
 
        PROCEDURE
              b31pointer_list (VAR nptr : tbd_nodeptr);
 
      ------------------------------ 
 
        FROM
              entryhandling : VBD35;
 
        PROCEDURE
              b35add_space (VAR nptr : tbd_nodeptr;
                    pos  : tsp00_Int4;
                    plus : tsp00_Int4;
                    t    : tgg00_TransContextPtr);
 
        PROCEDURE
              b35del_space (VAR nptr : tbd_nodeptr;
                    pos   : tsp00_Int4;
                    minus : tsp00_Int4;
                    t     : tgg00_TransContextPtr);
 
        PROCEDURE
              b35get_entrykey (VAR nptr : tbd_nodeptr;
                    index   : integer;
                    VAR sep : tgg00_Lkey;
                    t       : tgg00_TransContextPtr);
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG101;
 
        PROCEDURE
              SAPDB_PascalMove (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    source_upb  : tsp00_Int4;
                    dest_upb    : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    src_pos     : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    dest_pos    : tsp00_Int4;
                    length      : tsp00_Int4;
                    VAR e       : tgg00_BasisError);
 
        PROCEDURE
              g10mv (
                    mod_id      : tsp00_C6;            
                    mod_num     : tsp00_Int4;
                    source_upb  : tsp00_Int4;          
                    dest_upb    : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;       
                    src_pos     : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;       
                    dest_pos    : tsp00_Int4;
                    length      : tsp00_Int4;
                    VAR e       : tgg00_BasisError);
 
        PROCEDURE
              s10mv (
                    source_upb  : tsp00_Int4;       
                    destin_upb  : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;    
                    source_pos  : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;    
                    destin_pos  : tsp00_Int4;
                    length      : tsp00_Int4);
 
&       ifdef TRACE
 
      ------------------------------ 
 
        FROM
              Test_Procedures : VTA01;
 
        PROCEDURE
              t01page (debug : tgg00_Debug;
                    VAR buf  : tbd_node;
                    startpos : tsp00_Int4;
                    endpos   : tsp00_Int4);
&       endif
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              b06dump_bad_page;
 
              tbd_univ_ptr tbd_nodeptr
 
&             ifdef TRACE
 
        PROCEDURE
              t01page;
 
              tsp00_Page tbd_node
&             endif
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : JuergenP
.sp
.cp 3
Created : 1980-02-13
.sp
.cp 3
Version : 2002-12-09
.sp
.cp 3
Release :      Date : 2000-09-07
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
 
The routines described below are used to process the leaves of
the current B* tree.
.sp
A leaf node of a B* tree is considered to be underfilled if
it is less than half full.  This can result from the
deletion of entries but may also occur if entries are replaced
by shorter entries.  Unless the leaf is the root of the tree,
it has an environment (left and/or right neighbor leaf) and
the underflow can generally be corrected by redistributing
the entries between the leaf and its environment.
.sp
If the underflow handling makes necessary a modification
of the current B* index, the routines make available suitable
orders for index processing.  If, during the execution of routines,
the tree entries change leaves or change their position in a leaf,
all entries for the leaf concerned are deleted from the short-term
memory or the position data are labelled as unreliable.  Invariably,
all leaves of a permanent file that are affected by a reorganization
are written back as long as they were not removed from the tree
and (re-)released.  Changes in leaf nodes of permanent files are
first carried out separately on new leaf nodes (copies on leaves
with new page numbers) and then integrated into the tree after
successful execution.
.sp
Information on the current tree is found in 'current'.  Instructions
for a possible, future index reorganization are entered in
indexorderlist.
.sp 2
   b34p_leafunderflow(nptr,left,current,e)
.sp
It is assumed that, in the current tree belonging to a permanent file,
the leaf that is referenced by the pointer nptr is less than
half filled.  If this underflow can be corrected by a
reorganization of the leaf and its environment, such a reorganization
is carried out.
Acknowledgements in e:
   - e_ok
   - b_disk_not_accessible
.sp 2
   b34t_leafunderflow(nptr,left,current,e)
.sp
It is assumed that, in the current tree belonging to a permanent file,
the leaf that is referenced by the pointer nptr is less than
half filled.  If this underflow can be corrected by a
reorganization of the leaf and its environment, such a reorganization
is carried out.
Acknowledgements in e :
   - e_ok
   - b_disk_not_accessible
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
 
If an underfilled leaf n has a right neighbor rn in the tree,
a check is run as to whether the contents of the two leaves can be
accomodated in n (alone) ('merge_leaves').  If this is not possible,
the contents of the two leaves are distributed as evenly as possible
between the two leaves ('balance').  If both of these operations fail
because of a lack of space, an attempt is made to merge with the
left neighbor leaf, if it exists.  If this operation also fails, a
final attempt is made to achieve a better distribution with the left
neighbor.
.sp
When two underfilled leaves are merged, this does not guarantee
that the leaf remaining in the tree is then sufficiently filled.
If it is not, the underflow handling is not repeated because
this would make the modification of the B* index too complicated.
.sp
Whenever leaves are removed from the tree and released during the
course of reorganization, the associated routines ensure that the
short-term memory no longer contains any pointers to these leaves.
The reminders refering to a leaf that was used for the 'balance'
operation are also deleted.
.sp
Due to the fact that the security requirements for permanent and
temporary files differ from one another, the underflow handling
of leaves in these two types of files differs as
follows:
.in 4
.of 2
- for temporary files, entries are balanced in the old leaves.
.in 4
.of 2
- for permanent files, new leaves must be requested and the contents
of the old leaves must be transferred to the new leaves
.in 4
.of 2
_ for temporary files, it is sufficient if the changes are made in
the leaves in the system buffer
.in 4
.of 2
_ for permanent files, the leaves must be written out directly to
the secondary storage
.in 0
.sp
The B* tree index is reorganized as follows:
.br
In the case of a merge, the right-hand leaf of the two leaves
concerned was removed from the tree.  For this reason, the pointer
to this leaf must be deleted from the index.  If the leaves belong
to a permanent file, the pointer must also be redirected in the index
section from the old left leaf to the new leaf.  If the contents
are redistributed between the underfilled leaf and the left or right
neighbor leaf, the old separator in the right-hand leaf is
replaced by a new separator.  If the leaves are components of a
permanent file, the two pointers in the tree index must also be
redirected from the old leaves to the new ones.
.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:
 
.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :
 
 
(*------------------------------*) 
 
PROCEDURE
      b34p_leafunderflow (VAR nptr : tbd_node_ptrs;
            left        : tsp00_PageNo;
            VAR current : tbd_current_tree);
 
VAR
      ncov            : integer;
      neighbcov       : integer;
      neighb_nptr     : tbd_node_ptrs;
      right           : tsp00_PageNo;
      free_pno        : tsp00_PageNo;
      freePageVersion : tsp00_Int4;
      indexorderlist  : tbd00_OrderList;
 
BEGIN
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    indexorderlist.olstCount_bd00 := 0;
    neighb_nptr.np_ptr            := NIL;
    neighb_nptr.np_cbptr          := NIL;
    free_pno                      := NIL_PAGE_NO_GG00;
    WITH nptr.np_ptr^ DO
        BEGIN
        ncov  := nd_bottom - BODY_BEG_BD00 + ((nd_record_cnt)*POINTERSIZE_BD00);
        right := nd_right;
        END;
    (*ENDWITH*) 
    IF  right = NIL_PAGE_NO_GG00
    THEN
        trError_gg00 := e_no_more_space
    ELSE
        BEGIN
        bd13GetNode (current, right, plmLock_ebd00, nr_for_update, neighb_nptr);
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            WITH neighb_nptr.np_ptr^ DO
                neighbcov := nd_bottom - BODY_BEG_BD00 + ((nd_record_cnt)*POINTERSIZE_BD00);
            (*ENDWITH*) 
            IF  (ncov + neighbcov) <= FULLCOVERING_BD00
            THEN
                BEGIN
                IF  NOT neighb_nptr.np_ptr^.nd_sorted
                THEN
                    b31sort_entries (neighb_nptr.np_ptr, curr_trans);
                (*ENDIF*) 
                IF  trError_gg00 = e_ok
                THEN
                    bd34merge_leafnodes (nptr, neighb_nptr, indexorderlist, current);
                (*ENDIF*) 
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    free_pno             := neighb_nptr.np_ptr^.nd_id;
                    freePageVersion      := neighb_nptr.np_ptr^.nd_conv_version;
                    neighb_nptr.np_ptr   := NIL;
                    neighb_nptr.np_cbptr := NIL;
                    IF  trError_gg00 = e_ok
                    THEN
                        b13w_release_node (nptr, current)
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                END
            ELSE
                BEGIN
                IF  NOT neighb_nptr.np_ptr^.nd_sorted
                THEN
                    b31sort_entries (neighb_nptr.np_ptr, curr_trans);
                (*ENDIF*) 
                IF  trError_gg00 = e_ok
                THEN
                    bd34left_distribute (neighb_nptr, nptr, neighbcov,
                          ncov, indexorderlist, current);
                (*ENDIF*) 
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    WITH nptr.np_ptr^ DO
                        BEGIN
                        nd_write_cnt := 0;
                        nd_checksum  := 0
                        END;
                    (*ENDWITH*) 
                    WITH neighb_nptr.np_ptr^ DO
                        BEGIN
                        nd_write_cnt := 0;
                        nd_checksum  := 0
                        END;
                    (*ENDWITH*) 
                    b13w_release_node (neighb_nptr, current);
                    IF  trError_gg00 = e_ok
                    THEN
                        b13w_release_node (nptr, current);
                    (*ENDIF*) 
                    END
                ELSE
                    b13r_release_node (neighb_nptr, current, lru_normal)
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_no_more_space
    THEN
        IF  left <> NIL_PAGE_NO_GG00
        THEN
            BEGIN
            trError_gg00 := e_ok;
            bd13GetNode (current, left, plmLock_ebd00, nr_for_update, neighb_nptr);
            IF  trError_gg00 = e_ok
            THEN   (* nncov > 0 *)
                BEGIN
                WITH neighb_nptr.np_ptr^ DO
                    neighbcov := nd_bottom - BODY_BEG_BD00 + ((nd_record_cnt)*POINTERSIZE_BD00);
                (*ENDWITH*) 
                IF  (ncov + neighbcov) <= FULLCOVERING_BD00
                THEN
                    BEGIN
                    IF  NOT neighb_nptr.np_ptr^.nd_sorted
                    THEN
                        b31sort_entries (neighb_nptr.np_ptr, curr_trans);
                    (*ENDIF*) 
                    IF  trError_gg00 = e_ok
                    THEN
                        bd34merge_leafnodes (neighb_nptr, nptr, indexorderlist, current);
                    (*ENDIF*) 
                    IF  trError_gg00 = e_ok
                    THEN
                        BEGIN
                        free_pno        := nptr.np_ptr^.nd_id;
                        freePageVersion := nptr.np_ptr^.nd_conv_version;
                        nptr.np_ptr     := NIL;
                        nptr.np_cbptr   := NIL;
                        IF  trError_gg00 = e_ok
                        THEN
                            b13w_release_node (neighb_nptr, current)
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                ELSE
                    BEGIN
                    IF  NOT neighb_nptr.np_ptr^.nd_sorted
                    THEN
                        b31sort_entries (neighb_nptr.np_ptr,curr_trans);
                    (*ENDIF*) 
                    IF  trError_gg00 = e_ok
                    THEN
                        bd34right_distribute (neighb_nptr, nptr,
                              neighbcov, ncov, indexorderlist, current);
                    (*ENDIF*) 
                    IF  trError_gg00 = e_ok
                    THEN
                        BEGIN
                        WITH neighb_nptr.np_ptr^ DO
                            BEGIN
                            nd_write_cnt := 0;
                            nd_checksum  := 0
                            END;
                        (*ENDWITH*) 
                        WITH nptr.np_ptr^ DO
                            BEGIN
                            nd_write_cnt := 0;
                            nd_checksum  := 0
                            END;
                        (*ENDWITH*) 
                        b13w_release_node (nptr, current);
                        IF  trError_gg00 = e_ok
                        THEN
                            b13w_release_node (neighb_nptr, current)
                        (*ENDIF*) 
                        END
                    ELSE
                        b13r_release_node (neighb_nptr, current, lru_normal)
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        b54execute_indexorder (indexorderlist, current);
    (*ENDIF*) 
    IF  (trError_gg00 = e_ok) AND (free_pno <> NIL_PAGE_NO_GG00)
    THEN
        bd13FreePageNo (free_pno, freePageVersion, current);
    (*ENDIF*) 
    IF  trError_gg00 = e_no_more_space
    THEN
        BEGIN
        trError_gg00 := e_ok;
        b13w_release_node (nptr, current)
        END;
    (*ENDIF*) 
    IF  trError_gg00 <> e_ok
    THEN
        BEGIN
        IF  nptr.np_ptr <> NIL
        THEN
            b13r_release_node (nptr, current, lru_normal);
        (*ENDIF*) 
        IF  neighb_nptr.np_ptr <> NIL
        THEN
            b13r_release_node (neighb_nptr, current, lru_normal)
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b34t_leafunderflow (VAR nptr : tbd_node_ptrs;
            left        : tsp00_PageNo;
            VAR current : tbd_current_tree);
 
VAR
      ncov           : integer;
      neighbcov      : integer;
      neighb_nptr    : tbd_node_ptrs;
      right          : tsp00_PageNo;
      indexorderlist : tbd00_OrderList;
 
BEGIN
neighb_nptr.np_ptr            := NIL;
neighb_nptr.np_cbptr          := NIL;
indexorderlist.olstCount_bd00 := 0;
WITH nptr.np_ptr^ DO
    BEGIN
    right := nd_right;
    ncov := nd_bottom - BODY_BEG_BD00 + ((nd_record_cnt)*POINTERSIZE_BD00)
    END;
(*ENDWITH*) 
WITH current, curr_trans^ DO
    BEGIN
    IF  right = NIL_PAGE_NO_GG00
    THEN
        trError_gg00 := e_no_more_space
    ELSE
        BEGIN
        bd13GetNode (current, right, plmLock_ebd00, nr_for_update, neighb_nptr);
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            WITH neighb_nptr.np_ptr^ DO
                neighbcov := nd_bottom - BODY_BEG_BD00 + ((nd_record_cnt)*POINTERSIZE_BD00);
            (*ENDWITH*) 
            IF  (ncov + neighbcov) <= FULLCOVERING_BD00
            THEN
                BEGIN
                IF  NOT neighb_nptr.np_ptr^.nd_sorted
                THEN
                    b31sort_entries (neighb_nptr.np_ptr, curr_trans);
                (*ENDIF*) 
                IF  trError_gg00 = e_ok
                THEN
                    bd34merge_leafnodes (nptr, neighb_nptr, indexorderlist, current)
                (*ENDIF*) 
                END
            ELSE
                BEGIN
                IF  NOT neighb_nptr.np_ptr^.nd_sorted
                THEN
                    b31sort_entries (neighb_nptr.np_ptr, curr_trans);
                (*ENDIF*) 
                IF  trError_gg00 = e_ok
                THEN
                    bd34left_distribute (neighb_nptr, nptr, neighbcov,
                          ncov, indexorderlist, current)
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  trError_gg00 = e_no_more_space
            THEN
                b13r_release_node (neighb_nptr, current, lru_normal)
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_no_more_space
    THEN
        BEGIN
        trError_gg00 := e_ok;
        IF  left = NIL_PAGE_NO_GG00
        THEN
            trError_gg00 := e_no_more_space
        ELSE
            BEGIN
            bd13GetNode (current, left, plmLock_ebd00, nr_for_update, neighb_nptr);
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                WITH neighb_nptr.np_ptr^ DO
                    neighbcov := nd_bottom - BODY_BEG_BD00 + ((nd_record_cnt)*POINTERSIZE_BD00);
                (*ENDWITH*) 
                IF  (ncov + neighbcov) <= FULLCOVERING_BD00
                THEN
                    BEGIN
                    IF  NOT neighb_nptr.np_ptr^.nd_sorted
                    THEN
                        b31sort_entries (neighb_nptr.np_ptr,curr_trans);
                    (*ENDIF*) 
                    IF  trError_gg00 = e_ok
                    THEN
                        bd34merge_leafnodes (neighb_nptr, nptr, indexorderlist, current)
                    (*ENDIF*) 
                    END
                ELSE
                    BEGIN
                    IF  NOT neighb_nptr.np_ptr^.nd_sorted
                    THEN
                        b31sort_entries (neighb_nptr.np_ptr, curr_trans);
                    (*ENDIF*) 
                    IF  trError_gg00 = e_ok
                    THEN
                        bd34right_distribute (neighb_nptr, nptr, neighbcov,
                              ncov, indexorderlist, current)
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                IF  trError_gg00 = e_no_more_space
                THEN
                    b13r_release_node (neighb_nptr, current, lru_normal)
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  trError_gg00 = e_no_more_space
        THEN
            BEGIN
            trError_gg00 := e_ok;
            b13w_release_node (nptr, current)
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        b54execute_indexorder (indexorderlist, current);
    (*ENDIF*) 
    IF  trError_gg00 <> e_ok
    THEN
        BEGIN
        IF  nptr.np_ptr <> NIL
        THEN
            b13r_release_node (nptr, current, lru_normal);
        (*ENDIF*) 
        IF  neighb_nptr.np_ptr <> NIL
        THEN
            b13r_release_node (neighb_nptr, current, lru_normal)
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd34merge_leafnodes (VAR lnptr, rnptr : tbd_node_ptrs;
            VAR indexorderlist : tbd00_OrderList;
            VAR current        : tbd_current_tree);
 
VAR
      amount    : integer;
      right_sep : tgg00_Lkey;
 
BEGIN
&ifdef TRACE
t01page (bd_oflw, lnptr.np_ptr^, 1, lnptr.np_ptr^.nd_bottom);
t01page (bd_oflw, rnptr.np_ptr^, 1, rnptr.np_ptr^.nd_bottom);
&endif
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    trError_gg00 := e_ok;
    amount       := rnptr.np_ptr^.nd_bottom - BODY_BEG_BD00;
    b35get_entrykey (rnptr.np_ptr, FIRST_REC_INDEX_BD00, right_sep, curr_trans);
    lnptr.np_ptr^.nd_right := rnptr.np_ptr^.nd_right;
    IF  trError_gg00 = e_ok
    THEN
        g10mv ('VBD34 ',   1,    
              sizeof (rnptr.np_ptr^), sizeof (lnptr.np_ptr^),
              @rnptr.np_ptr^, BODY_BEG_BD00,
              @lnptr.np_ptr^, lnptr.np_ptr^.nd_bottom, amount, trError_gg00);
    (*ENDIF*) 
    IF  trError_gg00 = e_move_error
    THEN
        BEGIN
        trError_gg00 := e_data_page_corrupted;
        b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
              rnptr.np_ptr^.nd_id, rnptr.np_ptr, 1);
        b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
              lnptr.np_ptr^.nd_id, lnptr.np_ptr, 1)
        END
    ELSE
        BEGIN
        WITH lnptr.np_ptr^ DO
            nd_bottom := nd_bottom + b01rec_align (amount);
        (*ENDWITH*) 
&       ifdef TRACE
        t01page (bd_oflw, lnptr.np_ptr^, 1, lnptr.np_ptr^.nd_bottom);
&       endif
        b31pointer_list (lnptr.np_ptr);
        IF  ftsPerm_egg00 in fileType_gg00
        THEN
            b54del_index (@right_sep.keyVal_gg00, right_sep.keyLen_gg00,
                  rnptr.np_ptr^.nd_level, indexorderlist)
        ELSE
            BEGIN
            b54del_index (@right_sep.keyVal_gg00, right_sep.keyLen_gg00,
                  rnptr.np_ptr^.nd_level, indexorderlist);
            IF  lnptr.np_ptr^.nd_right <> NIL_PAGE_NO_GG00
            THEN
                b51ldivert_leftnext (lnptr.np_ptr^.nd_right,
                      lnptr.np_ptr^.nd_id, current);
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                b13w_release_node (lnptr, current);
                IF  trError_gg00 = e_ok
                THEN
                    b13free_node (rnptr, current);
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd34right_distribute (VAR nptr : tbd_node_ptrs;
            VAR rnptr          : tbd_node_ptrs;
            ncov               : integer;
            rncov              : integer;
            VAR indexorderlist : tbd00_OrderList;
            VAR current        : tbd_current_tree);
 
VAR
      oflw         : integer;
      opt_oflw     : integer;
      ptrlist_oflw : integer;
      index        : tsp00_Int4;
      bpos         : tsp00_Int4;
      old_sep      : tgg00_Lkey;
      new_sep      : tgg00_Lkey;
 
BEGIN
&ifdef TRACE
t01page (bd_oflw, nptr.np_ptr^, 1, nptr.np_ptr^.nd_bottom);
t01page (bd_oflw, rnptr.np_ptr^, 1, rnptr.np_ptr^.nd_bottom);
&endif
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    trError_gg00 := e_ok;
    opt_oflw     := ncov - ((ncov + rncov) DIV 2);
    IF  opt_oflw <= 0
    THEN
        trError_gg00 := e_no_more_space
    ELSE
        BEGIN
        oflw         := 0;
        ptrlist_oflw := 0;
        index        := nptr.np_ptr^.nd_record_cnt - 1;
        REPEAT
            WITH nptr.np_ptr^ DO
                BEGIN
                bpos         := nd_pointer_list[ MAX_POINTERINDEX_BD00 - index ];
                oflw         := nd_bottom - bpos;
                ptrlist_oflw := ptrlist_oflw + POINTERSIZE_BD00;
                index        := index - 1
                END
            (*ENDWITH*) 
        UNTIL
            oflw + ptrlist_oflw >= opt_oflw;
        (*ENDREPEAT*) 
        IF  (rncov + oflw + ptrlist_oflw) > FULLCOVERING_BD00
        THEN
            trError_gg00 := e_no_more_space
        ELSE
            BEGIN
            b35get_entrykey (rnptr.np_ptr, FIRST_REC_INDEX_BD00, old_sep, curr_trans);
            b35add_space (rnptr.np_ptr, BODY_BEG_BD00, oflw, curr_trans);
            nptr.np_ptr^.nd_bottom := nptr.np_ptr^.nd_bottom - oflw;
            IF  trError_gg00 = e_ok
            THEN
                g10mv ('VBD34 ',   2,    
                      sizeof (nptr.np_ptr^), sizeof (rnptr.np_ptr^),
                      @nptr.np_ptr^, nptr.np_ptr^.nd_bottom,
                      @rnptr.np_ptr^, BODY_BEG_BD00, oflw, trError_gg00);
            (*ENDIF*) 
            IF  trError_gg00 = e_move_error
            THEN
                BEGIN
                trError_gg00 := e_data_page_corrupted;
                b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
                      nptr.np_ptr^.nd_id, nptr.np_ptr, 1);
                b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
                      rnptr.np_ptr^.nd_id, rnptr.np_ptr, 1)
                END
            ELSE
                BEGIN
&               ifdef TRACE
                t01page (bd_oflw, nptr.np_ptr^,1,nptr.np_ptr^.nd_bottom);
                t01page (bd_oflw, rnptr.np_ptr^, 1,rnptr.np_ptr^.nd_bottom);
&               endif
                b31pointer_list (nptr.np_ptr);
                b31pointer_list (rnptr.np_ptr);
                bd53NewLeafIndex (nptr.np_ptr, rnptr.np_ptr, new_sep, curr_trans);
                b54repl_index (@old_sep.keyVal_gg00, old_sep.keyLen_gg00,
                      @new_sep.keyVal_gg00, new_sep.keyLen_gg00,
                      rnptr.np_ptr^.nd_id,
                      rnptr.np_ptr^.nd_level, indexorderlist);
                IF  (trError_gg00 = e_ok) AND (NOT (ftsPerm_egg00 in fileType_gg00))
                THEN
                    BEGIN
                    b13w_release_node (rnptr, current);
                    b13w_release_node (nptr, current);
                    END;
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd34left_distribute (VAR nptr : tbd_node_ptrs;
            VAR lnptr          : tbd_node_ptrs;
            VAR ncov           : integer;
            VAR lncov          : integer;
            VAR indexorderlist : tbd00_OrderList;
            VAR current        : tbd_current_tree);
 
VAR
      oflw         : integer;
      opt_oflw     : integer;
      ptrlist_oflw : integer;
      index        : tsp00_Int4;
      bpos         : tsp00_Int4;
      old_sep      : tgg00_Lkey;
      new_sep      : tgg00_Lkey;
 
BEGIN
&ifdef TRACE
t01page (bd_oflw, nptr.np_ptr^, 1, nptr.np_ptr^.nd_bottom);
t01page (bd_oflw, lnptr.np_ptr^, 1, lnptr.np_ptr^.nd_bottom);
&endif
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    trError_gg00 := e_ok;
    opt_oflw     := ncov - ((ncov + lncov) DIV 2);
    IF  opt_oflw <= 0
    THEN
        trError_gg00 := e_no_more_space
    ELSE
        BEGIN
        ptrlist_oflw := - POINTERSIZE_BD00;
        index        := 0;
        oflw         := 0;
        WITH nptr.np_ptr^ DO
            BEGIN
            REPEAT
                IF  index <= nd_record_cnt - 1
                THEN
                    bpos := nd_pointer_list[ MAX_POINTERINDEX_BD00 - index ]
                ELSE
                    bpos := nd_bottom;
                (*ENDIF*) 
                oflw         := bpos - BODY_BEG_BD00;
                ptrlist_oflw := ptrlist_oflw + POINTERSIZE_BD00;
                index        := index + 1
            UNTIL
                oflw + ptrlist_oflw >= opt_oflw
            (*ENDREPEAT*) 
            END;
        (*ENDWITH*) 
        IF  (lncov + oflw + ptrlist_oflw) > FULLCOVERING_BD00
        THEN
            trError_gg00 := e_no_more_space
        ELSE
            BEGIN
            b35get_entrykey (nptr.np_ptr, FIRST_REC_INDEX_BD00, old_sep, curr_trans);
            IF  trError_gg00 = e_ok
            THEN
                g10mv ('VBD34 ',   3,    
                      sizeof (nptr.np_ptr^), sizeof (lnptr.np_ptr^),
                      @nptr.np_ptr^, BODY_BEG_BD00,
                      @lnptr.np_ptr^, lnptr.np_ptr^.nd_bottom, oflw, trError_gg00);
            (*ENDIF*) 
            IF  trError_gg00 = e_move_error
            THEN
                BEGIN
                trError_gg00 := e_data_page_corrupted;
                b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
                      nptr.np_ptr^.nd_id, nptr.np_ptr, 1);
                b06dump_bad_page (trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
                      lnptr.np_ptr^.nd_id, lnptr.np_ptr, 1)
                END
            ELSE
                BEGIN
                lnptr.np_ptr^.nd_bottom := lnptr.np_ptr^.nd_bottom + oflw;
                b35del_space (nptr.np_ptr, BODY_BEG_BD00, oflw, curr_trans);
&               ifdef TRACE
                t01page (bd_oflw, nptr.np_ptr^, 1, nptr.np_ptr^.nd_bottom);
                t01page (bd_oflw, lnptr.np_ptr^, 1, lnptr.np_ptr^.nd_bottom);
&               endif
                b31pointer_list (nptr.np_ptr);
                b31pointer_list (lnptr.np_ptr);
                bd53NewLeafIndex (lnptr.np_ptr, nptr.np_ptr, new_sep, curr_trans);
                b54repl_index (@old_sep.keyVal_gg00, old_sep.keyLen_gg00,
                      @new_sep.keyVal_gg00, new_sep.keyLen_gg00,
                      nptr.np_ptr^.nd_id, nptr.np_ptr^.nd_level, indexorderlist);
                IF  (trError_gg00 = e_ok) AND (NOT (ftsPerm_egg00 in fileType_gg00))
                THEN
                    BEGIN
                    b13w_release_node (nptr, current);
                    b13w_release_node (lnptr, current);
                    END;
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
*-PRETTY-*  statements    :        238
*-PRETTY-*  lines of code :        653        PRETTYX 3.10 
*-PRETTY-*  lines in file :       1048         1997-12-10 
.PA 
