.ad 8
.bm 8
.fm 4
.bt $Copyright (c) 2000-2005 SAP AG$$Page %$
.tm 12
.hm 6
.hs 3
.TT 1 $SQL$Project Distributed Database System$VBD61$
.tt 2 $$$
.TT 3 $JuergenP$bytestring_indexhandling$2000-10-26$
***********************************************************
.nf
 
 .nf
 
    ========== licence begin  GPL
    Copyright (c) 2000-2005 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
 
 
.fo
.nf
.sp
MODULE  : bytestring_indexhandling
=========
.sp
Purpose : - bytestring primitives
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :
 
        PROCEDURE
              b61add_bstrindex (VAR act_rootptr : tbd_node_ptrs;
                    act_pno     : tsp00_PageNo;
                    pno_1       : tsp00_PageNo;
                    pno_2       : tsp00_PageNo;
                    ins_level   : tsp00_Int2;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b61change_content (VAR nptr : tbd_node_ptrs;
                    VAR rootptr : tbd_node_ptrs;
                    t           : tgg00_TransContextPtr);
 
        PROCEDURE
              b61first_load_step (VAR leftptr : tbd_node_ptrs;
                    VAR leafptr : tbd_node_ptrs;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b61gfree_garb_node (pno : tsp00_PageNo;
                    twice       : boolean;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b61rtrunc_bstrroot (VAR nptr : tbd_node_ptrs;
                    new_flength : tsp00_Int4;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b61search_leaf (
                    VAR nptr     : tbd_node_ptrs;
                    pos          : tsp00_Int4;
                    VAR leaf_pos : tsp00_Int4;
                    VAR current  : tbd_current_tree);
 
        PROCEDURE
              b61trunc_bstr (VAR nptr : tbd_node_ptrs;
                    new_flength : tsp00_Int4;
                    destroy     : boolean;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b61wsearch_writeleaf (VAR nptr : tbd_node_ptrs;
                    pos               : tsp00_Int4;
                    VAR leaf_pos      : tsp00_Int4;
                    VAR pre_last_page : boolean;
                    VAR current       : tbd_current_tree);
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        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
              bd13GetNode (VAR Current : tbd_current_tree;
                    Pno       : tsp00_PageNo;
                    PageLockMode : tbd00_PageLockMode;
                    NodeReq   : tbd_node_request;
                    VAR Nptrs : tbd_node_ptrs);
 
        PROCEDURE
              b13free_node (VAR nptr : tbd_node_ptrs;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b13init_default_data_page (
                    VAR FileId  : tgg00_FileId;
                    Level       : tsp00_Int2;
                    NewPno      : tsp00_PageNo;
                    VAR Nptrs   : tbd_node_ptrs);
 
        PROCEDURE
              b13new_node (lno  : tsp00_Int2;
                    VAR nptr    : tbd_node_ptrs;
                    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
              Kernel_move_and_fill : VGG101;
 
 
        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);
 
 
      ------------------------------ 
 
        FROM
              RTE-Extension-20 : VSP20;
 
        FUNCTION
              s20or4a (VAR n : tbd_node; pos : tsp00_Int4) : tsp00_Int4;
 
        PROCEDURE
              s20ch4 (pno : tsp00_PageNo;
                    VAR n : tbd_node;
                    pos   : tsp00_Int4);
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              b06dump_bad_page;
 
              tbd_univ_ptr tbd_nodeptr
 
        FUNCTION
              s20or4a;
 
              tsp00_MoveObj tbd_node
 
        PROCEDURE
              s20ch4;
 
              tsp00_Int4    tsp00_PageNo
              tsp00_MoveObj tbd_node
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : JuergenP
.sp
.cp 3
Created : 1984-07-11
.sp
.cp 3
.sp
.cp 3
Release :      Date : 2000-10-26
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
 
 
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
 
 
.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
      b61add_bstrindex (VAR act_rootptr : tbd_node_ptrs;
            act_pno     : tsp00_PageNo;
            pno_1       : tsp00_PageNo;
            pno_2       : tsp00_PageNo;
            ins_level   : tsp00_Int2;
            VAR current : tbd_current_tree);
 
VAR
      index_pos     : tsp00_Int4;
      indx_pno      : tsp00_PageNo;
      act_nptr      : tbd_node_ptrs;
      indx_nptr     : tbd_node_ptrs;
      new_rootptr   : tbd_node_ptrs;
 
BEGIN
act_nptr.np_ptr      := NIL;
act_nptr.np_cbptr    := NIL;
indx_nptr.np_ptr     := NIL;
indx_nptr.np_cbptr   := NIL;
new_rootptr.np_ptr   := NIL;
new_rootptr.np_cbptr := NIL;
IF  act_pno <> act_rootptr.np_ptr^.nd_id
THEN
    bd13GetNode (current, act_pno, plmLock_ebd00, nr_for_update, act_nptr)
ELSE
    act_nptr := act_rootptr;
(*ENDIF*) 
WITH current, curr_trans^ DO
    BEGIN
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        IF  act_nptr.np_ptr^.nd_level <> ins_level
        THEN
            BEGIN
            index_pos := act_nptr.np_ptr^.nd_bottom - sizeof (tsp00_PageNo);
            act_pno   := s20or4a (act_nptr.np_ptr^, index_pos);
            IF  act_nptr.np_ptr <> act_rootptr.np_ptr
            THEN
                b13r_release_node (act_nptr, current, lru_normal);
            (*ENDIF*) 
            b61add_bstrindex (act_rootptr, act_pno, pno_1, pno_2, ins_level, current)
            END
        ELSE
            BEGIN
            index_pos := act_nptr.np_ptr^.nd_bottom;
            IF  index_pos <= (MAX_BOTTOM_BD00 - sizeof (tsp00_PageNo))
            THEN
                BEGIN
                (* *)
                (* at least one leaf pageNo fits into the current index page *)
                (* *)
                s20ch4 (pno_1, act_nptr.np_ptr^, index_pos);
                index_pos := index_pos + sizeof (tsp00_PageNo);
                act_nptr.np_ptr^.nd_bottom := index_pos; (* PTS 1135689 TS 2005-05-23 *)
                IF  pno_2 <> NIL_PAGE_NO_GG00
                THEN
                    BEGIN
                    IF  index_pos <= MAX_BOTTOM_BD00 - sizeof(tsp00_PageNo)
                    THEN
                        BEGIN
                        s20ch4 (pno_2, act_nptr.np_ptr^, index_pos);
                        index_pos := index_pos + sizeof (tsp00_PageNo);
                        act_nptr.np_ptr^.nd_bottom := index_pos; (* PTS 1135689 TS 2005-05-23 *)
                        END
                    ELSE
                        BEGIN
                        (* *)
                        (* second leaf pageNo needs new index page *)
                        (* *)
                        b13new_node (ins_level, indx_nptr, current);
                        IF  trError_gg00 = e_ok
                        THEN
                            BEGIN
                            s20ch4 (pno_2, indx_nptr.np_ptr^, BODY_BEG_BD00);
                            indx_nptr.np_ptr^.nd_bottom := BODY_BEG_BD00 + sizeof (tsp00_PageNo);
                            END
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            ELSE
                BEGIN
                (* current index page is completely filled *)
                b13new_node (ins_level, indx_nptr, current);
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    s20ch4 (pno_1, indx_nptr.np_ptr^, BODY_BEG_BD00);
                    index_pos := BODY_BEG_BD00 + sizeof (tsp00_PageNo);
                    IF  pno_2 <> NIL_PAGE_NO_GG00
                    THEN
                        BEGIN
                        s20ch4 (pno_2, indx_nptr.np_ptr^, index_pos);
                        index_pos := index_pos + sizeof (tsp00_PageNo)
                        END;
                    (*ENDIF*) 
                    indx_nptr.np_ptr^.nd_bottom := index_pos
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  indx_nptr.np_ptr <> NIL
            THEN
                BEGIN
                indx_pno := indx_nptr.np_ptr^.nd_id;
                b13w_release_node (indx_nptr, current);
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    IF  act_nptr.np_ptr^.nd_id = act_rootptr.np_ptr^.nd_id
                    THEN
                        BEGIN
                        (* split of root page is needed *)
                        (* *)
                        b13new_node (ins_level, new_rootptr, current);
                        IF  trError_gg00 = e_ok
                        THEN
                            BEGIN
                            b61change_content (act_nptr, new_rootptr, curr_trans);
                            IF  trError_gg00 = e_ok
                            THEN
                                BEGIN
                                s20ch4 (act_nptr.np_ptr^.nd_id,
                                      new_rootptr.np_ptr^,BODY_BEG_BD00);
                                index_pos := BODY_BEG_BD00 + sizeof (tsp00_PageNo);
                                s20ch4 (indx_pno, new_rootptr.np_ptr^, index_pos);
                                act_nptr.np_ptr^.nd_right := indx_pno;
                                new_rootptr.np_ptr^.nd_bottom :=
                                      index_pos + sizeof (tsp00_PageNo);
                                b13w_release_node (act_nptr, current);
                                IF  trError_gg00 = e_ok
                                THEN
                                    b13w_release_node (new_rootptr, current)
                                (*ENDIF*) 
                                END
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                        END
                    ELSE
                        BEGIN
                        b13w_release_node (act_nptr, current);
                        b61add_bstrindex (act_rootptr,
                              act_rootptr.np_ptr^.nd_id, indx_pno,
                              NIL_PAGE_NO_GG00, ins_level + 1, current)
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            ELSE
                BEGIN
                IF  act_nptr.np_ptr^.nd_id = act_rootptr.np_ptr^.nd_id
                THEN
                    b13w_release_node (act_rootptr, current)
                ELSE
                    BEGIN
                    b13w_release_node (act_nptr, current);
                    IF  trError_gg00 = e_ok
                    THEN
                        b13w_release_node (act_rootptr, current)
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 <> e_ok
    THEN
        BEGIN
        IF  act_nptr.np_ptr <> NIL
        THEN
            b13r_release_node (act_nptr, current, lru_normal);
        (*ENDIF*) 
        IF  indx_nptr.np_ptr <> NIL
        THEN
            b13r_release_node (indx_nptr, current, lru_normal);
        (*ENDIF*) 
        IF  new_rootptr.np_ptr <> NIL
        THEN
            b13r_release_node (new_rootptr, current, lru_normal)
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b61change_content (VAR nptr : tbd_node_ptrs;
            VAR rootptr : tbd_node_ptrs;
            t           : tgg00_TransContextPtr);
 
VAR
      changeptr : tbd_node_ptrs;
 
BEGIN
changeptr := nptr;
nptr      := rootptr;
rootptr   := changeptr;
g10mv ('VBD61 ',   1,    
      sizeof (rootptr.np_ptr^), sizeof (nptr.np_ptr^),
      @rootptr.np_ptr^, BODY_BEG_BD00,
      @nptr.np_ptr^, BODY_BEG_BD00, MAX_BSTR_COVERING_BD00, t^.trError_gg00);
IF  t^.trError_gg00 = e_move_error
THEN
    BEGIN
    t^.trError_gg00 := e_data_page_corrupted;
    b06dump_bad_page (t^.trTaskId_gg00, 'd', FILE_EXT_COR_BD00,
          rootptr.np_ptr^.nd_id, rootptr.np_ptr, 1);
    changeptr := nptr;
    nptr      := rootptr;
    rootptr   := changeptr;
    END
ELSE
    BEGIN
    WITH nptr.np_ptr^ DO
        BEGIN
        nd_level  := rootptr.np_ptr^.nd_level;
        nd_bottom := MAX_BOTTOM_BD00; (* set filling to maximum *)
        nd_right  := rootptr.np_ptr^.nd_right
        END;
    (*ENDWITH*) 
    WITH rootptr.np_ptr^ DO
        BEGIN
        nd_level := succ (nd_level);
        nd_right := NIL_PAGE_NO_GG00
        END
    (*ENDWITH*) 
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b61first_load_step (VAR leftptr : tbd_node_ptrs;
            VAR leafptr : tbd_node_ptrs;
            VAR current : tbd_current_tree);
 
VAR
      index_pos   : tsp00_Int4;
      save_bottom : tgg00_PagePos;
      rootptr     : tbd_node_ptrs;
 
BEGIN
WITH current, curr_trans^ DO
    IF  leafptr.np_ptr <> NIL
    THEN
        BEGIN
        b13new_node (LEAF_LEVEL_BD00, rootptr, current);
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            b61change_content (leftptr, rootptr, curr_trans);
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                index_pos  := BODY_BEG_BD00;
                s20ch4 (leftptr.np_ptr^.nd_id, rootptr.np_ptr^, index_pos);
                index_pos  := index_pos + sizeof (tsp00_PageNo);
                s20ch4 (leafptr.np_ptr^.nd_id, rootptr.np_ptr^, index_pos);
                rootptr.np_ptr^.nd_bottom := index_pos + sizeof (tsp00_PageNo);
                WITH leafptr.np_ptr^ DO
                    BEGIN
                    save_bottom        := nd_bottom;
                    b13init_default_data_page (curr_tree_id, LEAF_LEVEL_BD00, nd_id, leafptr);
                    nd_bottom          := save_bottom;
                    nd_left            := leftptr.np_ptr^.nd_id;
                    ndStrFileSize_bd00 := MAX_BSTR_COVERING_BD00 + nd_bottom - BODY_BEG_BD00;
                    END;
                (*ENDWITH*) 
                leftptr.np_ptr^.nd_right := leafptr.np_ptr^.nd_id;
                b13w_release_node (leftptr, current);
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    b13w_release_node (rootptr, current);
                    leftptr          := leafptr;
                    leafptr.np_ptr   := NIL;
                    leafptr.np_cbptr := NIL
                    END
                (*ENDIF*) 
                END
            ELSE
                b13free_node (rootptr, current)
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        leftptr.np_ptr^.ndStrFileSize_bd00 := leftptr.np_ptr^.nd_bottom -
              BODY_BEG_BD00;
        b13w_release_node (leftptr, current)
        END
    (*ENDIF*) 
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b61gfree_garb_node (
            pno         : tsp00_PageNo;
            twice       : boolean;
            VAR current : tbd_current_tree);
 
VAR
      rightNeighbor : tsp00_PageNo;
      nptr          : tbd_node_ptrs;
 
BEGIN
nptr.np_ptr   := NIL;
nptr.np_cbptr := NIL;
WITH current, curr_trans^ DO
    BEGIN
    bd13GetNode (current, pno, plmLock_ebd00, nr_for_update, nptr);
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        rightNeighbor := nptr.np_ptr^.nd_right;
        b13free_node (nptr, current);
        IF  (twice AND (rightNeighbor <> NIL_PAGE_NO_GG00))
        THEN
            BEGIN
            bd13GetNode (current, rightNeighbor, plmLock_ebd00, nr_for_update, nptr);
            IF  trError_gg00 = e_ok
            THEN
                b13free_node (nptr, current);
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b61rtrunc_bstrroot (VAR nptr : tbd_node_ptrs;
            new_flength : tsp00_Int4;
            VAR current : tbd_current_tree);
 
BEGIN
WITH current DO
    BEGIN
    nptr.np_ptr^.ndStrFileSize_bd00 := new_flength;
    nptr.np_ptr^.nd_bottom          := BODY_BEG_BD00 + new_flength;
    b13w_release_node (nptr, current)
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b61search_leaf (
            VAR nptr     : tbd_node_ptrs;
            pos          : tsp00_Int4;
            VAR leaf_pos : tsp00_Int4;
            VAR current  : tbd_current_tree);
 
VAR
      pno_pos : tsp00_Int4;
      level   : tsp00_Int4;
      result  : tsp00_Int4;
      subRoot : tsp00_PageNo;
      poslist : tbd_position_list;
 
BEGIN
leaf_pos := pos MOD MAX_BSTR_COVERING_BD00;
result   := pos DIV MAX_BSTR_COVERING_BD00;
FOR level := 1 TO MAX_BSTR_LEVEL_BD00 DO
    BEGIN
    IF  result <> 0
    THEN
        BEGIN
        poslist [level] := result MOD PNOS_PER_PAGE_BD00;
        result          := result DIV PNOS_PER_PAGE_BD00
        END
    ELSE
        poslist [level] := 0
    (*ENDIF*) 
    END;
(*ENDFOR*) 
level := nptr.np_ptr^.nd_level;
WITH current, curr_trans^ DO
    BEGIN
    WHILE (level > LEAF_LEVEL_BD00) AND (trError_gg00 = e_ok) DO
        BEGIN
        pno_pos := poslist [level] * sizeof (tsp00_PageNo) + BODY_BEG_BD00;
        subRoot := s20or4a (nptr.np_ptr^, pno_pos);
        b13r_release_node (nptr, current, lru_normal);
        bd13GetNode (current, subRoot, plmLock_ebd00, nr_for_read, nptr);
        level := level - 1
        END
    (*ENDWHILE*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b61trunc_bstr (VAR nptr : tbd_node_ptrs;
            new_flength : tsp00_Int4;
            destroy     : boolean;
            VAR current : tbd_current_tree);
 
VAR
      is_root          : boolean;
      reduce_tree      : boolean;
      aux_error        : tgg00_BasisError;
      act_level        : tsp00_Int2;
      act_root_level   : tsp00_Int2;
      aux_level        : tsp00_Int2;
      nnptr            : tbd_node_ptrs;
      pno              : tsp00_PageNo;
      result           : tsp00_Int4;
      leaf_pos         : tsp00_Int4;
      i                : tsp00_Int4;
      index_pos        : tsp00_Int4;
      poslist          : tbd_position_list;
      old_conv_version : tsp00_Int4;
      old_left         : tsp00_PageNo;
      old_write_cnt    : tsp00_Int4;
      old_ndStrFileSize_bd00 : tsp00_Int4;
      old_str_version  : tsp00_Int4;
 
BEGIN
is_root                  := true;
nnptr.np_ptr             := NIL;
nnptr.np_cbptr           := NIL;
nptr.np_ptr^.ndStrFileSize_bd00 := new_flength;
act_root_level           := nptr.np_ptr^.nd_level;
new_flength              := new_flength - 1;
leaf_pos                 := new_flength MOD MAX_BSTR_COVERING_BD00;
result                   := new_flength DIV MAX_BSTR_COVERING_BD00;
act_level                := succ (LEAF_LEVEL_BD00);
WITH current, curr_trans^ DO
    BEGIN
    WHILE act_level <= MAX_BSTR_LEVEL_BD00 DO
        BEGIN
        IF  result <> 0
        THEN
            BEGIN
            poslist [act_level] := result MOD PNOS_PER_PAGE_BD00;
            result              := result DIV PNOS_PER_PAGE_BD00
            END
        ELSE
            poslist [act_level] := 0;
        (*ENDIF*) 
        act_level := succ (act_level)
        END;
    (*ENDWHILE*) 
    act_level := nptr.np_ptr^.nd_level;
    i := act_level;
    aux_error := e_ok;
    WHILE (act_level > LEAF_LEVEL_BD00) AND (trError_gg00 = e_ok) DO
        BEGIN
        index_pos := BODY_BEG_BD00 + poslist [i] * sizeof (tsp00_PageNo);
        pno       := s20or4a (nptr.np_ptr^, index_pos);
        bd13GetNode (current, pno, plmLock_ebd00, nr_for_update, nnptr);
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            index_pos := index_pos + sizeof (tsp00_PageNo);
            WHILE (trError_gg00 = e_ok) AND
                  (nptr.np_ptr^.nd_bottom > index_pos) DO
                BEGIN
                nptr.np_ptr^.nd_bottom := nptr.np_ptr^.nd_bottom -
                      sizeof (tsp00_PageNo);
                pno := s20or4a (nptr.np_ptr^, nptr.np_ptr^.nd_bottom);
                bd61free_bstrnode (pno, act_level, current);
                IF  trError_gg00 = e_bad_datapage
                THEN
                    BEGIN
                    aux_error := trError_gg00;
                    trError_gg00    := e_ok
                    END
                (*ENDIF*) 
                END;
            (*ENDWHILE*) 
            IF  (trError_gg00 = e_ok)
            THEN
                BEGIN
                reduce_tree := false;
                IF  poslist [i] = 0
                THEN
                    BEGIN
                    reduce_tree := true;
                    aux_level   := i + 1;
                    WHILE reduce_tree AND (aux_level <= act_root_level) DO
                        BEGIN
                        reduce_tree := poslist [aux_level] = 0;
                        aux_level   := succ (aux_level)
                        END
                    (*ENDWHILE*) 
                    END;
                (*ENDIF*) 
                IF  reduce_tree
                THEN
                    BEGIN
                    WITH nptr.np_ptr^ DO
                        BEGIN
                        pno                       := nd_id;
                        old_ndStrFileSize_bd00    := ndStrFileSize_bd00;
                        old_str_version           := nd_str_version;
                        old_conv_version          := nd_conv_version;
                        old_left                  := nd_left;
                        old_write_cnt             := nd_write_cnt
                        END;
                    (*ENDWITH*) 
                    g10mv ('VBD61 ',   2,    
                          sizeof (nnptr.np_ptr^), sizeof (nptr.np_ptr^),
                          @nnptr.np_ptr^, 1,
                          @nptr.np_ptr^, 1, nnptr.np_ptr^.nd_bottom -1,
                          trError_gg00);
                    IF  trError_gg00 = e_move_error
                    THEN
                        BEGIN
                        trError_gg00 := e_data_page_corrupted;
                        b06dump_bad_page (trTaskId_gg00, 'd',
                              FILE_EXT_COR_BD00, nnptr.np_ptr^.nd_id,
                              nnptr.np_ptr, 1)
                        END
                    ELSE
                        BEGIN
                        WITH nptr.np_ptr^ DO
                            BEGIN
                            nd_id           := pno;
                            ndStrFileSize_bd00 := old_ndStrFileSize_bd00;
                            nd_str_version  := old_str_version;
                            nd_conv_version := old_conv_version;
                            nd_left         := old_left;
                            nd_write_cnt    := old_write_cnt;
                            nd_checktype    := chckChecksumData_egg00;
                            nd_trailer      := nd_header
                            END;
                        (*ENDWITH*) 
                        b13free_node (nnptr, current)
                        END
                    (*ENDIF*) 
                    END
                ELSE
                    BEGIN
                    b13w_release_node (nptr, current);
                    IF  trError_gg00 = e_ok
                    THEN
                        nptr := nnptr
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                act_level := pred (act_level);
                i := act_level
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    IF  trError_gg00 = e_ok
    THEN
        trError_gg00 := aux_error;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        nptr.np_ptr^.nd_bottom := BODY_BEG_BD00 + leaf_pos + 1;
        nptr.np_ptr^.nd_right  := NIL_PAGE_NO_GG00;
        IF  NOT destroy
        THEN
            b13w_release_node (nptr, current)
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  (trError_gg00 <> e_ok) AND (nnptr.np_ptr <> NIL)
    THEN
        b13r_release_node (nnptr, current, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b61wsearch_writeleaf (VAR nptr : tbd_node_ptrs;
            pos               : tsp00_Int4;
            VAR leaf_pos      : tsp00_Int4;
            VAR pre_last_page : boolean;
            VAR current       : tbd_current_tree);
 
VAR
      first   : boolean;
      i       : tsp00_Int4;
      pno_pos : tsp00_Int4;
      result  : tsp00_Int4;
      new_pno : tsp00_PageNo;
      poslist : tbd_position_list;
 
BEGIN
leaf_pos := pos MOD MAX_BSTR_COVERING_BD00;
result := pos DIV MAX_BSTR_COVERING_BD00;
FOR i := 1 TO MAX_BSTR_LEVEL_BD00 DO
    BEGIN
    IF  result <> 0
    THEN
        BEGIN
        poslist [i] := result MOD PNOS_PER_PAGE_BD00;
        result := result DIV PNOS_PER_PAGE_BD00
        END
    ELSE
        poslist [i] := 0
    (*ENDIF*) 
    END;
(*ENDFOR*) 
i := nptr.np_ptr^.nd_level;
first := true;
pre_last_page := false;
WHILE (i > LEAF_LEVEL_BD00) AND (current.curr_trans^.trError_gg00 = e_ok) DO
    BEGIN
    pno_pos := poslist [i] * sizeof (tsp00_PageNo) + BODY_BEG_BD00;
    IF  pno_pos + sizeof (tsp00_PageNo) < nptr.np_ptr^.nd_bottom
    THEN
        pre_last_page := true;
    (*ENDIF*) 
    new_pno := s20or4a (nptr.np_ptr^, pno_pos);
    IF  NOT first
    THEN
        b13r_release_node (nptr, current, lru_normal)
    ELSE
        first := false;
    (*ENDIF*) 
    IF  i > succ (LEAF_LEVEL_BD00)
    THEN
        bd13GetNode (current, new_pno, plmLock_ebd00, nr_for_read, nptr)
    ELSE
        bd13GetNode (current, new_pno, plmLock_ebd00, nr_for_update, nptr);
    (*ENDIF*) 
    i := i - 1
    END
(*ENDWHILE*) 
END;
 
(*========== locals ============*)
(*------------------------------*) 
 
PROCEDURE
      bd61free_bstrnode (pno : tsp00_PageNo;
            act_level   : tsp00_Int2;
            VAR current : tbd_current_tree);
 
VAR
      aux_error  : tgg00_BasisError;
      nptr       : tbd_node_ptrs;
      index_pos  : tsp00_Int4;
 
BEGIN
nptr.np_ptr   := NIL;
nptr.np_cbptr := NIL;
WITH current, curr_trans^ DO
    BEGIN
    IF  act_level = succ (LEAF_LEVEL_BD00)
    THEN
        BEGIN
        bd13GetNode (current, pno, plmLock_ebd00, nr_for_update, nptr);
        IF  trError_gg00 = e_ok
        THEN
            b13free_node (nptr, current)
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        bd13GetNode (current, pno, plmLock_ebd00, nr_for_update, nptr);
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            index_pos := BODY_BEG_BD00;
            act_level := nptr.np_ptr^.nd_level;
            aux_error := e_ok;
            WHILE (index_pos < nptr.np_ptr^.nd_bottom)
                  AND (trError_gg00 = e_ok) DO
                BEGIN
                pno := s20or4a (nptr.np_ptr^, index_pos);
                bd61free_bstrnode (pno, act_level, current);
                index_pos := index_pos + sizeof (tsp00_PageNo);
                IF  trError_gg00 = e_bad_datapage
                THEN
                    BEGIN
                    aux_error    := trError_gg00;
                    trError_gg00 := e_ok
                    END;
                (*ENDIF*) 
                END;
            (*ENDWHILE*) 
            IF  trError_gg00 = e_ok
            THEN
                b13free_node (nptr, current);
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                trError_gg00 := aux_error
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  (trError_gg00 <> e_ok) AND (nptr.np_ptr <> NIL)
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
