.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$VBD30$
.tt 2 $$$
.tt 3 $JuergenP$treehandling$$$$2000-10-04$
***********************************************************
.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  : treehandling
=========
.sp
Purpose : - general tree operations
          - tree operations managing primary data
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :
 
        PROCEDURE
              b30cappend_to_tree (
                    VAR rk       : tgg00_Lkey;
                    VAR b        : tgg00_Rec;
                    VAR tree_pos : tgg00_FilePos;
                    VAR current  : tbd_current_tree);
 
        PROCEDURE
              b30cget_result_leaf (
                    VAR rk          : tgg00_Lkey;
                    get_next        : boolean;
                    prepare_for_upd : boolean;
                    VAR tree_pos    : tgg00_FilePos;
                    VAR nptr        : tbd_node_ptrs;
                    VAR current     : tbd_current_tree);
 
        PROCEDURE
              b30cnext_from_tree (
                    VAR rk         : tgg00_Lkey;
                    VAR set_result : tgg00_BdSetResultRecord;
                    VAR tree_pos   : tgg00_FilePos;
                    VAR b          : tsp00_MoveObj;
                    VAR current    : tbd_current_tree);
 
        PROCEDURE
              b30cprev_from_tree (
                    VAR rk         : tgg00_Lkey;
                    VAR set_result : tgg00_BdSetResultRecord;
                    VAR tree_pos   : tgg00_FilePos;
                    VAR b          : tsp00_MoveObj;
                    VAR current    : tbd_current_tree);
 
        PROCEDURE
              b30database_verify (
                    VAR t              : tgg00_TransContext;
                    VAR bad_index_cnt  : tsp00_Int4;
                    VAR total_bad_cnt  : tsp00_Int4;
                    VAR verify_error   : tgg00_BasisError;
                    bWithUpdate        : boolean;
                    bWithExtendedCheck : boolean;
                    bWithIndexes       : boolean;
                    max_server         : integer);
 
        PROCEDURE
              b30fdir_to_treeid (VAR fi : tbd_fileinfo;
                    VAR file_id : tgg00_FileId);
 
        PROCEDURE
              b30init_load (VAR rightmost_leaf : tsp00_PageNo;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b30load_table (VAR lnptr : tbd_node_ptrs;
                    VAR nptr           : tbd_node_ptrs;
                    only_left          : boolean;
                    VAR current        : tbd_current_tree);
 
        PROCEDURE
              b30new_tree (VAR fi : tbd_fileinfo;
                    VAR current   : tbd_current_tree);
 
        PROCEDURE
              bd30AddFileState (
                    VAR current : tbd_current_tree;
                    fileState   : tbd_file_state_set);
 
        PROCEDURE
              bd30AddToTempTree (
                    bCountDuplicates : boolean;
                    VAR rec          : tgg00_Rec;
                    VAR current      : tbd_current_tree);
 
        PROCEDURE
              bd30AddToTree (
                    VAR recKey  : tgg00_Lkey;
                    VAR rec     : tgg00_Rec;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              bd30BadFile (
                    VAR trans  : tgg00_TransContext;
                    VAR fileId : tgg00_FileId);
 
        PROCEDURE
              bd30BuildCurrent (
                    VAR trans   : tgg00_TransContext;
                    VAR fileId  : tgg00_FileId;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              bd30CheckTree (
                    VAR trans           : tgg00_TransContext;
                    VAR fileId          : tgg00_FileId;
                    longColCnt          : tsp00_Int2;
                    newLongColCnt       : tsp00_Int2;
                    bWithExtendedCheck  : boolean;
                    bCheckLongExistence : boolean);
 
        PROCEDURE
              bd30CreateBeforeImageForDelete (
                    VAR m          : tgg00_MessBlock;
                    pDeleteCmd     : tsp00_Addr;
                    VAR rk         : tgg00_Lkey;
                    VAR old_recbuf : tgg00_Rec;
                    granted_lock   : tgg00_LockReqMode;
                    VAR current    : tbd_current_tree);
 
        PROCEDURE
              bd30CreateBeforeImageForInsert (
                    VAR rk              : tgg00_Lkey;
                    VAR b               : tgg00_Rec;
                    VAR m               : tgg00_MessBlock;
                    pInsertCmd          : tsp00_Addr;
                    granted_lock        : tgg00_LockReqMode;
                    VAR current         : tbd_current_tree);
 
        PROCEDURE
              bd30CreateBeforeImageForSysKeyInsert (
                    VAR rk          : tgg00_Lkey;
                    VAR b           : tgg00_Rec;
                    VAR m           : tgg00_MessBlock;
                    pInsertCmd      : tsp00_Addr;
                    granted_lock    : tgg00_LockReqMode;
                    VAR current     : tbd_current_tree);
 
        PROCEDURE
              bd30CreateBeforeImageForUpdate (
                    VAR m              : tgg00_MessBlock;
                    pUpdateCmd         : tsp00_Addr;
                    VAR rk             : tgg00_Lkey;
                    VAR old_recbuf     : tgg00_Rec;
                    VAR new_recbuf     : tgg00_Rec;
                    granted_lock       : tgg00_LockReqMode;
                    VAR current        : tbd_current_tree);
 
        PROCEDURE
              bd30CreateCoordinator (
                    VAR t      : tgg00_TransContext;
                    MessType   : tgg00_MessType);
 
        PROCEDURE
              bd30DelFromTree (
                    VAR recKey  : tgg00_Lkey;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              bd30DropTree (
                    VAR current     : tbd_current_tree;
                    longColumnCount : integer;
                    bOnlyEmpty      : boolean);
 
        PROCEDURE
              bd30ExistRecord (
                    VAR recKey  : tgg00_Lkey;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              bd30FindLeaf (
                    VAR key     : tgg00_Lkey;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              bd30GetFromTree (
                    VAR recKey  : tgg00_Lkey;
                    VAR rec     : tgg00_Rec;
                    VAR current : tbd_current_tree;
                    wantedLock  : tgg00_LockReqMode);
 
        PROCEDURE
              bd30GetFromTreeWithTreepos (
                    VAR recKey  : tgg00_Lkey;
                    VAR rec     : tgg00_Rec;
                    VAR tree_pos   : tgg00_FilePos;
                    VAR current : tbd_current_tree;
                    wantedLock  : tgg00_LockReqMode);
 
        PROCEDURE
              bd30GetNextLeafPage (
                    VAR nextLeafPage : tsp00_PageNo;
                    VAR nptr         : tbd_node_ptrs;
                    VAR current      : tbd_current_tree);
 
        PROCEDURE
              bd30GetNextLong (
                    VAR recKey      : tgg00_Lkey;
                    numberOfLongs   : integer;
                    VAR currentLong : integer;
                    VAR longFileId  : tgg00_FileId;
                    VAR filePos     : tgg00_FilePos;
                    VAR current     : tbd_current_tree);
 
        PROCEDURE
              bd30GetTree (
                    VAR trans      : tgg00_TransContext;
                    VAR fileId     : tgg00_FileId;
                    VAR current    : tbd_current_tree;
                    bTreeExclusive : boolean;
                    messType       : tgg00_MessType);
 
        PROCEDURE
              bd30GetSubTree (
                    VAR current : tbd_current_tree;
                    indexPageNo : tsp00_PageNo);
 
        PROCEDURE
              bd30NextFromTree (
                    VAR recKey   : tgg00_Lkey;
                    bInclusive   : boolean;
                    VAR rec      : tgg00_Rec;
                    VAR current  : tbd_current_tree);
 
        PROCEDURE
              bd30PrevFromTree (
                    VAR recKey  : tgg00_Lkey;
                    bInclusive  : boolean;
                    VAR rec     : tgg00_Rec;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              bd30ReleaseTree (
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              bd30ReleaseSubTree(
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              bd30ReplaceInTree (
                    VAR recKey  : tgg00_Lkey;
                    VAR rec     : tgg00_Rec;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              bd30ReplaceInTreeWithTreepos (
                    VAR rec      : tgg00_Rec;
                    VAR tree_pos : tgg00_FilePos;
                    VAR current  : tbd_current_tree);
 
        PROCEDURE
              bd30ResetBadFile (
                    VAR trans  : tgg00_TransContext;
                    VAR fileId : tgg00_FileId);
 
        PROCEDURE
              bd30SearchRecord(
                    VAR current      : tbd_current_tree;
                    VAR recKey       : tsp00_Key (* ptocSynonym tsp00_KeyPtr *);
                    recKeyLen        : tsp00_Int4;
                    VAR nptr         : tbd_node_ptrs;
                    VAR recIndex     : tsp00_Int4;
                    VAR neighbs      : tbd_neighbors;
                    VAR searchResult : tbd_searchresult);
 
        PROCEDURE
              bd30SetReadOnly (
                    VAR trans  : tgg00_TransContext;
                    VAR fileId : tgg00_FileId);
 
        PROCEDURE
              bd30SetFileVersion (
                    VAR current    : tbd_current_tree;
                    newfileVersion : tgg91_FileVersion);
 
        PROCEDURE
              bd30SubFileState (
                    VAR current : tbd_current_tree;
                    fileState   : tbd_file_state_set);
 
        PROCEDURE
              bd30OmsReadAheadCoordinator (VAR t : tgg00_TransContext;
                    ReadAheadServer : integer);
 
        PROCEDURE
              bd30VerifyTree (
                    VAR trans          : tgg00_TransContext;
                    VAR fileId         : tgg00_FileId;
                    bUpdateConverter   : boolean;
                    bWithExtendedCheck : boolean;
                    VAR numPages       : tsp00_Int4);
              (* ptocExport hbd30_1.h *)
 
        PROCEDURE
              bd30ObjFileCoordinator (
                    VAR t           : tgg00_TransContext;
                    mtype           : tgg00_MessType;    (* PTS 1113635 FF *)
                    NumRepairServer : integer);
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              filesysteminterface_1 : VBD01;
 
        VAR
              b01downfilesystem : boolean;
              b01niltree_id     : tgg00_FileId;
              b01fullkey        : tsp00_Key;
 
        PROCEDURE
              b01pverify_participant (
                    VAR t              : tgg00_TransContext;
                    VAR file_id        : tgg00_FileId;
                    is_cold            : boolean;
                    bWithExtendedCheck : boolean);
 
        PROCEDURE
              bd01SetToNilCurrent(
                    VAR current : tbd_current_tree );
 
      ------------------------------ 
 
        FROM
              filesysteminterface_4 : VBD04;
 
        PROCEDURE
              bd04OmsReadAheadParticipant (VAR t : tgg00_TransContext;
                    VAR FileId : tgg00_FileId);
 
      ------------------------------ 
 
        FROM
              error_text_handling : VBD06;
 
        PROCEDURE
              b06file_opmsg (
                    msg_no     : tsp00_Int4;
                    VAR fileId : tgg00_FileId);
 
        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);
 
        PROCEDURE
              b06write_filename_and_root (VAR file_id : tgg00_FileId);
 
        PROCEDURE
              bd06IllegalRootAccess (
                    VAR trans  : tgg00_TransContext;
                    VAR fileId : tgg00_FileId);
 
      ------------------------------ 
 
        FROM
              Trace : VBD120;
 
        PROCEDURE
              b120InsertTrace (VAR t   : tgg00_TransContext;
                    trace_layer  : tgg00_Debug;
                    trace_object : tgg00_VtraceType;
                    body_len     : tsp00_Int2;
                    trace_body   : tgg11_VtraceBodyPtr);
 
      ------------------------------ 
 
        FROM
              nodehandling : VBD13;
 
        PROCEDURE
              b13init_default_data_page (
                    VAR FileId  : tgg00_FileId;
                    Level       : tsp00_Int2;
                    NewPno      : tsp00_PageNo;
                    VAR Nptrs   : tbd_node_ptrs);
 
        PROCEDURE
              b13new_root (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);
 
        PROCEDURE
              bd13FreePnosAfterUnlock(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
              bd13WriteExclusiveLockedRoot (VAR current : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              filedirectory : VBD17;
 
        PROCEDURE
              b17fadd_file_state (
                    VAR t      : tgg00_TransContext;
                    VAR fileId : tgg00_FileId;
                    new_state  : tbd_file_state_set);
 
        PROCEDURE
              b17fsub_file_state (
                    VAR t      : tgg00_TransContext;
                    VAR fileId : tgg00_FileId;
                    subState   : tbd_file_state_set);
 
        PROCEDURE
              b17state_fdir (VAR fn : tgg00_Filename;
                    VAR fi          : tbd_fileinfo;
                    concurrent_file : boolean;
                    VAR t           : tgg00_TransContext);
 
        PROCEDURE
              b17succ_fdir (VAR fn  : tgg00_Filename;
                    VAR next_fn     : tgg00_Filename;
                    VAR fi          : tbd_fileinfo;
                    shared_file     : boolean;
                    VAR t           : tgg00_TransContext;
                    include_strcols : boolean);
 
        FUNCTION
              bd17GetFdirRoot : tsp00_PageNo;
 
        FUNCTION
              bd17GetLongFdirRoot : tsp00_PageNo;
 
      ------------------------------ 
 
        FROM
              systembufferinterface : VBD20;
 
        FUNCTION
              bd20IsPageExclusiveLocked (
                    pCBlock : tbd_nodeptr) : boolean;
 
      ------------------------------ 
 
        FROM
              leafhandling : VBD31;
 
        PROCEDURE
              b31add_to_leaf (VAR b : tgg00_Rec;
                    VAR nptr    : tbd_node_ptrs;
                    index       : integer;
                    left        : tsp00_PageNo;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b31append_to_leaf (VAR b : tgg00_Rec;
                    VAR nptr           : tbd_node_ptrs;
                    index              : integer;
                    page_fill_limit    : integer;
                    left               : tsp00_PageNo;
                    VAR current        : tbd_current_tree);
 
        PROCEDURE
              b31del_from_leaf (VAR nptr : tbd_node_ptrs;
                    index       : integer;
                    left        : tsp00_PageNo;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b31get_from_leaf (VAR nptr : tbd_node_ptrs;
                    index        : integer;
                    with_kb_lock : boolean;
                    VAR b        : tgg00_Rec;
                    VAR current  : tbd_current_tree);
 
        PROCEDURE
              b31next_search (
                    VAR nptr    : tbd_node_ptrs;
                    VAR index   : integer;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b31nfill_recordbuffer (VAR nptr : tbd_node_ptrs;
                    VAR test_key   : tgg00_Lkey;
                    VAR tree_pos   : tgg00_FilePos;
                    VAR set_result : tgg00_BdSetResultRecord;
                    VAR b          : tsp00_MoveObj;
                    VAR current    : tbd_current_tree);
 
        PROCEDURE
              b31pfill_recordbuffer (VAR nptr : tbd_node_ptrs;
                    VAR test_key   : tgg00_Lkey;
                    VAR tree_pos   : tgg00_FilePos;
                    VAR set_result : tgg00_BdSetResultRecord;
                    VAR b          : tsp00_MoveObj;
                    VAR current    : tbd_current_tree);
 
        PROCEDURE
              b31prev_search (VAR reckey : tsp00_Key;
                    KeyLen        : tsp00_Int4;
                    VAR nptr      : tbd_node_ptrs;
                    VAR index     : integer;
                    VAR prev_leaf : tsp00_PageNo;
                    VAR current   : tbd_current_tree);
 
        PROCEDURE
              b31repl_in_leaf (VAR b : tgg00_Rec;
                    VAR nptr    : tbd_node_ptrs;
                    index       : integer;
                    left        : tsp00_PageNo;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b31search_entry (VAR current : tbd_current_tree;
                    VAR rk     : tsp00_Key;
                    KeyLen     : tsp00_Int4;
                    VAR nptr   : tbd_nodeptr;
                    VAR index  : tsp00_Int4;
                    VAR result : tbd_searchresult);
 
        PROCEDURE
              b31t_append_to_temp_leaf (VAR b : tgg00_Rec;
                    VAR nptr     : tbd_node_ptrs;
                    VAR tree_pos : tgg00_FilePos;
                    VAR current  : tbd_current_tree);
 
        PROCEDURE
              b31t_prev_temp_search (VAR nptr : tbd_node_ptrs;
                    VAR index   : integer;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b31w_next_search (VAR nptr : tbd_node_ptrs;
                    VAR index   : integer;
                    VAR current : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              indexhandling : VBD50;
 
        PROCEDURE
              bd50CheckSubTree (
                    subRoot               : tsp00_PageNo;
                    right                 : tsp00_PageNo;
                    longColCnt            : tsp00_Int2;
                    newLongColCnt         : tsp00_Int2;
                    VAR scanCount         : tsp00_Int4;
                    VAR boundNeighborLeaf : tsp00_PageNo;
                    VAR bDumpParent       : boolean;
                    VAR bLongIsBad        : boolean;
                    VAR reEntranceKey     : tgg00_Lkey;
                    VAR checkKey          : tgg00_Lkey;
                    VAR current           : tbd_current_tree;
                    bWithExtendedCheck    : boolean;
                    bCheckLongExistence   : boolean);
 
        PROCEDURE
              bd50DetermineLeafNode (
                    VAR current  : tbd_current_tree;
                    pSepKey      : tsp00_KeyAddr;
                    keyLen       : tsp00_Int4;
                    VAR recIndex : tsp00_Int4;
                    VAR leaf     : tsp00_PageNo;
                    VAR leftLeaf : tsp00_PageNo);
 
        PROCEDURE
              bd50DropSubTree (
                    root          : tsp00_PageNo;
                    numberOfLongs : integer;
                    bOnlyEmpty    : boolean;
                    VAR current   : tbd_current_tree);
 
        PROCEDURE
              bd50FindLeaf (
                    VAR sepKey          : tsp00_Key;
                    keyLen              : tsp00_Int4;
                    VAR nptrs           : tbd_node_ptrs;
                    VAR neighbs         : tbd_neighbors;
                    VAR recIndexForLeaf : tsp00_Int4;
                    VAR current         : tbd_current_tree);
 
        FUNCTION
              bd50IndexNodeIsSaveForDelete (
                    VAR current   : tbd_current_tree;
                    recIndex      : tsp00_Int4;
                    maximumKeyLen : tsp00_Int4) : boolean;
 
        FUNCTION
              bd50IndexNodeIsSaveForInsert (
                    VAR current   : tbd_current_tree;
                    recIndex      : tsp00_Int4;
                    newKeyLen     : tsp00_Int4;
                    maximumKeyLen : tsp00_Int4) : boolean;
 
        FUNCTION
              bd50IndexNodeIsSaveForReplace (
                    VAR current   : tbd_current_tree;
                    bIsGrowing    : boolean;
                    recIndex      : tsp00_Int4;
                    newKeyLen     : tsp00_Int4;
                    maximumKeyLen : tsp00_Int4) : boolean;
 
        PROCEDURE
              bd50VerifySubTree (
                    subRoot               : tsp00_PageNo;
                    right                 : tsp00_PageNo;
                    bUpdateConverter      : boolean;
                    bWithExtendedCheck    : boolean;
                    VAR reEntranceKey     : tgg00_Lkey;
                    VAR checkKey          : tgg00_Lkey;
                    VAR boundNeighborLeaf : tsp00_PageNo;
                    VAR bDumpParent       : boolean;
                    VAR current           : tbd_current_tree;
                    VAR scanCount         : tsp00_Int4;
                    VAR numPages          : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              branchhandling : VBD52;
 
        FUNCTION
              bd52SubtreePno (
                    VAR nptr : tbd_nodeptr;
                    RecIndex : tsp00_Int4) : tsp00_PageNo;
 
      ------------------------------ 
 
        FROM
              indexing : VBD53;
 
        PROCEDURE
              bd53NewLeafIndex (VAR Nptr : tbd_nodeptr;
                    VAR Nnptr        : tbd_nodeptr;
                    VAR NewSeparator : tgg00_Lkey;
                    t                : tgg00_TransContextPtr);
 
      ------------------------------ 
 
        FROM
              indexupdateorders : VBD54;
 
        PROCEDURE
              b54add_index (pSep       : tsp00_KeyAddr;
                    SepLen             : 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
              ref_statistic : VBD73;
 
        PROCEDURE
              b73cmd_count (statement_kind : tgg00_RefInfoIndex);
 
      ------------------------------ 
 
        FROM
              InvHandling : VBD300;
 
        PROCEDURE
              bd300FileIdRootCheck (VAR FileId  : tgg00_FileId;
                    VAR TrError : tgg00_BasisError);
 
        PROCEDURE
              bd300SetRootCheck (VAR FileId  : tgg00_FileId);
 
      ------------------------------ 
 
        FROM
              RTE_kernel : VEN101;
 
        PROCEDURE
              vsleep (pid : tsp00_TaskId;
                    limit : tsp00_Int2);
 
      ------------------------------ 
 
        FROM
              Configuration_Parameter : VGG01;
 
        VAR
              g01vtrace : tgg00_VtraceState;
              g01glob   : tgg00_KernelGlobals;
 
        PROCEDURE
              g01abort (msg_no : tsp00_Int4;
                    msg_label : tsp00_C8;
                    msg_text  : tsp00_C24;
                    bad_value : tsp00_Int4);
 
        PROCEDURE
              g01mblock_init (VAR source_trans : tgg00_TransContext;
                    mess_type  : tgg00_MessType;
                    mess2_type : tgg00_MessType2;
                    VAR mblock : tgg00_MessBlock);
 
        PROCEDURE
              g01opmsg (msg_prio : tsp3_priority;
                    msg_type  : tsp3_msg_type;
                    msg_no    : tsp00_Int4;
                    msg_label : tsp00_C8;
                    msg_text  : tsp00_C24;
                    msg_value : tsp00_Int4);
 
        PROCEDURE
              g01optextmsg (msg_prio : tsp3_priority;
                    msg_type  : tsp3_msg_type;
                    msg_no    : tsp00_Int4;
                    msg_label : tsp00_C8;
                    msg_text  : tsp00_C40);
 
      ------------------------------ 
 
        FROM
              Select_Help_Procedures : VGG04;
 
        PROCEDURE
              g04locate_col (VAR st : tgg00_StackEntry;
                    rec_buf        : tgg00_RecPtr;
                    VAR varcol_pos : tgg00_VarColPosList;
                    VAR col_pos    : integer;
                    VAR col_len    : integer);
 
        FUNCTION
              g04inv_tfn (Tfn : tgg00_Tfn) : boolean;
 
      ------------------------------ 
 
        FROM
              GG_cpp_auxiliary_functions : VGG06;
 
        FUNCTION
              gg06TransGetInt4 (VAR TransNo : tgg91_TransNo): tsp00_Int4;
 
        FUNCTION
              gg06Min (
                    value1 : tsp00_Int4;
                    value2 : tsp00_Int4 ) : tsp00_Int4;
 
        FUNCTION
              gg06PnoGet (VAR Cint4 : tgg90_Cint4): tsp00_Int4;
 
        PROCEDURE
              gg06PnoPut (VAR Cint4 : tgg90_Cint4; int4 : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG101;
 
        PROCEDURE
              SAPDB_PascalFill (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    obj_upb     : tsp00_Int4;
                    obj         : tsp00_MoveObjPtr;
                    obj_pos     : tsp00_Int4;
                    length      : tsp00_Int4;
                    fillchar    : char;
                    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);
 
      ------------------------------ 
 
        FROM
              GG_edit_routines : VGG17;
 
        PROCEDURE
              g17hexto_line (c : char;
                    VAR ln_len : integer;
                    VAR ln     : tsp00_C40);
 
        PROCEDURE
              g17nameto_line (n : tsp00_Name;
                    VAR ln_len  : integer;
                    VAR ln      : tsp00_C40);
 
        PROCEDURE
              g17trimint4_to_line (int : tsp00_Int4;
                    VAR ln_len : integer;
                    VAR ln     : tsp_c40);
 
        PROCEDURE
              g17basis_err_to_line (b_err : tgg00_BasisError;
                    VAR ln_len : integer;
                    VAR ln     : tsp00_C40);
 
      ------------------------------ 
 
        FROM
              KB_transaction : VKB53;
 
        PROCEDURE
              k53child_trans_build (MessType : tgg00_MessType;
                    TransCnt       : tsp00_Int4;
                    VAR ChildTrans : tgg00_TransChild);
 
      ------------------------------ 
 
        FROM
              KB_ins_del_upd : VKB61;
 
        PROCEDURE
              k61bd_del (VAR m     : tgg00_MessBlock;
                    pDeleteCmd     : tsp00_Addr;
                    VAR old_recbuf : tgg00_Rec;
                    granted_lock   : tgg00_LockReqMode);
 
        PROCEDURE
              k61bd_ins (VAR m   : tgg00_MessBlock;
                    pInsertCmd   : tsp00_Addr;
                    VAR b        : tgg00_Rec;
                    granted_lock : tgg00_LockReqMode);
 
      ------------------------------ 
 
        FROM
              KB_InsDelUpd_interface : VKB611;
 
        PROCEDURE
              kb611ins_WriteBeforeImage (
                    pInsertCmd       : tsp00_Addr;
                    VAR TransContext : tgg00_TransContext);
 
      ------------------------------ 
 
        FROM
              KB_update : VKB63;
 
        PROCEDURE
              k63bd_upd (VAR m     : tgg00_MessBlock;
                    pUpdateCmd     : tsp00_Addr;
                    VAR old_recbuf : tgg00_Rec;
                    VAR new_recbuf : tgg00_Rec;
                    granted_lock   : tgg00_LockReqMode);
 
      ------------------------------ 
 
        FROM
              KB_sender_receiver : VKB90;
 
        PROCEDURE
              k90rcv_child (VAR mblock : tgg00_MessBlock;
                    VAR child_trans    : tgg00_TransChild);
 
        PROCEDURE
              k90send (VAR mblock    : tgg00_MessBlock;
                    VAR remote_trans : tgg00_TransChild);
 
      ------------------------------ 
 
        FROM
              RTE-Extension-30 : VSP30;
 
        PROCEDURE
              s30cmp (VAR buf1   : tsp00_MoveObj;
                    fieldpos1    : tsp00_Int4;
                    fieldlength1 : tsp00_Int4;
                    VAR buf2     : tsp00_Buf;
                    fieldpos2    : tsp00_Int4;
                    fieldlength2 : tsp00_Int4;
                    VAR l_result : tsp00_LcompResult);
&       ifdef TRACE
 
      ------------------------------ 
 
        FROM
              Test_Procedures : VTA01;
 
        PROCEDURE
              t01basis_error (layer : tgg00_Debug;
                    nam   : tsp00_Sname;
                    b_err : tgg00_BasisError);
 
        PROCEDURE
              t01buf (debug  : tgg00_Debug;
                    VAR buf  : tgg00_Rec;
                    startpos : integer;
                    endpos   : integer);
 
        PROCEDURE
              t01int4 (debug : tgg00_Debug;
                    nam      : tsp00_Sname;
                    int4     : tsp00_Int4);
 
        PROCEDURE
              t01key (
                    debug   : tgg00_Debug;
                    nam     : tsp00_Sname;
                    VAR k   : tgg00_Lkey);
 
        PROCEDURE
              t01p2int4 (debug : tgg00_Debug;
                    nam_1 : tsp00_Sname;
                    int_1 : tsp00_Int4;
                    nam_2 : tsp00_Sname;
                    int_2 : tsp00_Int4);
&       endif
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              b06dump_bad_page;
 
              tbd_univ_ptr tbd_nodeptr
 
        FUNCTION
              bd20IsPageExclusiveLocked;
 
              tbd02_pDataCBlock tbd_nodeptr
 
        PROCEDURE
              g17hexto_line;
 
              tsp00_Line tsp00_C40
 
        PROCEDURE
              g17nameto_line;
 
              tsp00_Line tsp00_C40
 
        PROCEDURE
              g17trimint4_to_line;
 
              tsp00_Line tsp_c40
 
        PROCEDURE
              g17basis_err_to_line;
 
              tsp00_Line tsp00_C40
 
        PROCEDURE
              s30cmp;
 
              tsp00_MoveObj tsp00_Buf
 
        PROCEDURE
              t01buf;
 
              tsp00_Buf tgg00_Rec
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : JuergenP
.sp
.cp 3
Created : 1979-11-09
.sp
.cp 3
.sp
.cp 3
Release :      Date : 2000-10-04
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
 
Every (nonempty) file of the base file system is managed via
a B* tree.  B* trees are special storage and access structures
for the index sequential organization of dynamically changeable
files.  They feature
.sp ;.of 2
- rapid access during optional and sequential processing,
.sp ;.in ;.of 2
- efficient utilization of the secondary storage area and
.sp ;.in ;.of 2
- dynamic reorganization of the storage and access structure.
.sp ;.in
For the file management system described here, a B* tree variant is
used that is specially suited to managing files with the
following characteristics:
.sp
.of 2
- the length of file entries and entry keys can vary within
very wide margins
.sp ;.in ;.of 2
- the files change frequently (insertion, replacement and
deletion of records).
.sp 2;.cp 4
.in
In an indexed sequential file that is organized via a B* tree, the
data entries and the index are accomodated in blocks of a fixed
length, called pages or page frames.  The pages form the units that
are transferred between the main memory and the secondary storage.
At the same time, these units form the nodes of a tree structure.
The way in which this tree is dynamically structured and reorganized
is successively described in a series of modules, with each
module solving individual problem aspects.
The following is intended merely to provide a terminological framework
for the specification of the routines concerned.
.sp 2
A
.oc _/1;B* tree
B is a finite set whose elements are called
.oc _/1;nodes.
It is either empty (
.oc _/1;empty_tree
) or it contains a designated node W, known as the
.oc _/1;root,
and the remaining nodes (B(W)) are subdivided into
g(W) >= 0
.oc _/1;subtrees;
each subtree is itself a B* tree.
Under certain circumstances, the entire B* tree can also be referred
to as a subtree.  The subtrees can be graphically depicted as branches
from the root; g(W) is therefore called the
.oc _/1;branching_degree
of the node W.
The nodes of a B* tree have a variable branching degree!
.sp
A root is referred to as a
.oc _/1;parent_node
with relation to the roots of its subtrees and, inversely, the
subtree nodes are the
.oc _/1;offspring_nodes
of the parent node.
The offspring nodes of a root are always ordered;
nodes that directly follow one another are called
.oc _/1;neighbor nodes,
as are the last and first offspring of two adjacent
parent nodes.
In this case, the preceeding node in the sequence
(or last offspring node) is the
.oc _/1;left_neighbor_node
and the suceeding node (or first offspring node) is the
.oc _/1;right_neighbor_node.
.sp
A node is a
.oc _/1;leaf
if it has a branching degree of zero; otherwise it is a
.oc _/1;branch_node.
B* trees are characterized by the fact that each node that is
neighbor to a leaf is also a leaf.
This means that each node can be assigned a
.oc _/1;level_number
according to the following principle:
neighbor nodes have the same level number,
parent nodes have a level number that is one greater
than that of their offspring nodes and all leaves have the same
level number of zero.
.sp
Since each node is implemented via a page in the secondary
storage (see pagestore), the nodes are unambiguously identified by
.oc _/1;page_numbers
and B* trees are identified by the page numbers of their roots.
Unless otherwise indicated, the routines always process the
.oc _/1;current_B*_tree,
as determined by the last call of the routine b30adjust_tree
since the last system startup (or since system generation).
.sp 3;.cp 7
   b30new_tree(fi,current,e)
.sp
This routine generates a new B* tree for a file with
file information fi.
The new B* tree consists only of a root, whose page number
is entered in fi.root.
'current' contains additional information on the tree.
Some possible acknowledgements in e:
   - e_ok
   - b_no_more_space
   - b_disk_not_accessible
.sp 2;.cp 7
   b30adjust_tree (fi,t,current)
.sp
The file with file information fi becomes the current
B* tree.  File-specific information is made available in 'current'
by calling b30adjust_tree.
.sp 2;.cp 7
   bd30DropTree(current,stringcol_cnt,only_empty,e)
.sp
This routine re-releases all pages being used by the current
B* tree (current contains the necessary information).
.br
However, if 'only_empty' is assigned, the root of the tree is not
released but instead is re-initialized.
In this way, the contents of a file can be deleted without
the file having to be removed from the database.
.br
Otherwise ('only_empty' = FALSE), in order to ensure that no other
process with an invalid tree_id can access this tree, the root,
before it is released, is written to the secondary storage with a
deleted treeroot entry in the header. The parameter stringcol_cnt
contains the number of string fields in the RECORD representation
that belongs to this tree.  The B* trees that are referred to in
these fields are also deleted.
.br
Some possible acknowledgements in e:
   - e_ok
   - b_invalid_index_structure
   - b_invalid_leaves_structure
   - b_disk_not_accessible
.sp 2;.cp 7
   bd30VerifyTree (current,e)
.sp
The tree identified by 'current' is verified, i.e. the entire tree
is traversed and every node in the tree is labelled as used
in the previously deleted free storage manager.  In this manner,
pages that do not belong to any tree but were labelled as used
are again released.
.br
Some possible acknowledgements in e:
   - e_ok
   - b_invalid_index_structure
   - b_invalid_leaves_structure
   - b_disk_not_accessible
.sp 2;.cp 7
   current
.sp
The following is some of the information on the current B* tree
that is held in this variable:
.sp ;.of 2
- the page number 'root' of the root of the tree,
.br ;.in ;.of 2
- the file type ft that manages the tree,
(see filesysteminterface)
.br ;.in ;.of 2
- the buffer type bt, depending on whether a temporary file, the
system file or another permanent file is involved (see
systembufferinterface).
.sp 2;.cp 7
   indexorderlist
.sp
In this list, information is managed for a possible index
update or an index reorganization.
(see VBD54, indexupdateorders !).
.sp ;.in
.sp 3;.cp 6
.oc _/1
Operations_Involving_Trees_that_Manage_Primary_Files
.sp 2
Primary file entries are records with unambiguous record keys.
The way in which records and keys are transferred to a record or
key buffer is described in bufferhandling.
.sp 2;.cp 4
   bd30AddFileState (current, new_filestate)
.sp
.sp 2;.cp 4
   b30add_to_tree (rk, b, page_fill_limit, current)
.sp
Inserts in the current B* tree the record contained in the record
buffer b with the key rk, if no record with this key is already
present and if enough space is available. If a page is written to the secondary
storage during a tree operation, all log pages whose page numbers
are lower than or the same as that of the current log page are also
written to the secondary storage, making the change restart-capable.
In addition, the current log information must be entered in the
data cache when the page to be changed is allocated so that,
if this page is ever displaced from the data cache, the writing
of the log pages with lower or identical page numbers to the
secondary storage can be initiated.
.br
The set bd_use_info indicates whether act_logpos must be used
- bd_valid_logpos - and whether the pages are written through to
the secondary storage unbuffered - bd_unbuffered -.  In the case
of a temporary file, this set is always empty.
.br
Some possible acknowledgements in e:
   - e_ok
   - b_duplicate_key
   - b_no_more_space
   - b_no_more_temp_space
   - b_illegal_entrypos
   - b_invalid_entrypos
   - b_invalid_index_structure
   - b_invalid_leaves_structure
   - b_disk_not_accessible
.sp 2;.cp 4
   b30cappend_to_tree (rk, b, tree_pos, current)
.sp 2;.cp 4
   b30cnext_from_tree(rk,set_result,tree_pos,b,current,e)
.sp
Copies cnt records from the current B* tree that follow the record
with key rk (with the records arranged in ascending order by
keys).  If no record with a key greater than rk is contained in
the tree, 'b_no_next_record' is sent to e and cnt is set to
zero.  Otherwise, as many (complete) records are transferred
to buffer b as it can receive or they are transferred for as long as
records with greater keys are still present.  When it has been
determined that no other record is present, b_no_next_record
is sent to e.
.br
Some possible acknowledgements in e:
   - e_ok
   - b_buffer_limit
   - b_no_next_record
   - b_illegal_entrypos
   - b_invalid_entrypos
   - b_invalid_index_structure
   - b_invalid_leaves_structure
   - b_disk_not_accessible
.sp 2;.cp 4
  b30cprev_from_tree (rk, set_result, tree_pos, b, current)
.sp
Copies cnt records from the current B* tree that preceed the record
with key rk (with the records arranged in descending order by
keys).  If no record with a key smaller than rk is contained in
the tree, 'b_no_prev_record' is sent to e and cnt is set to
zero.  Otherwise, as many (complete) records are transferred
to buffer b as it can receive or they are transferred for as long as
records with smaller keys are still present.  When it has been
determined that no other record is present, b_no_prev_record
is sent to e.
.br
Some possible acknowledgements in e:
   - e_ok
   - b_buffer_limitn
   - b_no_prev_record
   - b_illegal_entrypos
   - b_invalid_entrypos
   - b_invalid_index_structure
   - b_invalid_leaves_structure
   - b_disk_not_accesible
.sp 2;.cp 4
   b30del_from_tree (rk, current)
.sp
Deletes the record with the key rk from the current B* tree,
if such a record is present.
.br
.sp 2;.cp 4
   bd30ExistRecord(rk,current)
.sp
Carries out a search for a record with the key rk in
the current B* tree.
.br
Some possible acknowledgements in e:
   - e_ok
   - b_key_not_found
   - b_illegal_entrypos
   - b_invalid_entrypos
   - b_invalid_index_structure
   - b_invalid_leaves_structure
   - b_disk_not_accessible
????????????????????????
   - e_no_next_record
   - e_no_prev_record
   - b_file_not_found
.sp 2;.cp 4
   b30fdir_to_treeid (fi, file_id)
.sp 2;.cp 4
   bd30GetFromTree (rk, b, current, wanted_mode)
.sp
Copies the record with the key rk, if such a record is present,
from the current B* tree to the record buffer b.
.br
Some possible acknowledgements in e:
   - e_ok
   - b_key_not_found
   - b_illegal_entrypos
   - b_invalid_entrypos
   - b_invalid_index_structure
   - b_invalid_leaves_structure
   - b_disk_not_accessible
.sp 2;.cp 4
  b30init_load (rightmost_leaf, current)
.sp 2;.cp 4
  bd30CreateBeforeImageForDelete
       (m, rk, old_recbuf, granted_lock, current)
 
.sp 2;.cp 4
  bd30CreateBeforeImageForInsert
        (rk, b, m, granted_lock, page_fill_limit, current)
.sp
.sp 2;.cp 4
  bd30CreateBeforeImageForUpdate (m, rk, old_recbuf, new_recbuf,
        granted_lock, current)
.sp
.sp 2;.cp 4
  b30load_table (lnptr, nptr, tbd_node_ptrs, only_left,
        sep, indexorderlist, tbd_order_list current)
.sp
.sp 2;.cp 4
  b30new_tree (fi, current);
.sp
.sp 2;.cp 4
   bd30NextFromTree (rk, inclusive, tree_pos, b, current)
.sp
If the parameter is set to 'inclusive' and the record
with record key rk is found, this record is copied to record buffer b.
.br
Otherwise, the record that follows the record with key rk (with
the records arranged in ascending order by keys) is copied to b.
If no record with a key greater than rk is contained in the tree,
b_no_next_record is sent to e.  If the record with key rk is not
present, b_key_not_found is sent to e but the record is retrieved
that would have followed rk if it had been present.
.br
Some possible acknowledgements in e:
   - e_ok
   - b_key_not_found
   - b_no_next_record
   - b_illegal_entrypos
   - b_invalid_entrypos
   - b_invalid_index_structure
   - b_invalid_leaves_structure
   - b_disk_not_accessible
.sp 2;.cp 4
  bd30PrevFromTree(rk,inclusive,tree_pos,b,current,e)
.sp
If the parameter is set to 'inclusive' and the record
with the record key rk is found, this record is copied to the
record buffer b.
.br
Otherwise, the record that preceeds the record with key rk (with
the records arranged in descending order by keys) is copied to b.
If no record with a key smaller than rk is contained in the tree,
b_no_prev_record is sent to e.  If the record with key rk is not
present, b_key_not_found is sent to e but the record is retrieved
that would have preceeded rk if it had been present.
.br
Some possible acknowledgements in e:
   - e_ok
   - b_key_not_found
   - b_no_prev_record
   - b_illegal_entrypos
   - b_invalid_entrypos
   - b_invalid_index_structure
   - b_invalid_leaves_structure
   - b_disk_not_accesible
.sp 3;.cp 7
   b30repl_in_tree(rk,b,bd_use_info, current,e)
.sp
Replaces the record with the key rk in the current B* tree, if
such a record is present, with the new record contained in the
record buffer b.  The new record must also have the record key rk
and, if it is longer than the old record, will be substituted only
if sufficient space is available.
.br
Some possible acknowledgements in e:
   - e_ok
   - b_key_not_found
   - b_no_more_space
   - b_no_more_temp_space
   - b_illegal_entrypos
   - b_invalid_entrypos
   - b_invalid_index_structure
   - b_invalid_leaves_structure
   - b_disk_not_accessible
.fo
.CM *-END-* specification -------------------------------
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
 
The branch nodes of a B* tree form its
.oc _/1;B*_index
and the leaves form its
.oc _/1;B*_file.
For the management of a primary file, the records are stored
in the B* file, whereas the B* index represents a generally
multilevel index for the B* file.
.sp
For each primary file record, the B* file contains a record
entry that begins in a specific leaf (n) in a specific
position (pos).  This position can be accessed via an index
(pointer_list) that is located at the end of each leaf.  The
sorting of record entries is defined by the index.  Normally,
the record is inserted by appending it to the existing records
and maintaining the index.  This means that the sorting of all
the record entries in a leaf only becomes necessary if the leaf
takes part in a tree balancing operation.
The position of a record
entry is not fixed but changes along with the dynamic setup and
dismantling of the tree.
.sp
.cp 17
.nf
                      Structure of a node
                      ===================
 
            +-------<---------<---------+
            |    +--------<--------<----|---+
            |    |                      |   |
            |    |                      |   |
+---+------+|---+|-----+----+----+----+-|-+-|-+---+---+---+-+
|   |  s1  | s5 |  s4  | s2 | s3 |    |P5 |P4 |P3 |P2 |P1 | |
+-|-+|-----+----+------+|---+|---+----+---+---+-|-+-|-+-|-+-+
  |  |                  |    |                  |   |   |
  |  |                  |    |                  |   |   |
  |  |                  |    +----------<-------+   |   |
  |  |                  +----------<----------<-----+   |
  |  +-------<-------------<-------------<--------------+
  |
  +--> header
.fo
.sp2
The function of the B* index is to provide quick access to a
record entry with a preset key (bd50FindLeaf).
.br
In order to support the sequential processing (bd30NextFromTree),
each leaf has a pointer to its right neighbor leaf
(see nodehandling) and an additional
.oc _/1;short-term_memory
(see keymemory) is maintained.
.sp
Each time a record entry is found and transferred to a
record buffer (get/next_from_tree), the 'address' of the record
entry is recorded in the memory.  The routines that process the
leaves are responsible for ensuring that the memory is not rendered
inconsistent by the insertion, deletion or replacement of record
entries.  When a search for a record entry is being carried out
first of all an attempt is made to find the
page number of the 'leaf' and, if possible, even the position
(pos, when dirty = FALSE) of the record entry via the short-term
memory.  If no corresponding entry is found in the memory, a
descent via the index occurs (bd50FindLeaf).  The position
within a leaf is found via b31search_entry and 'result'
delivers one of the following acknowledgements:
.sp ;.of 2
- nonefound, if no record entry begins in that leaf,
.br ;.in ;.of 2
- thisfound, if the record entry being searched for was found,
.br ;.in ;.of 2
- nextfound, if the record entry being searched for does not begin
in that leaf and the next record entry was found,
.br ;.in ;.of 2
- lastfound, if the last record entry beginning in the leaf was
found and has a key that is smaller than that of the record
for which the search was run.
.sp ;.in
Changes in the leaves may result in the need for minor
modifications to the B* index.  These modifications are
executed with b54execute_indexorder
at the end.  For a more detailed description, see
indexupdateorders.
.sp
When an entire B* tree is deleted (bd30DropTree), all
nodes are recursively deleted.  If the tree is made up of a
single node only (single), it is handled separately since this is
often the case with temporary files and should then take place very
quickly, whereas the large, permanent files are seldom deleted
and are also likely to require more time.
.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    :
 
 
TYPE
 
      int4_map_c4  = RECORD
            CASE boolean OF
                true  :
                    (map_c4 : tsp00_C4);
                false :
                    (map_i4 : tsp00_Int4)
                END;
            (*ENDCASE*) 
 
 
      tbd30_SendQualPart = RECORD
            sqp_FileId_bd30     : tgg00_FileId;
            sqp_WithUpdate_bd30 : boolean;
            sqp_Extended_bd30   : boolean;
            sqp_Filler1_bd30    : tsp00_Int2;
      END;
 
 
CONST
      MSG_WRONG_LEVEL     = 'Tree level is not 1     ';
      MSG_1_WRONG_LEVEL   = 'Tree level is <= 1      ';
      MSG_1_DROP          = 'Error during drop file  ';
      MSG_RELEASE_MISSING = 'Release page missing    ';
      MSG_2_DROP          = 'CHECK DATA WITH UPDATE may be needed    ';
      (* *)
      c_include_strcols = true;
      (* *)
      c_max_retries     = 10;
      (* *)
      MSG_START_CHECK_TABLE1 = 'Start check tables and indexes          ';
      MSG_START_CHECK_TABLE2 = 'Start check tables only                 ';
      MSG_START_CHECK_BLOB   = 'Start check blobs                       ';
      MSG_FDIR_CORRUPTED     = 'File Directory corrupted                ';
 
 
(*------------------------------*) 
 
PROCEDURE
      b30cappend_to_tree (
            VAR rk       : tgg00_Lkey;
            VAR b        : tgg00_Rec;
            VAR tree_pos : tgg00_FilePos;
            VAR current  : tbd_current_tree);
 
VAR
      searchResult : tbd_searchresult;
      recIndex     : tsp00_Int4;
      nptr         : tbd_node_ptrs;
      neighbs      : tbd_neighbors;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    nptr.np_ptr   := NIL;
    nptr.np_cbptr := NIL;
    IF  tree_pos.tpsPno_gg00 <> NIL_PAGE_NO_GG00
    THEN
        bd13GetNode (current, tree_pos.tpsPno_gg00, plmLock_ebd00, nr_for_update, nptr)
    ELSE
        BEGIN
        bd30SearchRecord (current, rk.keyVal_gg00, rk.keyLen_gg00,
              nptr, recIndex, neighbs, searchResult);
        IF  trError_gg00 = e_ok
        THEN
            IF  searchResult = thisfound
            THEN
                trError_gg00 := e_duplicate_key
            ELSE
                IF  (searchResult = nextfound) OR
                    (nptr.np_ptr^.nd_right <> NIL_PAGE_NO_GG00)
                THEN
                    trError_gg00 := e_append_not_allowed
                ELSE
                    BEGIN
                    tree_pos.tpsPno_gg00 := nptr.np_ptr^.nd_id;
                    IF  searchResult = nonefound
                    THEN
                        tree_pos.tpsIndex_gg00 := recIndex - 1
                    ELSE
                        tree_pos.tpsIndex_gg00 := recIndex
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
            (*ENDIF*) 
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        b31t_append_to_temp_leaf (b, nptr, tree_pos, current);
    (*ENDIF*) 
    IF  (trError_gg00 <> e_ok) AND (nptr.np_ptr <> NIL)
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b30cget_result_leaf (
            VAR rk          : tgg00_Lkey;
            get_next        : boolean;
            prepare_for_upd : boolean;
            VAR tree_pos    : tgg00_FilePos;
            VAR nptr        : tbd_node_ptrs;
            VAR current     : tbd_current_tree);
 
VAR
      searchResult     : tbd_searchresult;
      node_req        : tbd_node_request;
      recIndex        : tsp00_Int4;
      right_neighbor  : tsp00_PageNo;
      neighbs         : tbd_neighbors;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    IF  prepare_for_upd
    THEN
        node_req := nr_for_update
    ELSE
        node_req := nr_for_read;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        BEGIN
        IF  get_next
        THEN
            right_neighbor := nptr.np_ptr^.nd_right
        ELSE
            right_neighbor := tree_pos.tpsPno_gg00;
        (*ENDIF*) 
        IF  prepare_for_upd
        THEN
            b13w_release_node (nptr, current)
        ELSE
            b13r_release_node (nptr, current, lru_normal)
        (*ENDIF*) 
        END
    ELSE
        IF  get_next
        THEN
            right_neighbor := NIL_PAGE_NO_GG00
        ELSE
            right_neighbor := tree_pos.tpsPno_gg00;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  tree_pos.tpsPno_gg00 = NIL_PAGE_NO_GG00
    THEN
        BEGIN
        bd30SearchRecord (current, rk.keyVal_gg00, rk.keyLen_gg00,
              nptr, recIndex, neighbs, searchResult);
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            IF  searchResult = nonefound
            THEN
                trError_gg00 := e_no_next_record
            ELSE
                IF  (searchResult = lastfound) OR (searchResult = thisfound)
                THEN
                    IF  prepare_for_upd
                    THEN
                        b31w_next_search (nptr, recIndex, current)
                    ELSE
                        b31next_search (nptr, recIndex, current);
                    (*ENDIF*) 
                (*might return b_no_next_record*)
                (*ENDIF*) 
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                tree_pos.tpsPno_gg00   := nptr.np_ptr^.nd_id;
                tree_pos.tpsIndex_gg00 := recIndex
                END
            ELSE
                tree_pos.tpsPno_gg00 := NIL_PAGE_NO_GG00
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        IF  right_neighbor <> NIL_PAGE_NO_GG00
        THEN
            BEGIN
            bd13GetNode (current, right_neighbor, plmLock_ebd00, node_req, nptr);
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                tree_pos.tpsPno_gg00   := nptr.np_ptr^.nd_id;
                tree_pos.tpsIndex_gg00 := FIRST_REC_INDEX_BD00
                END
            (*ENDIF*) 
            END
        ELSE
            BEGIN
            trError_gg00         := e_no_next_record;
            tree_pos.tpsPno_gg00 := NIL_PAGE_NO_GG00
            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;
 
(*------------------------------*) 
 
PROCEDURE
      b30cnext_from_tree (
            VAR rk         : tgg00_Lkey;
            VAR set_result : tgg00_BdSetResultRecord;
            VAR tree_pos   : tgg00_FilePos;
            VAR b          : tsp00_MoveObj;
            VAR current    : tbd_current_tree);
 
VAR
      searchResult : tbd_searchresult;
      recIndex     : tsp00_Int4;
      nptr         : tbd_node_ptrs;
      neighbs      : tbd_neighbors;
 
BEGIN
WITH current, curr_trans^  DO
    BEGIN
    nptr.np_ptr   := NIL;
    nptr.np_cbptr := NIL;
    IF  tree_pos.tpsPno_gg00 = NIL_PAGE_NO_GG00
    THEN
        BEGIN
        bd30SearchRecord (current, rk.keyVal_gg00, rk.keyLen_gg00,
              nptr, recIndex, neighbs, searchResult);
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            IF  searchResult = nonefound
            THEN
                trError_gg00 := e_no_next_record
            ELSE
                IF  (searchResult = lastfound) OR
                    ((searchResult = thisfound) AND set_result.bd_next)
                THEN
                    b31next_search (nptr, recIndex, current);
                (*might return b_no_next_record*)
                (*ENDIF*) 
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                tree_pos.tpsPno_gg00   := nptr.np_ptr^.nd_id;
                tree_pos.tpsIndex_gg00 := recIndex
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        IF  tree_pos.tpsIndex_gg00 = NIL_RECINDEX_BD00
        THEN
            trError_gg00 := e_no_next_record
        ELSE
            BEGIN
            searchResult := thisfound;
            bd13GetNode (current, tree_pos.tpsPno_gg00, plmLock_ebd00, nr_for_read, nptr);
            IF  set_result.bd_next AND (trError_gg00 = e_ok)
            THEN
                BEGIN
                recIndex := tree_pos.tpsIndex_gg00;
                b31next_search (nptr, recIndex, current);
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    tree_pos.tpsPno_gg00   := nptr.np_ptr^.nd_id;
                    tree_pos.tpsIndex_gg00 := recIndex
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        b31nfill_recordbuffer (nptr, rk, tree_pos, set_result, b, current);
    (*ENDIF*) 
    IF  (trError_gg00 = e_ok) AND (searchResult <> thisfound)
    THEN
        trError_gg00 := e_key_not_found;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b30cprev_from_tree (
            VAR rk         : tgg00_Lkey;
            VAR set_result : tgg00_BdSetResultRecord;
            VAR tree_pos   : tgg00_FilePos;
            VAR b          : tsp00_MoveObj;
            VAR current    : tbd_current_tree);
 
VAR
      searchResult : tbd_searchresult;
      recIndex     : tsp00_Int4;
      nptr         : tbd_node_ptrs;
      neighbs      : tbd_neighbors;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    nptr.np_ptr   := NIL;
    nptr.np_cbptr := NIL;
    IF  tree_pos.tpsPno_gg00 = NIL_PAGE_NO_GG00
    THEN
        BEGIN
        bd30SearchRecord (current, rk.keyVal_gg00, rk.keyLen_gg00,
              nptr, recIndex, neighbs, searchResult);
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            IF  searchResult = nonefound
            THEN
                trError_gg00 := e_no_prev_record
            ELSE
                IF  (searchResult = nextfound) OR
                    ((searchResult = thisfound) AND set_result.bd_next)
                THEN
                    b31t_prev_temp_search (nptr, recIndex, current);
                (*ENDIF*) 
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                tree_pos.tpsPno_gg00   := nptr.np_ptr^.nd_id;
                tree_pos.tpsIndex_gg00 := recIndex
                END;
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        IF  tree_pos.tpsIndex_gg00 = NIL_RECINDEX_BD00
        THEN
            trError_gg00 := e_no_prev_record
        ELSE
            BEGIN
            searchResult := thisfound;
            bd13GetNode (current, tree_pos.tpsPno_gg00, plmLock_ebd00, nr_for_read, nptr);
            IF  set_result.bd_next AND (trError_gg00 = e_ok)
            THEN
                BEGIN
                recIndex := tree_pos.tpsIndex_gg00;
                b31t_prev_temp_search (nptr, recIndex, current);
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    tree_pos.tpsPno_gg00   := nptr.np_ptr^.nd_id;
                    tree_pos.tpsIndex_gg00 := recIndex
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        b31pfill_recordbuffer (nptr, rk, tree_pos, set_result, b, current);
    (*ENDIF*) 
    IF   (trError_gg00 = e_ok) AND (searchResult <> thisfound)
    THEN
        trError_gg00 := e_key_not_found;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b30database_verify (
            VAR t              : tgg00_TransContext;
            VAR bad_index_cnt  : tsp00_Int4;
            VAR total_bad_cnt  : tsp00_Int4;
            VAR verify_error   : tgg00_BasisError;
            bWithUpdate        : boolean;
            bWithExtendedCheck : boolean;
            bWithIndexes       : boolean;
            max_server         : integer);
 
VAR
      finish           : boolean;
      handle_error     : boolean;
      startBlobVerify  : boolean;
      bSearchNext      : boolean;
      retry_cnt        : integer;
      send_cnt         : integer;
      ErrorRoot        : tsp00_PageNo;
      fi               : tbd_fileinfo;
      file_id          : tgg00_FileId;
 
BEGIN
finish          := false;
handle_error    := false;
startBlobVerify := false;
bSearchNext     := false;
retry_cnt       := 0;
send_cnt        := 0;
ErrorRoot       := NIL_PAGE_NO_GG00;
file_id         := b01niltree_id;
IF  bWithUpdate
THEN
    bWithIndexes := true;
(*ENDIF*) 
WITH t DO
    BEGIN
    IF  bWithIndexes
    THEN
        g01optextmsg (sp3p_knldiag, sp3m_info, csp3_bd_msg,
              csp3_n_check, MSG_START_CHECK_TABLE1)
    ELSE
        g01optextmsg (sp3p_knldiag, sp3m_info, csp3_bd_msg,
              csp3_n_check, MSG_START_CHECK_TABLE2);
    (*ENDIF*) 
    WHILE (
          (trError_gg00 = e_ok) AND
          (NOT finish         )
          )
          OR
          (
          (trError_gg00 = e_too_many_net_requests) AND
          (retry_cnt < c_max_retries             )
          )
          DO
        BEGIN
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            REPEAT
                b17succ_fdir (file_id.fileName_gg00, file_id.fileName_gg00, fi,
                      ftsShared_egg00 IN file_id.fileType_gg00, t, c_include_strcols);
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    IF  (f_not_accessible IN fi.fi_state)
                    THEN
                        BEGIN
                        trError_gg00 := e_file_not_accessible;
                        ErrorRoot    := fi.fi_root;
                        handle_error := true;
                        END;
                    (*ENDIF*) 
                    b30fdir_to_treeid (fi, file_id);
                    IF  (NOT startBlobVerify AND (ftsByteStr_egg00 IN file_id.fileType_gg00))
                    THEN
                        BEGIN
                        startBlobVerify := true;
                        g01optextmsg (sp3p_knldiag, sp3m_info, csp3_bd_msg,
                              csp3_n_check, MSG_START_CHECK_BLOB)
                        END;
                    (*ENDIF*) 
                    bSearchNext := (fi.fi_root = NIL_PAGE_NO_GG00) OR
                          ((NOT bWithIndexes) AND (g04inv_tfn (file_id.fileTfn_gg00))) OR
                          ( ftsArchive_egg00 IN file_id.fileType_gg00 )
                    END;
                (*ENDIF*) 
            UNTIL
                (trError_gg00 <> e_ok) OR (NOT bSearchNext);
            (*ENDREPEAT*) 
            IF  trError_gg00 = e_file_not_found
            THEN
                BEGIN
                finish       := true;
                trError_gg00 := e_ok
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  (
            (trError_gg00 = e_ok                   ) OR
            (trError_gg00 = e_too_many_net_requests)
            )
            AND
            (NOT finish                    )
        THEN
            bd30_SendFileId (t, file_id, retry_cnt, send_cnt, m_verify,
                  bWithUpdate, bWithExtendedCheck);
        (*ENDIF*) 
        IF  ((trError_gg00 = e_ok) AND (send_cnt = max_server))
            OR
            ((finish) AND (send_cnt > 0))
            OR
            ((trError_gg00 = e_too_many_net_requests) AND (send_cnt > 0))
        THEN
            BEGIN
            bd30wait_for_reply (t, send_cnt, ErrorRoot, max_server, finish);
            handle_error := (trError_gg00 <> e_ok)
            END;
        (*ENDIF*) 
        IF  (NOT finish                      )
            AND
            (
            (trError_gg00 = e_too_many_net_requests) AND
            (send_cnt = 0                          ) AND
            (retry_cnt >= c_max_retries            )
            )
        THEN
            BEGIN
            (* no server available *)
            trError_gg00 := e_ok;
            retry_cnt    := 0;
            b01pverify_participant (t, file_id, bWithUpdate, bWithExtendedCheck);
            (* PTS 1105359 TS 2000-01-17 *)
            IF   (trError_gg00 <> e_ok)
            THEN
                BEGIN
                handle_error := true;
                ErrorRoot    := file_id.fileRoot_gg00;
                END
            ELSE
                handle_error := false;
            (*ENDIF*) 
            (* PTS 1105359 *)
            END;
        (*ENDIF*) 
        IF  (handle_error                           ) AND
            (trError_gg00 <> e_too_many_net_requests) AND
            (trError_gg00 <> e_shutdown             ) AND
            (trError_gg00 <> e_disk_not_accessible  ) AND
            (trError_gg00 <> e_cancelled            )
        THEN
            BEGIN
            handle_error  := false;
            total_bad_cnt := succ (total_bad_cnt);
            IF  trError_gg00 = e_file_not_accessible
            THEN
                bad_index_cnt := succ (bad_index_cnt)
            ELSE
                IF  verify_error = e_ok
                THEN
                    verify_error := trError_gg00;
                (* PTS 1105359 TS 2000-01-17 *)
                (*ENDIF*) 
            (*ENDIF*) 
            bd30_PnoCheckOpmsg (ErrorRoot, trError_gg00);
            (* PTS 1105359 *)
            (* *)
            trError_gg00 := e_ok;
            END;
        (*ENDIF*) 
        IF  (trError_gg00 = e_ok) AND (trRteCommPtr_gg00^.to_cancel)
        THEN
            trError_gg00 := e_cancelled
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    IF  trError_gg00 <> e_ok
    THEN
        bd30discard_task (t, send_cnt);
    (*ENDIF*) 
    IF  (finish) AND (trError_gg00 = e_ok)
    THEN
        trError_gg00 := e_file_not_found
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b30fdir_to_treeid (VAR fi : tbd_fileinfo;
            VAR file_id : tgg00_FileId);
 
BEGIN
WITH file_id DO
    BEGIN
    fileRoot_gg00 := fi.fi_root;
    fileType_gg00 := fi.fi_type;
    IF  fileRoot_gg00 = NIL_PAGE_NO_GG00
    THEN
        fileRootCheck_gg00 := ROOT_CHECK_GG00
    ELSE
        bd300SetRootCheck (file_id);
    (*ENDIF*) 
&   ifdef trace
    t01int4 (bi, '30n_root_che', fileRootCheck_gg00);
&   endif
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b30init_load (VAR rightmost_leaf : tsp00_PageNo;
            VAR current : tbd_current_tree);
 
VAR
      recIndexForLeaf : tsp00_Int4;
      nptr            : tbd_node_ptrs;
      neighbs         : tbd_neighbors;
      fullkey         : tgg00_Lkey;
 
BEGIN
nptr.np_ptr         := NIL;
nptr.np_cbptr       := NIL;
rightmost_leaf      := NIL_PAGE_NO_GG00;
fullkey.keyLen_gg00 := MAX_KEYLEN_GG00;
fullkey.keyVal_gg00 := b01fullkey;
bd50FindLeaf (fullkey.keyVal_gg00, fullkey.keyLen_gg00,
      nptr, neighbs, recIndexForLeaf, current);
IF  current.curr_trans^.trError_gg00 = e_ok
THEN
    BEGIN
    rightmost_leaf := nptr.np_ptr^.nd_id;
    b13r_release_node (nptr, current, lru_normal)
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b30load_table (VAR lnptr : tbd_node_ptrs;
            VAR nptr           : tbd_node_ptrs;
            only_left          : boolean;
            VAR current        : tbd_current_tree);
 
VAR
      rightmost_leaf : tsp00_PageNo;
      sep            : tgg00_Lkey;
      indexorderlist : tbd00_OrderList;
      save_bottom    : tgg00_PagePos;
      save_list_top  : tsp00_Int4;
 
BEGIN
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    (* only one page is given via sql packet *)
    IF  only_left
    THEN
        lnptr.np_ptr^.nd_right := NIL_PAGE_NO_GG00
    ELSE
        BEGIN
        curr_lvl_1_pno := NIL_PAGE_NO_GG00;
        indexorderlist.olstCount_bd00 := 0;
        WITH nptr.np_ptr^ DO
            BEGIN
            (* h.b. 19.02.99                          *)
            (* changed initialisation for FASTLOAD:   *)
            (* list_top and bottom are already filled *)
            (* by FASTLOAD                            *)
            save_bottom      := nd_bottom;
            save_list_top    := nd_record_cnt;
            b13init_default_data_page (curr_tree_id, LEAF_LEVEL_BD00, nd_id, nptr);
            nd_bottom        := save_bottom;
            nd_record_cnt    := save_list_top;
            IF  ftsTemp_egg00 in fileType_gg00
            THEN
                nd_left  := lnptr.np_ptr^.nd_id;
            (*ENDIF*) 
            IF  (nd_id = fileRoot_gg00)
            THEN
                nd_file_version := fileVersion_gg00;
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
        lnptr.np_ptr^.nd_right := nptr.np_ptr^.nd_id;
        sep.keyLen_gg00 := 0; (* sep.lksep.len := 0; *)
        bd53NewLeafIndex (lnptr.np_ptr, nptr.np_ptr, sep, curr_trans);
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            b54add_index (@sep.keyVal_gg00, sep.keyLen_gg00, nptr.np_ptr^.nd_id,
                  LEAF_LEVEL_BD00, indexorderlist);
            b13w_release_node (lnptr, current);
            (* *)
            (* PTS XXXX TS 2000-12-27 *)
            (* release pages to avoid illegal request in data cache *)
            rightmost_leaf := nptr.np_ptr^.nd_id;
            b13w_release_node (nptr, current);
            (* *)
            b54execute_indexorder (indexorderlist, current);
            IF  trError_gg00 = e_ok
            THEN
                bd13GetNode (current, rightmost_leaf, plmLock_ebd00, nr_for_update, lnptr);
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b30new_tree (VAR fi : tbd_fileinfo;
            VAR current   : tbd_current_tree);
 
VAR
      nptr : tbd_node_ptrs;
 
BEGIN
WITH current, curr_tree_id, curr_trans^, nptr DO
    BEGIN
    np_ptr   := NIL;
    np_cbptr := NIL;
    b13new_root (nptr, current);
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        fi.fi_root    := np_ptr^.nd_id;
        fileRoot_gg00 := np_ptr^.nd_id;
        IF  (fileTabId_gg00 = cgg_sys1_catalog_id) OR
            (fileTabId_gg00 = cgg_sys2_catalog_id)
        THEN
            BEGIN
            np_ptr^.nd_pmode   := np_ptr^.nd_pmode + [pmCatalog_egg00];
            np_ptr^.nd_trailer := np_ptr^.nd_header
            END;
        (*ENDIF*) 
        np_ptr^.nd_file_state := fi.fi_state;
        bd300SetRootCheck (curr_tree_id);
        b13w_release_node (nptr, current)
        END;
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30AddFileState (
            VAR current : tbd_current_tree;
            fileState   : tbd_file_state_set);
 
BEGIN
WITH current, currRootNptrs_bd00.np_ptr^ DO
    BEGIN
    nd_file_state        := nd_file_state + fileState;
    currRootUpdated_bd00 := true;
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30AddToTempTree (
            bCountDuplicates : boolean;
            VAR rec          : tgg00_Rec;
            VAR current      : tbd_current_tree);
 
VAR
      searchResult    : tbd_searchresult;
      recIndex        : tsp00_Int4;
      duplicateCnt    : tsp00_Int4;
      pRec            : tgg00_RecPtr;
      nptr            : tbd_node_ptrs;
      neighbs         : tbd_neighbors;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    nptr.np_ptr   := NIL;
    nptr.np_cbptr := NIL;
&   ifdef TRACE
    IF  bCountDuplicates
    THEN
        t01key( bi, 'TempRecKey  ', rec.recKey_gg00);
&   endif
    (*ENDIF*) 
    bd30SearchRecord (current, rec.recKey_gg00.keyVal_gg00, rec.recKeyLen_gg00,
          nptr, recIndex, neighbs, searchResult);
    IF  trError_gg00 = e_ok
    THEN
        WITH neighbs DO
            CASE searchResult OF
                thisfound :
                    BEGIN
                    IF  bCountDuplicates
                    THEN
                        WITH nptr.np_ptr^ DO
                            BEGIN
                            pRec         := @nd_body [nd_pointer_list [MAX_POINTERINDEX_BD00 - recIndex]];
                            duplicateCnt := gg06PnoGet(pRec^.recPno_gg00);
                            IF  duplicateCnt < MAX_INT4_SP00 -1
                            THEN
                                BEGIN
                                gg06PnoPut( pRec^.recPno_gg00, duplicateCnt +1);
                                b13w_release_node (nptr, current);
                                END;
                            (*ENDIF*) 
                            END;
                        (*ENDWITH*) 
                    (*ENDIF*) 
                    trError_gg00 := e_duplicate_key;
                    END;
                nonefound :
                    b31add_to_leaf (rec, nptr, FIRST_REC_INDEX_BD00, ln, current);
                nextfound :
                    b31add_to_leaf (rec, nptr, recIndex, ln, current);
                lastfound :
                    b31append_to_leaf (rec, nptr, recIndex,
                          NINETY_PERCENT_COV_BD00, ln, current)
                END;
            (*ENDCASE*) 
        (*ENDWITH*) 
    (*ENDIF*) 
    IF  (trError_gg00 <> e_ok) AND (nptr.np_ptr <> NIL)
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30AddToTree (
            VAR recKey  : tgg00_Lkey;
            VAR rec     : tgg00_Rec;
            VAR current : tbd_current_tree);
 
VAR
      bDoLockHandling  : boolean;
      bReadyForInsert  : boolean;
      searchResult     : tbd_searchresult;
      maximumKeyLen    : tsp00_Int4;
      recIndex         : tsp00_Int4;
      recIndexForLeaf  : tsp00_Int4;
      leaf             : tsp00_PageNo;
      nptr             : tbd_node_ptrs;
      neighbs          : tbd_neighbors;
 
BEGIN
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    nptr.np_ptr     := NIL;
    nptr.np_cbptr   := NIL;
    bReadyForInsert := false;
    bDoLockHandling := ftsConcurrent_egg00 IN fileType_gg00;
    (* *)
    WHILE (trError_gg00 = e_ok) AND NOT bReadyForInsert DO
        BEGIN
        IF  nptr.np_ptr = NIL (* leaf node is not available *)
        THEN
            bd50FindLeaf (recKey.keyVal_gg00, recKey.keyLen_gg00,
                  nptr, neighbs, recIndexForLeaf, current);
        (*ENDIF*) 
        IF  trError_gg00 = e_ok
        THEN
            b31search_entry (current, recKey.keyVal_gg00, recKey.keyLen_gg00,
                  nptr.np_ptr, recIndex, searchResult);
        (*ENDIF*) 
        IF  (trError_gg00 = e_ok) AND (searchResult = thisfound)
        THEN
            trError_gg00 := e_duplicate_key;
        (*ENDIF*) 
        bReadyForInsert := NOT bDoLockHandling;
        IF  (trError_gg00 = e_ok) AND bDoLockHandling
        THEN
            BEGIN
            IF  (
                nptr.np_ptr^.nd_bottom + rec.recLen_gg00 <=
                MAX_BOTTOM_BD00 - ((nptr.np_ptr^.nd_record_cnt+1)*POINTERSIZE_BD00)
                )
                AND
                (
                (nptr.np_ptr^.nd_bottom < NINETY_PERCENT_COV_BD00) OR
                (searchResult <> lastfound                       ) OR
                (nptr.np_ptr^.nd_right <> NIL_PAGE_NO_GG00       )
                )
            THEN
                bReadyForInsert := true (* local update possible *)
            ELSE
                BEGIN
                bDoLockHandling := false;
                maximumKeyLen   := bd30_DetermineMaxKeyLength (nptr.np_ptr);
                b13r_release_node (nptr, current, lru_normal);
                IF  NOT bd50IndexNodeIsSaveForInsert (current,
                    recIndexForLeaf, recKey.keyLen_gg00, maximumKeyLen)
                THEN
                    bd30_LockTreeExclusive (current)
                ELSE
                    BEGIN (* level > FIRST_INDEX_LEVEL_BD00 *)
                    bd30_LockSubTreeExclusive (current);
                    IF  trError_gg00 = e_ok
                    THEN
                        BEGIN
                        bd50DetermineLeafNode (current, @recKey.keyVal_gg00,
                              recKey.keyLen_gg00, recIndexForLeaf, leaf, neighbs.ln);
                        IF  trError_gg00 = e_ok
                        THEN
                            BEGIN
                            bd13GetNode (current, leaf, plmLock_ebd00, nr_for_update, nptr);
                            IF  trError_gg00 = e_ok
                            THEN
                                BEGIN
                                maximumKeyLen := bd30_DetermineMaxKeyLength (nptr.np_ptr);
                                IF  NOT bd50IndexNodeIsSaveForInsert (current,
                                    recIndexForLeaf, recKey.keyLen_gg00, maximumKeyLen)
                                THEN
                                    BEGIN
                                    b13r_release_node (nptr, current, lru_normal);
                                    bd30_LockTreeExclusive (current)
                                    END
                                (*ENDIF*) 
                                END
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        CASE searchResult OF
            nonefound :
                b31add_to_leaf (rec, nptr, FIRST_REC_INDEX_BD00, neighbs.ln, current);
            nextfound :
                b31add_to_leaf (rec, nptr, recIndex, neighbs.ln, current);
            lastfound :
                b31append_to_leaf (rec, nptr, recIndex, NINETY_PERCENT_COV_BD00,
                      neighbs.ln, current);
            OTHERWISE
                trError_gg00 := e_not_implemented
            END;
        (*ENDCASE*) 
        END;
    (*ENDIF*) 
    IF  (trError_gg00 <> e_ok) AND (nptr.np_ptr <> NIL)
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30BuildCurrent (
            VAR trans   : tgg00_TransContext;
            VAR fileId  : tgg00_FileId;
            VAR current : tbd_current_tree);
 
BEGIN
bd01SetToNilCurrent (current);
current.curr_trans   := @trans;
current.curr_tree_id := fileId;
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30CheckTree (
            VAR trans           : tgg00_TransContext;
            VAR fileId          : tgg00_FileId;
            longColCnt          : tsp00_Int2;
            newLongColCnt       : tsp00_Int2;
            bWithExtendedCheck  : boolean;
            bCheckLongExistence : boolean);
 
VAR
      bDumpPage         : boolean;
      bFileWasBad       : boolean;
      bLongIsBad        : boolean;
      len               : integer;
      scanCount         : tsp00_Int4;
      boundNeighborLeaf : tsp00_PageNo;
      current           : tbd_current_tree;
      msg               : tsp00_C40;
      fileInfo          : tbd_fileinfo;
      reEntranceKey     : tgg00_Lkey;
      checkKey          : tgg00_Lkey;
 
BEGIN
bDumpPage                 := false;
bFileWasBad               := false;
bLongIsBad                := false;
boundNeighborLeaf         := NIL_PAGE_NO_GG00;
reEntranceKey.keyLen_gg00 := 0;
WITH trans DO
    BEGIN
    b17state_fdir (fileId.fileName_gg00, fileInfo,
          ftsShared_egg00 IN fileId.fileType_gg00, trans);
    IF  (trError_gg00 = e_ok) AND (f_bad IN fileInfo.fi_state)
    THEN
        bFileWasBad := true;
    (*ENDIF*) 
    REPEAT
        IF  b01downfilesystem
        THEN
            trError_gg00 := e_shutdown
        ELSE
            BEGIN
            trError_gg00                     := e_ok;
            scanCount                        := 0;
            checkKey.keyLen_gg00             := 0;
            boundNeighborLeaf                := NIL_PAGE_NO_GG00;
            fileId.fileVersion_gg00.ci2_gg00 := cgg_dummy_file_version;
            fileId.fileLeafNodes_gg00        := cgg_nil_leafnodes;
            bd30GetTree (trans, fileId, current, NOT LOCK_TREE_EXCL_BD00, m_verify);
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                IF  reEntranceKey.keyLen_gg00 = 0
                THEN
                    b06file_opmsg (csp3_check_file, current.curr_tree_id);
                (*ENDIF*) 
                bFileWasBad :=  bFileWasBad OR (f_bad IN current.currRootNptrs_bd00.np_ptr^.nd_file_state);
                bd50CheckSubTree (current.curr_tree_id.fileRoot_gg00, NIL_PAGE_NO_GG00,
                      longColCnt, newLongColCnt, scanCount, boundNeighborLeaf, bDumpPage, bLongIsBad,
                      reEntranceKey, checkKey, current, bWithExtendedCheck, bCheckLongExistence);
                END;
            (*ENDIF*) 
            bd30ReleaseTree (current);
            IF  trError_gg00 = e_bd_leaf_unlocked
            THEN
                BEGIN
                fileId.fileRoot_gg00 := NIL_PAGE_NO_GG00; (* PTS 1124752 TS 2003-10-22 *)
                vsleep (trTaskId_gg00, 0)
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
    UNTIL
        trError_gg00 <> e_bd_leaf_unlocked;
    (*ENDREPEAT*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        fileId := current.curr_tree_id;
        IF  bFileWasBad
        THEN
            bd30ResetBadFile (trans, fileId)
        (*ENDIF*) 
        END
    ELSE
        IF  (trError_gg00 <> e_disk_not_accessible) AND
            (trError_gg00 <> e_cancelled          ) AND
            (trError_gg00 <> e_shutdown           )
        THEN
            BEGIN
            b06write_filename_and_root( current.curr_tree_id );
            msg := bsp_c40;
            len := 0;
            g17nameto_line ('Base error:       ', len, msg);
            len := len + 1;
            g17basis_err_to_line (trError_gg00, len, msg);
            g01optextmsg (sp3p_console, sp3m_error, csp3_bd30_2_bad_file, csp3_n_btree, msg);
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  (trError_gg00 = e_ok) AND bLongIsBad
    THEN
        trError_gg00 := e_bad_file
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30CreateBeforeImageForDelete (
            VAR m          : tgg00_MessBlock;
            pDeleteCmd     : tsp00_Addr;
            VAR rk         : tgg00_Lkey;
            VAR old_recbuf : tgg00_Rec;
            granted_lock   : tgg00_LockReqMode;
            VAR current    : tbd_current_tree);
 
VAR
      searchResult    : tbd_searchresult;
      recPos          : tsp00_Int4;
      recIndex        : tsp00_Int4;
      nptr            : tbd_node_ptrs;
      pRec            : tgg00_RecPtr;
      neighbs         : tbd_neighbors;
 
BEGIN
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    nptr.np_ptr   := NIL;
    nptr.np_cbptr := NIL;
    bd30SearchRecord (current, rk.keyVal_gg00, rk.keyLen_gg00,
          nptr, recIndex, neighbs, searchResult);
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        IF  searchResult <> thisfound
        THEN
            trError_gg00 := e_key_not_found
        ELSE
            BEGIN
            recPos := nptr.np_ptr^.nd_pointer_list[ MAX_POINTERINDEX_BD00 - recIndex ];
            pRec   := @nptr.np_ptr^.nd_body [ recPos ];
            g10mv ('VBD30 ',   1,    
                  sizeof (nptr.np_ptr^), sizeof (old_recbuf),
                  @nptr.np_ptr^, recPos, @old_recbuf, 1 , pRec^.recLen_gg00, 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,
                      nptr.np_ptr^.nd_id, nptr.np_ptr, 1)
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current, lru_normal);
    (*ENDIF*) 
    bd30ReleaseTree (current);
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        k61bd_del (m, pDeleteCmd, old_recbuf, granted_lock);
        IF  fileTfn_gg00 = tfnTable_egg00
        THEN
            BEGIN
            b73cmd_count (ideletes_rows_read);
            b73cmd_count (ideletes_rows_del);
            END;
&       ifdef TRACE
        (*ENDIF*) 
        t01buf (bi, old_recbuf, 1, old_recbuf.recLen_gg00);
&       endif
        END;
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30CreateBeforeImageForInsert (
            VAR rk          : tgg00_Lkey;
            VAR b           : tgg00_Rec;
            VAR m           : tgg00_MessBlock;
            pInsertCmd      : tsp00_Addr;
            granted_lock    : tgg00_LockReqMode;
            VAR current     : tbd_current_tree);
 
VAR
      searchResult  : tbd_searchresult;
      recIndex      : tsp00_Int4;
      recPos        : tsp00_Int4;
      nptr          : tbd_node_ptrs;
      pRec          : tsp00_BufAddr;
      neighbs       : tbd_neighbors;
 
BEGIN
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    nptr.np_ptr   := NIL;
    nptr.np_cbptr := NIL;
    (* *)
    bd30SearchRecord (current, rk.keyVal_gg00, rk.keyLen_gg00,
          nptr, recIndex, neighbs, searchResult);
    IF  (trError_gg00 = e_ok) AND (searchResult = thisfound)
    THEN
        BEGIN
        IF  m.mb_type2 <> mm_compare_record
        THEN
            trError_gg00 := e_duplicate_key
        ELSE
            BEGIN
            recPos := nptr.np_ptr^.nd_pointer_list[ MAX_POINTERINDEX_BD00 - recIndex ];
            pRec   := @nptr.np_ptr^.nd_body[ recPos ];
            bd30compare_record (m, pRec, 1)
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current, lru_normal);
    (*ENDIF*) 
    bd30ReleaseTree (current);
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        (* *)
        k61bd_ins (m, pInsertCmd, b, granted_lock);
        (* *)
        IF  fileTfn_gg00 = tfnTable_egg00
        THEN
            b73cmd_count (iinserts_rows);
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30CreateBeforeImageForSysKeyInsert (
            VAR rk          : tgg00_Lkey;
            VAR b           : tgg00_Rec;
            VAR m           : tgg00_MessBlock;
            pInsertCmd      : tsp00_Addr;
            granted_lock    : tgg00_LockReqMode;
            VAR current     : tbd_current_tree);
 
VAR
      auxError      : tgg00_BasisError;
      searchResult  : tbd_searchresult;
      recIndex      : tsp00_Int4;
      recPos        : tsp00_Int4;
      nptr          : tbd_node_ptrs;
      pRec          : tsp00_BufAddr;
      neighbs       : tbd_neighbors;
      keyTrace      : tgg11_BdKeyTrace;
 
BEGIN
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    nptr.np_ptr         := NIL;
    nptr.np_cbptr       := NIL;
    rk.keyLen_gg00      := 1;
    rk.keyVal_gg00[ 1 ] := csp_undef_byte;
    (* *)
    bd30SearchRecord (current, rk.keyVal_gg00, rk.keyLen_gg00,
          nptr, recIndex, neighbs, searchResult);
    IF  (trError_gg00 = e_ok) AND (searchResult = thisfound)
    THEN
        BEGIN
        IF  m.mb_type2 <> mm_compare_record
        THEN
            trError_gg00 := e_duplicate_key
        ELSE
            BEGIN
            recPos := nptr.np_ptr^.nd_pointer_list[ MAX_POINTERINDEX_BD00 - recIndex ];
            pRec   := @nptr.np_ptr^.nd_body[ recPos ];
            bd30compare_record (m, pRec, 1)
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        IF  searchResult = nonefound
        THEN
            BEGIN
            b.recBody_gg00 [1] := csp_defined_byte;
            SAPDB_PascalFill ('VBD30 ',   2,    
                  sizeof (tgg00_RecBody), @b.recBody_gg00, 2,
                  sizeof (tgg00_Surrogate), chr (0), trError_gg00)
            END
        ELSE
            BEGIN
            recPos := nptr.np_ptr^.nd_pointer_list[ MAX_POINTERINDEX_BD00 - recIndex ];
            g10mv ('VBD30 ',   3,    
                  sizeof (nptr.np_ptr^), sizeof (b), @nptr.np_ptr^, recPos + cgg_rec_key_offset,
                  @b, 1 + cgg_rec_key_offset, sizeof (tgg00_Surrogate) + 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,
                      nptr.np_ptr^.nd_id, nptr.np_ptr, 1)
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        b.recKeyLen_gg00 := SURROGATE_MXGG00 + 1;
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        (* *)
        k61bd_ins (m, pInsertCmd, b, granted_lock);
        (* *)
        IF  fileTfn_gg00 = tfnTable_egg00
        THEN
            b73cmd_count (iinserts_rows);
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current, lru_normal);
    (*ENDIF*) 
    bd30ReleaseTree (current);
    (* *)
    IF  (g01vtrace.vtrAll_gg00 OR g01vtrace.vtrBdPrim_gg00)
    THEN
        BEGIN
        auxError                := e_ok;
        keyTrace.bdkTrType_gg11 := bdtrKey_egg11;
        keyTrace.bdkKeyLen_gg11 := b.recKeyLen_gg00;
        g10mv ('VBD30 ',   4,    
              b.recKeyLen_gg00, sizeof (keyTrace.bdkKey_gg11),
              @b.recKey_gg00.keyVal_gg00, 1, @keyTrace.bdkKey_gg11, 1,
              gg06Min( b.recKeyLen_gg00, sizeof( tgg00_VtraceKey )), auxError);
        b120InsertTrace (m.mb_trns^, bd, b02logadd, sizeof (keyTrace), @keyTrace)
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        kb611ins_WriteBeforeImage (pInsertCmd, m.mb_trns^)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30CreateBeforeImageForUpdate (
            VAR m              : tgg00_MessBlock;
            pUpdateCmd         : tsp00_Addr;
            VAR rk             : tgg00_Lkey;
            VAR old_recbuf     : tgg00_Rec;
            VAR new_recbuf     : tgg00_Rec;
            granted_lock       : tgg00_LockReqMode;
            VAR current        : tbd_current_tree);
 
VAR
      searchResult : tbd_searchresult;
      recPos       : tsp00_Int4;
      recIndex     : tsp00_Int4;
      pRec         : tgg00_RecPtr;
      nptr         : tbd_node_ptrs;
      neighbs      : tbd_neighbors;
 
BEGIN
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    nptr.np_ptr   := NIL;
    nptr.np_cbptr := NIL;
    bd30SearchRecord (current, rk.keyVal_gg00, rk.keyLen_gg00,
          nptr, recIndex, neighbs, searchResult);
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        IF  searchResult <> thisfound
        THEN
            trError_gg00 := e_key_not_found
        ELSE
            BEGIN
            recPos := nptr.np_ptr^.nd_pointer_list[ MAX_POINTERINDEX_BD00 - recIndex ];
            pRec   := @nptr.np_ptr^.nd_body[ recPos ];
            g10mv ('VBD30 ',   5,    
                  sizeof (nptr.np_ptr^), sizeof (old_recbuf),
                  @nptr.np_ptr^, recPos,  @old_recbuf, 1, pRec^.recLen_gg00, 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,
                      nptr.np_ptr^.nd_id, nptr.np_ptr, 1)
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current, lru_normal);
    (*ENDIF*) 
    bd30ReleaseTree (current);
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        k63bd_upd (m, pUpdateCmd, old_recbuf, new_recbuf, granted_lock);
        IF  fileTfn_gg00 = tfnTable_egg00
        THEN
            BEGIN
            b73cmd_count (iupdates_rows_read);
            b73cmd_count (iupdates_rows_upd)
            END;
&       ifdef TRACE
        (*ENDIF*) 
        t01buf (bi, old_recbuf, 1, old_recbuf.len);
        t01buf (bi, new_recbuf, 1, new_recbuf.len);
&       endif
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30CreateCoordinator (
            VAR t      : tgg00_TransContext;
            MessType   : tgg00_MessType);
 
VAR
      SendMBlock : tgg00_MessBlock;
      SendTrans  : tgg00_TransChild;
 
BEGIN
(* *)
(* MessType = m_get_object => Read Ahead For OMS Pages *)
(* *)
k53child_trans_build (MessType, t.trTaskId_gg00, SendTrans);
g01mblock_init (t, MessType, mm_coordinator, SendMBlock);
SendMBlock.mb_reply := false;
(*-=-=-=-=-=-=-=-=-=-=-=-=-=-*)
k90send (SendMBlock, SendTrans);
(*-=-=-=-=-=-=-=-=-=-=-=-=-=-*)
IF  t.trError_gg00 = e_too_many_net_requests
THEN
    t.trError_gg00 := e_ok
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30DelFromTree (
            VAR recKey  : tgg00_Lkey;
            VAR current : tbd_current_tree);
 
VAR
      bDoLockHandling : boolean;
      bReadyForDelete : boolean;
      searchResult    : tbd_searchresult;
      maximumKeyLen   : tsp00_Int4;
      recIndex        : tsp00_Int4;
      recIndexForLeaf : tsp00_Int4;
      leaf            : tsp00_PageNo;
      nptr            : tbd_node_ptrs;
      neighbs         : tbd_neighbors;
      pRec            : tgg00_RecPtr;
 
BEGIN
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    nptr.np_ptr     := NIL;
    nptr.np_cbptr   := NIL;
    bReadyForDelete := false;
    bDoLockHandling := ftsConcurrent_egg00 IN fileType_gg00;
    WHILE (trError_gg00 = e_ok) AND NOT bReadyForDelete DO
        BEGIN
        IF  nptr.np_ptr = NIL (* leaf node is not available *)
        THEN
            bd50FindLeaf (recKey.keyVal_gg00, recKey.keyLen_gg00,
                  nptr, neighbs, recIndexForLeaf, current);
        (*ENDIF*) 
        IF  trError_gg00 = e_ok
        THEN
            b31search_entry (current, recKey.keyVal_gg00, recKey.keyLen_gg00,
                  nptr.np_ptr, recIndex, searchResult);
        (*ENDIF*) 
        IF  (trError_gg00 = e_ok) AND (searchResult <> thisfound)
        THEN
            trError_gg00 := e_key_not_found;
        (*ENDIF*) 
        bReadyForDelete := NOT bDoLockHandling;
        IF  (trError_gg00 = e_ok) AND bDoLockHandling
        THEN
            BEGIN
            WITH nptr.np_ptr^ DO
                pRec := @nd_body [ nd_pointer_list[ MAX_POINTERINDEX_BD00 - recIndex ]];
            (*ENDWITH*) 
            IF  (
                (nptr.np_ptr^.nd_bottom - pRec^.recLen_gg00 - BODY_BEG_BD00 +
                ((nptr.np_ptr^.nd_record_cnt -1) * POINTERSIZE_BD00)) >= HALF_COVERING_BD00
                )
                OR
                (nptr.np_ptr^.nd_id = fileRoot_gg00)
            THEN
                bReadyForDelete := true (* local delete possible *)
            ELSE
                BEGIN
                bDoLockHandling := false;
                maximumKeyLen   := bd30_DetermineMaxKeyLength (nptr.np_ptr);
                b13r_release_node (nptr, current, lru_normal);
                IF  NOT bd50IndexNodeIsSaveForDelete (current, recIndexForLeaf, maximumKeyLen)
                THEN
                    bd30_LockTreeExclusive (current)
                ELSE
                    BEGIN (* level > FIRST_INDEX_LEVEL_BD00 *)
                    bd30_LockSubTreeExclusive (current);
                    IF  trError_gg00 = e_ok
                    THEN
                        BEGIN
                        bd50DetermineLeafNode (current, @recKey.keyVal_gg00,
                              recKey.keyLen_gg00, recIndexForLeaf, leaf, neighbs.ln);
                        IF  trError_gg00 = e_ok
                        THEN
                            BEGIN
                            bd13GetNode (current, leaf, plmLock_ebd00, nr_for_update, nptr);
                            IF  trError_gg00 = e_ok
                            THEN
                                BEGIN
                                maximumKeyLen := bd30_DetermineMaxKeyLength (nptr.np_ptr);
                                IF  NOT bd50IndexNodeIsSaveForDelete (current, recIndexForLeaf,
                                    maximumKeyLen)
                                THEN
                                    BEGIN
                                    b13r_release_node (nptr, current, lru_normal);
                                    bd30_LockTreeExclusive (current)
                                    END
                                (*ENDIF*) 
                                END
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    IF  trError_gg00 = e_ok
    THEN
        b31del_from_leaf (nptr, recIndex, neighbs.ln, current);
    (*ENDIF*) 
    IF  (trError_gg00 <> e_ok) AND (nptr.np_ptr <> NIL)
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30DropTree (
            VAR current     : tbd_current_tree;
            longColumnCount : integer;
            bOnlyEmpty      : boolean);
 
VAR
      bIsPerm : boolean;
 
BEGIN
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    bIsPerm := ftsPerm_egg00 IN fileType_gg00;
    IF  ((fileRoot_gg00 = bd17GetFdirRoot) OR (fileRoot_gg00 = bd17GetLongFdirRoot)) AND (bIsPerm)
    THEN
        trError_gg00 := e_do_not_drop_fdir;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        IF  (bIsPerm) AND (NOT bOnlyEmpty)
        THEN (* avoid prolonged blockade of SVP if root is already marked as changed *)
            bd13WriteExclusiveLockedRoot (current);
        (*ENDIF*) 
        bd50DropSubTree (fileRoot_gg00, longColumnCount, bOnlyEmpty, current);
        END;
    (*ENDIF*) 
    IF  (trError_gg00 <> e_disk_not_accessible) AND
        (trError_gg00 <> e_do_not_drop_fdir   ) AND
        (trError_gg00 <> e_ok                 )
    THEN
        BEGIN
        IF  ftsPerm_egg00 IN fileType_gg00
        THEN
            BEGIN
            g01opmsg (sp3p_knldiag, sp3m_info, bd30ErrorDuringDrop_csp03,
                  csp3_n_btree, MSG_1_DROP, trError_gg00);
            g01optextmsg (sp3p_knldiag, sp3m_info, bd30ErrorDuringDrop_csp03,
                  csp3_n_btree, MSG_2_DROP)
            END;
        (*ENDIF*) 
        trError_gg00 := e_ok
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30ExistRecord (
            VAR recKey  : tgg00_Lkey;
            VAR current : tbd_current_tree);
 
VAR
      searchResult : tbd_searchresult;
      recIndex     : tsp00_Int4;
      nptr         : tbd_node_ptrs;
      neighbs      : tbd_neighbors;
 
BEGIN
WITH current, curr_trans^  DO
    BEGIN
    nptr.np_ptr   := NIL;
    nptr.np_cbptr := NIL;
    bd30SearchRecord (current, recKey.keyVal_gg00, recKey.keyLen_gg00,
          nptr, recIndex, neighbs, searchResult);
    IF  (trError_gg00 = e_ok) AND (searchResult <> thisfound)
    THEN
        trError_gg00 := e_key_not_found;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30FindLeaf (
            VAR key     : tgg00_Lkey;
            VAR current : tbd_current_tree);
 
VAR
      recIndexForLeaf : tsp00_Int4;
      nptr            : tbd_node_ptrs;
      neighbs         : tbd_neighbors;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    nptr.np_ptr   := NIL;
    nptr.np_cbptr := NIL;
    IF  trError_gg00 = e_ok
    THEN
        bd50FindLeaf (key.keyVal_gg00, key.keyLen_gg00,
              nptr, neighbs, recIndexForLeaf, current);
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30GetFromTreeWithTreepos (
            VAR recKey   : tgg00_Lkey;
            VAR rec      : tgg00_Rec;
            VAR tree_pos : tgg00_FilePos;
            VAR current  : tbd_current_tree;
            wantedLock   : tgg00_LockReqMode);
 
VAR
      searchResult : tbd_searchresult;
      recIndex     : tsp00_Int4;
      nptr         : tbd_node_ptrs;
      neighbs      : tbd_neighbors;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    nptr.np_ptr   := NIL;
    nptr.np_cbptr := NIL;
    bd30SearchRecord (current, recKey.keyVal_gg00, recKey.keyLen_gg00,
          nptr, recIndex, neighbs, searchResult);
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        IF  searchResult <> thisfound
        THEN
            trError_gg00 := e_key_not_found
        ELSE
            BEGIN
            tree_pos.tpsPno_gg00   := nptr.np_ptr^.nd_id;
            tree_pos.tpsIndex_gg00 := recIndex;
            b31get_from_leaf (nptr, recIndex, wantedLock <> lckFree_egg00,
                  rec, current);
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30GetFromTree (
            VAR recKey  : tgg00_Lkey;
            VAR rec     : tgg00_Rec;
            VAR current : tbd_current_tree;
            wantedLock  : tgg00_LockReqMode);
 
VAR
      searchResult : tbd_searchresult;
      recIndex     : tsp00_Int4;
      nptr         : tbd_node_ptrs;
      neighbs      : tbd_neighbors;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    nptr.np_ptr   := NIL;
    nptr.np_cbptr := NIL;
    bd30SearchRecord (current, recKey.keyVal_gg00, recKey.keyLen_gg00,
          nptr, recIndex, neighbs, searchResult);
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        IF  searchResult <> thisfound
        THEN
            trError_gg00 := e_key_not_found
        ELSE
            b31get_from_leaf (nptr, recIndex, wantedLock <> lckFree_egg00,
                  rec, current)
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30GetNextLeafPage (
            VAR nextLeafPage : tsp00_PageNo;
            VAR nptr         : tbd_node_ptrs;
            VAR current      : tbd_current_tree);
 
VAR
      recIndexForLeaf : tsp00_Int4;
      nextIndexPage   : tsp00_PageNo;
      neighbs         : tbd_neighbors;
      startKey        : tgg00_Lkey;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    IF  nextLeafPage = curr_tree_id.fileRoot_gg00
    THEN
        BEGIN (* first access *)
        startKey.keyLen_gg00 := 0;
        bd50FindLeaf (startKey.keyVal_gg00, startKey.keyLen_gg00,
              nptr, neighbs, recIndexForLeaf, current)
        END
    ELSE
        BEGIN
        nextIndexPage := NIL_PAGE_NO_GG00;
        IF  nptr.np_ptr <> NIL
        THEN
            BEGIN
            IF  (ftsPerm_egg00 IN curr_tree_id.fileType_gg00) AND
                (currRightBound_bd00 = nptr.np_ptr^.nd_id   ) AND
                (currIndexNptrs_bd00.np_ptr <> NIL          )
            THEN
                nextIndexPage := currIndexNptrs_bd00.np_ptr^.nd_right;
            (*ENDIF*) 
            b13r_release_node (nptr, current, lru_last);
            END;
        (*ENDIF*) 
        IF  nextIndexPage <> NIL_PAGE_NO_GG00
        THEN
            BEGIN
            bd30ReleaseSubTree (current);
            bd30GetSubTree (current, nextIndexPage)
            END;
        (*ENDIF*) 
        IF  (trError_gg00 = e_ok) AND (nextLeafPage <> NIL_PAGE_NO_GG00)
        THEN
            bd13GetNode (current, nextLeafPage, plmLock_ebd00, nr_for_read, nptr)
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        IF  trError_gg00 = e_ok
        THEN
            nextLeafPage := nptr.np_ptr^.nd_right
        ELSE
            b13r_release_node (nptr, current, lru_normal)
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30GetNextLong (
            VAR recKey      : tgg00_Lkey;
            numberOfLongs   : integer;
            VAR currentLong : integer;
            VAR longFileId  : tgg00_FileId;
            VAR filePos     : tgg00_FilePos;
            VAR current     : tbd_current_tree);
 
VAR
      bFound       : boolean;
      searchResult : tbd_searchresult;
      recPos       : tsp00_Int4;
      longPos      : tsp00_Int4;
      recIndex     : tsp00_Int4;
      nextLeaf     : tsp00_PageNo;
      nptr         : tbd_node_ptrs;
      longFileInfo : tbd_fileinfo;
      neighbs      : tbd_neighbors;
      pRec         : tgg00_RecPtr;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    nptr.np_ptr   := NIL;
    nptr.np_cbptr := NIL;
    bFound        := false;
    IF  filePos.tpsPno_gg00 = NIL_PAGE_NO_GG00
    THEN
        BEGIN
        bd30SearchRecord (current, recKey.keyVal_gg00, recKey.keyLen_gg00,
              nptr, recIndex, neighbs, searchResult);
        IF  (trError_gg00 = e_ok) AND (searchResult = nonefound)
        THEN
            trError_gg00 := e_no_next_record
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        bd13GetNode (current, filePos.tpsPno_gg00, plmLock_ebd00, nr_for_read, nptr);
        recIndex  := filePos.tpsIndex_gg00
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        REPEAT
            WHILE (recIndex < nptr.np_ptr^.nd_record_cnt) AND (NOT bFound) DO
                WITH nptr, np_ptr^ DO
                    BEGIN
                    recPos      := nd_pointer_list[ MAX_POINTERINDEX_BD00 - recIndex ];
                    pRec        := @nptr.np_ptr^.nd_body [ recPos ];
                    longPos     := recPos + cgg_rec_key_offset + pRec^.recKeyLen_gg00;
                    longPos     := longPos + currentLong *  cgg_col_fd_size;
                    currentLong := currentLong + 1;
                    (* *)
                    WHILE (currentLong <= numberOfLongs) AND (NOT bFound) DO
                        BEGIN
                        IF  nd_body[longPos] = csp_undef_byte
                        THEN
                            BEGIN
                            longPos     := longPos +  cgg_col_fd_size;
                            currentLong := currentLong + 1
                            END
                        ELSE
                            BEGIN
                            longFileId               := b01niltree_id;
                            longFileId.fileTfn_gg00  := tfnColumn_egg00;
                            longFileId.fileType_gg00 := [ftsByteStr_egg00, ftsConcurrent_egg00];
                            g10mv ('VBD30 ',   6,    
                                  sizeof (np_ptr^), sizeof (longFileId.fileName_gg00),
                                  @np_ptr^, longPos + 1,
                                  @longFileId.fileName_gg00, 3, SURROGATE_MXGG00, 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, nd_id, np_ptr, 1)
                                END
                            ELSE
                                b17state_fdir (longFileId.fileName_gg00, longFileInfo,
                                      ftsShared_egg00 in longFileId.fileType_gg00, curr_trans^);
                            (*ENDIF*) 
                            IF  trError_gg00 = e_ok
                            THEN
                                bFound := true
                            ELSE
                                BEGIN
                                IF  trError_gg00 = e_file_not_found
                                THEN
                                    trError_gg00 := e_ok;
                                (*ENDIF*) 
                                longPos     := longPos + cgg_col_fd_size;
                                currentLong := currentLong + 1
                                END
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                        END;
                    (*ENDWHILE*) 
                    IF  bFound AND (trError_gg00 = e_ok)
                    THEN
                        BEGIN
                        filePos.tpsIndex_gg00 := recIndex;
                        filePos.tpsPno_gg00   := nd_id;
                        recKey.keyLen_gg00    := pRec^.recKeyLen_gg00;
                        g10mv ('VBD30 ',   7,    
                              sizeof (np_ptr^), recKey.keyLen_gg00,
                              @np_ptr^, recPos + cgg_rec_key_offset,
                              @recKey.keyVal_gg00, 1, recKey.keyLen_gg00, 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, nd_id, np_ptr, 1)
                            END
                        (*ENDIF*) 
                        END
                    ELSE
                        BEGIN
                        currentLong := 0;
                        recIndex    := recIndex + 1
                        END
                    (*ENDIF*) 
                    END;
                (*ENDWITH*) 
            (*ENDWHILE*) 
            IF  (NOT bFound) AND (trError_gg00 = e_ok)
            THEN
                BEGIN
                nextLeaf := nptr.np_ptr^.nd_right;
                b13r_release_node (nptr, current, lru_last);
                IF  nextLeaf <> NIL_PAGE_NO_GG00
                THEN
                    bd13GetNode (current, nextLeaf, plmLock_ebd00, nr_for_read, nptr)
                ELSE
                    trError_gg00 := e_no_next_record;
                (*ENDIF*) 
                recIndex := FIRST_REC_INDEX_BD00
                END
            (*ENDIF*) 
        UNTIL
            (trError_gg00 <> e_ok) OR bFound;
        (*ENDREPEAT*) 
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30GetTree (
            VAR trans      : tgg00_TransContext;
            VAR fileId     : tgg00_FileId;
            VAR current    : tbd_current_tree;
            bTreeExclusive : boolean;
            messType       : tgg00_MessType);
 
VAR
      bStopLoop  : boolean;
      bForDrop   : boolean;
      bForUpdate : boolean;
      fileInfo   : tbd_fileinfo;
 
BEGIN
bStopLoop           := false;
bForDrop            := bd_release_acc IN fileId.fileBdUse_gg00;
bForUpdate          := bd_write_acc IN fileId.fileBdUse_gg00;
bd01SetToNilCurrent (current);
current.curr_trans  := @trans;
current.curr_action := messType;
WITH trans DO
    BEGIN
    IF  fileId.fileRoot_gg00 <> NIL_PAGE_NO_GG00
    THEN
        BEGIN
        IF  fileId.fileRootCheck_gg00 <> ROOT_CHECK_GG00
        THEN
            bd300FileIdRootCheck (fileId, trError_gg00)
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        b17state_fdir (fileId.fileName_gg00, fileInfo,
              ftsShared_egg00 IN fileId.fileType_gg00, trans);
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            b30fdir_to_treeid (fileInfo, fileId);
            IF  ftsConcurrent_egg00 IN fileInfo.fi_type
            THEN
                BEGIN
                IF  (fileId.fileVersion_gg00          <> fileInfo.fi_vers      ) AND
                    (fileId.fileVersion_gg00.ci2_gg00 <> cgg_dummy_file_version)
                THEN
                    trError_gg00 := e_old_fileversion
                ELSE
                    IF  (ftsByteStr_egg00 IN fileInfo.fi_type   ) AND
                        (fileId.fileRoot_gg00 = NIL_PAGE_NO_GG00)
                    THEN
                        trError_gg00 := e_file_empty
                    ELSE
                        IF  bForUpdate
                        THEN
                            BEGIN
                            IF  f_bad IN fileInfo.fi_state
                            THEN
                                BEGIN
                                trError_gg00 := e_bad_file;
                                b06file_opmsg (csp3_bd30_1_bad_file, fileId);
                                END
                            ELSE
                                IF  (
                                    (f_read_only IN fileInfo.fi_state               ) AND
                                    (NOT (bd_load_nolog IN fileId.fileBdUse_gg00   )) AND
                                    (NOT (hsNoLog_egg00 IN fileId.fileHandling_gg00))
                                    )
                                THEN
                                    trError_gg00 := e_file_read_only
                                ELSE
                                    IF  (hsNoLog_egg00 IN fileId.fileHandling_gg00) AND
                                        (NOT (ftsTemp_egg00 IN fileInfo.fi_type  )) AND
                                        (NOT(f_read_only IN fileInfo.fi_state    ))
                                    THEN
                                        bd30SetReadOnly (trans, fileId)
                                    (*ENDIF*) 
                                (*ENDIF*) 
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                    (*ENDIF*) 
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    WHILE  (trError_gg00 = e_ok) AND NOT bStopLoop DO
        WITH current DO
            BEGIN
            curr_tree_id := fileId;
            IF  bTreeExclusive
            THEN
                IF  (NOT bForDrop)
                    AND
                    ((ftsPerm_egg00 IN fileInfo.fi_type) OR (ftsByteStr_egg00 IN fileInfo.fi_type))
                THEN
                    bd13GetNode (current, fileId.fileRoot_gg00, plmLockForSplit_ebd00,
                          nr_for_update, currRootNptrs_bd00)
                ELSE
                    bd13GetNode (current, fileId.fileRoot_gg00, plmLock_ebd00,
                          nr_for_update, currRootNptrs_bd00)
                (*ENDIF*) 
            ELSE
                BEGIN
                bd13GetNode (current, fileId.fileRoot_gg00, plmLock_ebd00,
                      nr_for_read, currRootNptrs_bd00);
                IF  (trError_gg00 = e_ok) AND bForUpdate AND
                    (LEAF_LEVEL_BD00 = currRootNptrs_bd00.np_ptr^.nd_level)
                THEN
                    BEGIN
                    bd30ReleaseTree (current);
                    bd13GetNode (current, fileId.fileRoot_gg00, plmLock_ebd00,
                          nr_for_update, currRootNptrs_bd00)
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  trError_gg00 = e_file_must_be_read_only
            THEN
                BEGIN
                trError_gg00 := e_ok;
                bd30ReleaseTree (current);
                bd30SetReadOnly (trans, fileId)
                END
            ELSE
                bStopLoop := true; (* common case *)
            (*ENDIF*) 
            END
        (*ENDWITH*) 
    (*ENDWHILE*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30GetSubTree (
            VAR current : tbd_current_tree;
            indexPageNo : tsp00_PageNo);
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    bd13GetNode (current, indexPageNo, plmLock_ebd00,
          nr_for_read, currIndexNptrs_bd00);
    IF  trError_gg00 = e_ok
    THEN
        WITH currIndexNptrs_bd00 DO
            BEGIN
            currLeftBound_bd00  := bd52SubtreePno (np_ptr, FIRST_REC_INDEX_BD00);
            currRightBound_bd00 := bd52SubtreePno (np_ptr, np_ptr^.nd_record_cnt - 1);
            IF  np_ptr^.nd_level <> FIRST_INDEX_LEVEL_BD00
            THEN
                g01abort (bd30x1IllegalLockHandling_csp03, csp3_n_btree,
                      MSG_WRONG_LEVEL, np_ptr^.nd_level);
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
&   ifdef TRACE
    (*ENDIF*) 
    t01int4 (bd_index,   'indexNode   ', indexPageNo);
    t01p2int4 (bd_index, 'currLeft    ', currLeftBound_bd00, 'currRight   ', currRightBound_bd00);
&   endif
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30NextFromTree (
            VAR recKey   : tgg00_Lkey;
            bInclusive   : boolean;
            VAR rec      : tgg00_Rec;
            VAR current  : tbd_current_tree);
 
VAR
      bWithSQLLock : boolean;
      searchResult : tbd_searchresult;
      recIndex     : tsp00_Int4;
      nptr         : tbd_node_ptrs;
      neighbs      : tbd_neighbors;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    nptr.np_ptr   := NIL;
    nptr.np_cbptr := NIL;
    bd30SearchRecord (current, recKey.keyVal_gg00, recKey.keyLen_gg00,
          nptr, recIndex, neighbs, searchResult);
    IF  (trError_gg00 = e_ok) AND (searchResult = nonefound)
    THEN
        trError_gg00 := e_no_next_record;
    (*ENDIF*) 
    IF  (trError_gg00 = e_ok) AND (searchResult <> nextfound)
        AND
        (NOT bInclusive OR (searchResult = lastfound))
    THEN
        b31next_search (nptr, recIndex, current);
    (*might return b_no_next_record*)
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        bWithSQLLock := curr_tree_id.fileTabId_gg00 = cgg_sys1_catalog_id;
        b31get_from_leaf (nptr, recIndex, bWithSQLLock, rec, current)
        END;
    (*ENDIF*) 
    IF  (trError_gg00 = e_ok) AND (searchResult <> thisfound)
    THEN
        trError_gg00 := e_key_not_found;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30PrevFromTree (
            VAR recKey  : tgg00_Lkey;
            bInclusive  : boolean;
            VAR rec     : tgg00_Rec;
            VAR current : tbd_current_tree);
 
VAR
      bWithSQLLock : boolean;
      searchResult : tbd_searchresult;
      recIndex     : tsp00_Int4;
      prevLeaf     : tsp00_PageNo;
      nptr         : tbd_node_ptrs;
      neighbs      : tbd_neighbors;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    nptr.np_ptr   := NIL;
    nptr.np_cbptr := NIL;
    bd30SearchRecord (current, recKey.keyVal_gg00, recKey.keyLen_gg00,
          nptr, recIndex, neighbs, searchResult);
    IF  (trError_gg00 = e_ok) AND (searchResult = nonefound)
    THEN
        trError_gg00 := e_no_prev_record;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        IF  (searchResult <> lastfound)
            AND
            (NOT bInclusive OR (searchResult <> thisfound))
        THEN
            IF  ftsTemp_egg00 IN curr_tree_id.fileType_gg00
            THEN
                b31t_prev_temp_search (nptr, recIndex, current)
            ELSE
                b31prev_search (recKey.keyVal_gg00, recKey.keyLen_gg00,
                      nptr, recIndex, prevLeaf, current);
            (*ENDIF*) 
        (*ENDIF*) 
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            bWithSQLLock := curr_tree_id.fileTabId_gg00 = cgg_sys1_catalog_id;
            b31get_from_leaf (nptr, recIndex, bWithSQLLock, rec, current)
            END;
        (*ENDIF*) 
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            IF  (trError_gg00 = e_ok) AND (searchResult <> thisfound)
            THEN
                trError_gg00 := e_key_not_found
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30ReleaseTree (
            VAR current : tbd_current_tree);
 
VAR
      auxRootNptrs  : tbd_node_ptrs;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    bd30ReleaseSubTree (current);
    IF  currRootNptrs_bd00.np_ptr <> NIL
    THEN
        BEGIN
        auxRootNptrs                := currRootNptrs_bd00;
        currRootNptrs_bd00.np_ptr   := NIL;
        currRootNptrs_bd00.np_cbptr := NIL;
        IF  (trError_gg00 = e_ok) AND currRootUpdated_bd00
        THEN
            BEGIN
            b13w_release_node (auxRootNptrs, current);
            currRootUpdated_bd00 := false;
            END
        ELSE
            b13r_release_node (auxRootNptrs, current, lru_normal)
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  currFreeQueue_bd00.fqTop_bd00 > 1
    THEN
        bd13FreePnosAfterUnlock (current);
    (*ENDIF*) 
    IF  (currCounter_bd00 <> 0) AND g01glob.bd_lock_check
    THEN
        BEGIN
        IF  (bd_release_acc IN curr_tree_id.fileBdUse_gg00) OR
            (ftsTemp_egg00  IN curr_tree_id.fileType_gg00 )
        THEN (* Drop/Delete: caused by b13free_node and bd13FreePageNo mix *)
            currCounter_bd00 := 0
        ELSE
            BEGIN
            b06write_filename_and_root (curr_tree_id);
            g01abort (bd30x3IllegalLockHandling_csp03, csp3_n_btree,
                  MSG_RELEASE_MISSING, currCounter_bd00)
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  (e_bad_datapage = trError_gg00                      ) AND
        (
        (ftsPerm_egg00 IN curr_tree_id.fileType_gg00        ) OR
        (ftsByteStr_egg00 IN curr_tree_id.fileType_gg00     )
        )
        AND
        (NOT (bd_release_acc IN curr_tree_id.fileBdUse_gg00))
    THEN
        bd30BadFile (curr_trans^, curr_tree_id);
    (*ENDIF*) 
    IF  trError_gg00 <> e_ok
    THEN
        IF  (trError_gg00 = e_no_converter_entry   ) OR
            (trError_gg00 = e_invalid_root         ) OR
            (trError_gg00 = e_page_in_wrong_tree   ) OR
            (trError_gg00 = e_inconsistent_nodetype)
        THEN
            bd06IllegalRootAccess (curr_trans^, curr_tree_id)
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30ReleaseSubTree(
            VAR current : tbd_current_tree);
 
VAR
      auxNptrs : tbd_node_ptrs;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    IF  currIndexNptrs_bd00.np_ptr <> NIL
    THEN
        BEGIN
        auxNptrs                     := currIndexNptrs_bd00;
        currIndexNptrs_bd00.np_ptr   := NIL;
        currIndexNptrs_bd00.np_cbptr := NIL;
        currLeftBound_bd00           := NIL_PAGE_NO_GG00;
        currRightBound_bd00          := NIL_PAGE_NO_GG00;
        curr_lvl_1_pno               := NIL_PAGE_NO_GG00;
        IF  (trError_gg00 = e_ok) AND currIndexUpdated_bd00
        THEN
            BEGIN
            b13w_release_node (auxNptrs, current);
            currIndexUpdated_bd00 := false;
            END
        ELSE
            b13r_release_node (auxNptrs, current, lru_normal)
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30ReplaceInTreeWithTreepos (
            VAR rec      : tgg00_Rec;
            VAR tree_pos : tgg00_FilePos;
            VAR current  : tbd_current_tree);
 
VAR
      recIndex        : tsp00_Int4;
      nptr            : tbd_node_ptrs;
 
BEGIN
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    nptr.np_ptr     := NIL;
    nptr.np_cbptr   := NIL;
    IF  tree_pos.tpsPno_gg00 = fileRoot_gg00
    THEN
        nptr := currRootNptrs_bd00
    ELSE
        bd13GetNode (current, tree_pos.tpsPno_gg00, plmLock_ebd00, nr_for_update, nptr);
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        recIndex := tree_pos.tpsIndex_gg00;
        b31repl_in_leaf (rec, nptr, recIndex, NIL_PAGE_NO_GG00, current);
        END;
    (*ENDIF*) 
    IF  (trError_gg00 <> e_ok) AND (nptr.np_ptr <> NIL)
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30ReplaceInTree (
            VAR recKey  : tgg00_Lkey;
            VAR rec     : tgg00_Rec;
            VAR current : tbd_current_tree);
 
VAR
      bDoLockHandling : boolean;
      bIsGrowing      : boolean;
      bReadyForUpdate : boolean;
      searchResult    : tbd_searchresult;
      difference      : tsp00_Int4;
      maximumKeyLen   : tsp00_Int4;
      recIndex        : tsp00_Int4;
      recIndexForLeaf : tsp00_Int4;
      leaf            : tsp00_PageNo;
      nptr            : tbd_node_ptrs;
      neighbs         : tbd_neighbors;
      pRec            : tgg00_RecPtr;
 
BEGIN
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    nptr.np_ptr     := NIL;
    nptr.np_cbptr   := NIL;
    bReadyForUpdate := false;
    bDoLockHandling := ftsConcurrent_egg00 IN fileType_gg00;
    WHILE (trError_gg00 = e_ok) AND NOT bReadyForUpdate DO
        BEGIN
        IF  nptr.np_ptr = NIL (* leaf node is not available *)
        THEN
            bd50FindLeaf (recKey.keyVal_gg00, recKey.keyLen_gg00,
                  nptr, neighbs, recIndexForLeaf, current);
        (*ENDIF*) 
        IF  trError_gg00 = e_ok
        THEN
            b31search_entry (current, recKey.keyVal_gg00, recKey.keyLen_gg00,
                  nptr.np_ptr, recIndex, searchResult);
        (*ENDIF*) 
        IF  (trError_gg00 = e_ok) AND (searchResult <> thisfound)
        THEN
            trError_gg00 := e_key_not_found;
        (*ENDIF*) 
        bReadyForUpdate := NOT bDoLockHandling;
        IF  (trError_gg00 = e_ok) AND bDoLockHandling
        THEN
            BEGIN
            WITH nptr.np_ptr^ DO
                BEGIN
                pRec       := @nd_body [ nd_pointer_list[ MAX_POINTERINDEX_BD00 - recIndex ]];
                difference := abs( pRec^.recLen_gg00 -  rec.recLen_gg00);
                IF  pRec^.recLen_gg00 <= rec.recLen_gg00
                THEN
                    BEGIN
                    bIsGrowing      := true;
                    bReadyForUpdate := ((nd_bottom + difference) <=
                          MAX_BOTTOM_BD00 - (nd_record_cnt * POINTERSIZE_BD00))
                    END
                ELSE (* record shrinks *)
                    BEGIN
                    bIsGrowing      := false;
                    bReadyForUpdate :=
                          ((nd_bottom - difference - BODY_BEG_BD00 +
                          (nd_record_cnt * POINTERSIZE_BD00)) >= HALF_COVERING_BD00)
                          OR
                          (nd_id = fileRoot_gg00)
                    END
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
            IF  NOT bReadyForUpdate
            THEN
                BEGIN
                bDoLockHandling := false;
                maximumKeyLen   := bd30_DetermineMaxKeyLength (nptr.np_ptr);
                b13r_release_node (nptr, current, lru_normal);
                IF  NOT bd50IndexNodeIsSaveForReplace (current, bIsGrowing,
                    recIndexForLeaf, recKey.keyLen_gg00, maximumKeyLen)
                THEN
                    bd30_LockTreeExclusive (current)
                ELSE
                    BEGIN (* level > FIRST_INDEX_LEVEL_BD00 *)
                    bd30_LockSubTreeExclusive (current);
                    IF  trError_gg00 = e_ok
                    THEN
                        BEGIN
                        bd50DetermineLeafNode (current, @recKey.keyVal_gg00,
                              recKey.keyLen_gg00, recIndexForLeaf, leaf, neighbs.ln);
                        IF  trError_gg00 = e_ok
                        THEN
                            BEGIN
                            bd13GetNode (current, leaf, plmLock_ebd00, nr_for_update, nptr);
                            IF  trError_gg00 = e_ok
                            THEN
                                BEGIN
                                maximumKeyLen := bd30_DetermineMaxKeyLength (nptr.np_ptr);
                                IF  NOT bd50IndexNodeIsSaveForReplace (current, bIsGrowing,
                                    recIndexForLeaf, recKey.keyLen_gg00, maximumKeyLen)
                                THEN
                                    BEGIN
                                    b13r_release_node (nptr, current, lru_normal);
                                    bd30_LockTreeExclusive (current)
                                    END
                                (*ENDIF*) 
                                END
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    IF  trError_gg00 = e_ok
    THEN
        b31repl_in_leaf (rec, nptr, recIndex, neighbs.ln, current);
    (*ENDIF*) 
    IF  (trError_gg00 <> e_ok) AND (nptr.np_ptr <> NIL)
    THEN
        b13r_release_node (nptr, current, lru_normal)
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30ResetBadFile (
            VAR trans  : tgg00_TransContext;
            VAR fileId : tgg00_FileId);
 
VAR
      current : tbd_current_tree;
 
BEGIN
WITH trans DO
    BEGIN
    bd30GetTree (trans, fileId, current, LOCK_TREE_EXCL_BD00, m_nil);
    IF  trError_gg00 = e_ok
    THEN
        bd30SubFileState (current, [f_bad]);
    (*ENDIF*) 
    bd30ReleaseTree (current);
    IF  trError_gg00 = e_ok
    THEN
        b17fsub_file_state (trans, fileId, [f_bad]);
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30SearchRecord(
            VAR current      : tbd_current_tree;
            VAR recKey       : tsp00_Key;
            recKeyLen        : tsp00_Int4;
            VAR nptr         : tbd_node_ptrs;
            VAR recIndex     : tsp00_Int4;
            VAR neighbs      : tbd_neighbors;
            VAR searchResult : tbd_searchresult);
 
VAR
      recIndexForLeaf : tsp00_Int4;
 
BEGIN
IF  current.curr_trans^.trError_gg00 = e_ok
THEN
    bd50FindLeaf (recKey, recKeyLen, nptr, neighbs, recIndexForLeaf, current);
(*ENDIF*) 
IF  current.curr_trans^.trError_gg00 = e_ok
THEN
    b31search_entry (current, recKey, recKeyLen, nptr.np_ptr, recIndex, searchResult);
&ifdef TRACE
(*ENDIF*) 
t01p2int4 (bd_index, 'recIndex    ', recIndex, 'searchResult', ord (searchResult));
t01p2int4 (bd_index, 'leftNeighbor', neighbs.ln, 'rightNeighbo', neighbs.rn);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30SetReadOnly (
            VAR trans  : tgg00_TransContext;
            VAR fileId : tgg00_FileId);
 
VAR
      bIsWriteAccess : boolean;
      len            : integer;
      id_pos         : integer;
      n              : tsp00_Name;
      msg            : tsp00_C40;
      current        : tbd_current_tree;
 
BEGIN
WITH trans DO
    BEGIN
    trError_gg00 := e_ok;
    b17fadd_file_state (trans, fileId, [f_read_only]);
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        bIsWriteAccess := bd_write_acc IN fileId.fileBdUse_gg00;
        IF  bIsWriteAccess
        THEN (* avoid endless loop during bd30GetTree call *)
            fileId.fileBdUse_gg00 := fileId.fileBdUse_gg00 - [bd_write_acc];
        (*ENDIF*) 
        bd30GetTree (trans, fileId, current, LOCK_TREE_EXCL_BD00, m_nil);
        IF  trError_gg00 = e_ok
        THEN
            bd30AddFileState (current, [f_read_only]);
        (*ENDIF*) 
        bd30ReleaseTree (current);
        IF  bIsWriteAccess
        THEN
            fileId.fileBdUse_gg00 := fileId.fileBdUse_gg00 + [bd_write_acc];
        (* *)
        (*ENDIF*) 
        n   := 'SET READ ONLY:    ';
        msg := bsp_c40;
        len := 0;
        g17nameto_line (n, len, msg);
        len := len + 1;
        FOR id_pos := 1 TO 10 DO
            BEGIN
            g17hexto_line (current.curr_tree_id.fileName_gg00 [id_pos], len, msg);
            IF  id_pos = 2
            THEN
                len := len + 1;
            (*ENDIF*) 
            END;
        (*ENDFOR*) 
        g01optextmsg (sp3p_knldiag, sp3m_info, csp3_b30_1_set_read_only, csp3_n_btree, msg);
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30SetFileVersion (
            VAR current    : tbd_current_tree;
            newfileVersion : tgg91_FileVersion);
 
BEGIN
WITH current, currRootNptrs_bd00.np_ptr^  DO
    BEGIN
    nd_file_version      := newfileVersion;
    currRootUpdated_bd00 := true
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30SubFileState (
            VAR current : tbd_current_tree;
            fileState   : tbd_file_state_set);
 
BEGIN
WITH current, currRootNptrs_bd00.np_ptr^ DO
    BEGIN
    nd_file_state        := nd_file_state - fileState;
    currRootUpdated_bd00 := true;
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30_LockTreeExclusive (
            VAR current : tbd_current_tree);
 
BEGIN
(* ftsConcurrent_egg00 IN fileType_gg00 only *)
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    IF  NOT bd20IsPageExclusiveLocked (currRootNptrs_bd00.np_cbptr)
    THEN
        BEGIN
        bd30ReleaseTree (current);
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            IF  bd_release_acc IN fileBdUse_gg00
            THEN
                bd13GetNode (current, fileRoot_gg00, plmLock_ebd00,
                      nr_for_update, currRootNptrs_bd00)
            ELSE
                BEGIN
                IF  ftsPerm_egg00 in fileType_gg00
                THEN
                    bd13GetNode (current, fileRoot_gg00, plmLockForSplit_ebd00,
                          nr_for_update, currRootNptrs_bd00)
                ELSE
                    bd13GetNode (current, fileRoot_gg00, plmLock_ebd00,
                          nr_for_update, currRootNptrs_bd00)
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30_LockSubTreeExclusive (
            VAR current : tbd_current_tree);
 
VAR
      subRoot : tsp00_PageNo;
 
BEGIN
(* ftsConcurrent_egg00 IN fileType_gg00 only *)
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    IF  FIRST_INDEX_LEVEL_BD00 >= currRootNptrs_bd00.np_ptr^.nd_level
    THEN
        g01abort (bd30x2IllegalLockHandling_csp03,
              csp3_n_btree, MSG_1_WRONG_LEVEL, fileRoot_gg00);
    (*ENDIF*) 
    IF  NOT bd20IsPageExclusiveLocked (currIndexNptrs_bd00.np_cbptr)
    THEN
        BEGIN
        (* caused by the root share lock it is guaranteed that the structure *)
        (* of the b*tree index part won't be modified. Only the number of    *)
        (* leaves could be changed.                                          *)
        (* *)
        subRoot := currIndexNptrs_bd00.np_ptr^.nd_id;
        bd30ReleaseSubTree (current);
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            IF  ftsPerm_egg00 in fileType_gg00
            THEN
                bd13GetNode (current, subRoot, plmLockForSplit_ebd00,
                      nr_for_update, currIndexNptrs_bd00)
            ELSE
                bd13GetNode (current, subRoot, plmLock_ebd00,
                      nr_for_update, currIndexNptrs_bd00);
            (*ENDIF*) 
            IF  trError_gg00 = e_ok
            THEN
                WITH currIndexNptrs_bd00 DO
                    BEGIN
                    currLeftBound_bd00  := bd52SubtreePno (np_ptr, FIRST_REC_INDEX_BD00);
                    currRightBound_bd00 := bd52SubtreePno (np_ptr, np_ptr^.nd_record_cnt - 1);
                    IF  np_ptr^.nd_level <> FIRST_INDEX_LEVEL_BD00
                    THEN
                        g01abort (bd30x4IllegalLockHandling_csp03, csp3_n_btree,
                              MSG_WRONG_LEVEL, np_ptr^.nd_level);
                    (*ENDIF*) 
                    END
                (*ENDWITH*) 
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30OmsReadAheadCoordinator (VAR t : tgg00_TransContext;
            ReadAheadServer : integer);
 
VAR
      Finish          : boolean;
      RetryCnt        : integer;
      SendCnt         : integer;
      ErrorRoot       : tsp00_PageNo;
      FileId          : tgg00_FileId;
      FileInfo        : tbd_fileinfo;
 
BEGIN
RetryCnt            := 0;
SendCnt             := 0;
Finish              := false;
FileId              := b01niltree_id;
FileId.fileTfn_gg00 := tfnObj_egg00;
WITH t DO
    BEGIN
    WHILE ((trError_gg00 = e_ok) AND (NOT Finish))
          OR
          ((trError_gg00 = e_too_many_net_requests) AND (RetryCnt < c_max_retries))
          DO
        BEGIN
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            b17succ_fdir (FileId.fileName_gg00, FileId.fileName_gg00,
                  FileInfo, ftsShared_egg00 IN FileId.fileType_gg00, t,
                  NOT c_include_strcols);
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                IF  (FileId.fileTfn_gg00 <> tfnObj_egg00) OR  b01downfilesystem
                THEN
                    Finish := true
                ELSE
                    b30fdir_to_treeid (FileInfo, FileId)
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  trError_gg00 = e_file_not_found
            THEN
                BEGIN
                Finish       := true;
                trError_gg00 := e_ok
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  ((trError_gg00 = e_ok) OR (trError_gg00 = e_too_many_net_requests))
            AND
            (NOT Finish)
        THEN
            bd30_SendFileId (t, FileId, RetryCnt, SendCnt, m_get_object,
                  false, false); (* PTS 1113635 FF *)
        (*ENDIF*) 
        IF  ((trError_gg00 = e_ok) AND (SendCnt = ReadAheadServer))
            OR
            ((Finish) AND (SendCnt > 0))
            OR
            ((trError_gg00 = e_too_many_net_requests) AND (SendCnt > 0))
        THEN
            bd30wait_for_reply (t, SendCnt, ErrorRoot, ReadAheadServer, Finish);
        (*ENDIF*) 
        IF  (NOT Finish) AND
            (
            (trError_gg00 = e_too_many_net_requests) AND
            (SendCnt      = 0                      ) AND
            (RetryCnt    >= c_max_retries          )
            )
        THEN
            BEGIN
            (* no server available *)
            trError_gg00 := e_ok;
            RetryCnt     := 0;
            bd04OmsReadAheadParticipant (t, FileId)
            END;
        (*ENDIF*) 
        IF  (trError_gg00 = e_ok) AND (trRteCommPtr_gg00^.to_cancel)
        THEN
            trError_gg00 := e_cancelled
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    IF  trError_gg00 <> e_ok
    THEN
        bd30discard_task (t, SendCnt)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30VerifyTree (
            VAR trans          : tgg00_TransContext;
            VAR fileId         : tgg00_FileId;
            bUpdateConverter   : boolean;
            bWithExtendedCheck : boolean;
            VAR numPages       : tsp00_Int4);
 
VAR
      bIsPerm           : boolean;
      bDumpPage         : boolean;
      bFileWasBad       : boolean;
      bIsFileDirectory  : boolean;
      scanCount         : tsp00_Int4;
      boundNeighborLeaf : tsp00_PageNo;
      current           : tbd_current_tree;
      fileInfo          : tbd_fileinfo;
      reEntranceKey     : tgg00_Lkey;
      checkKey          : tgg00_Lkey;
 
BEGIN
numPages                  := 0;
bDumpPage                 := false;
bFileWasBad               := false;
reEntranceKey.keyLen_gg00 := 0;
bIsPerm                   := ftsPerm_egg00 IN fileId.fileType_gg00;
bIsFileDirectory          := (fileId.fileRoot_gg00 = bd17GetFdirRoot    ) OR
      (fileId.fileRoot_gg00 = bd17GetLongFdirRoot);
WITH trans  DO
    BEGIN
    IF  NOT bIsFileDirectory
    THEN
        BEGIN
        b17state_fdir (fileId.fileName_gg00, fileInfo,
              ftsShared_egg00 IN fileId.fileType_gg00, trans);
        IF  (trError_gg00 = e_ok) AND (f_bad IN fileInfo.fi_state)
        THEN
            bFileWasBad := true;
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    REPEAT
        IF  b01downfilesystem
        THEN
            trError_gg00 := e_shutdown
        ELSE
            BEGIN
            trError_gg00                     := e_ok;
            scanCount                        := 0;
            checkKey.keyLen_gg00             := 0;
            boundNeighborLeaf                := NIL_PAGE_NO_GG00;
            fileId.fileVersion_gg00.ci2_gg00 := cgg_dummy_file_version;
            fileId.fileLeafNodes_gg00        := cgg_nil_leafnodes;
            bd30GetTree (trans, fileId, current, NOT LOCK_TREE_EXCL_BD00, m_verify);
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                IF  (NOT bIsFileDirectory) AND (reEntranceKey.keyLen_gg00 = 0)
                THEN
                    b06file_opmsg (csp3_check_file, current.curr_tree_id);
                (*ENDIF*) 
                bFileWasBad := bFileWasBad OR (f_bad IN current.currRootNptrs_bd00.np_ptr^.nd_file_state);
                bd50VerifySubTree (current.curr_tree_id.fileRoot_gg00, NIL_PAGE_NO_GG00,
                      bUpdateConverter, bWithExtendedCheck, reEntranceKey, checkKey,
                      boundNeighborLeaf, bDumpPage, current, scanCount, numPages);
                END;
            (*ENDIF*) 
            bd30ReleaseTree (current);
            IF  trError_gg00 = e_bd_leaf_unlocked
            THEN
                BEGIN
                fileId.fileRoot_gg00 := NIL_PAGE_NO_GG00; (* PTS 1124752 TS 2003-10-22 *)
                vsleep (trTaskId_gg00, 0)
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
    UNTIL
        trError_gg00 <> e_bd_leaf_unlocked;
    (*ENDREPEAT*) 
    IF  (trError_gg00 = e_ok) AND bFileWasBad
    THEN
        BEGIN
        fileId := current.curr_tree_id;
        bd30ResetBadFile (trans, fileId)
        END
    ELSE
        IF  (trError_gg00 <> e_ok                 ) AND
            (trError_gg00 <> e_disk_not_accessible) AND
            (trError_gg00 <> e_cancelled          ) AND
            (trError_gg00 <> e_shutdown           )
        THEN
            b06write_filename_and_root( fileId );
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30ObjFileCoordinator (VAR t : tgg00_TransContext;
            mtype           : tgg00_MessType;    (* PTS 1113635 FF *)
            NumRepairServer : integer);
 
VAR
      Finish          : boolean;
      RetryCnt        : integer;
      SendCnt         : integer;
      ErrorRoot       : tsp00_PageNo;
      FileId          : tgg00_FileId;
      FileInfo        : tbd_fileinfo;
 
BEGIN
RetryCnt            := 0;
SendCnt             := 0;
Finish              := false;
FileId              := b01niltree_id;
FileId.fileTfn_gg00 := tfnObj_egg00;
WITH t DO
    BEGIN
    WHILE ((trError_gg00 = e_ok) AND (NOT Finish))
          OR
          ((trError_gg00 = e_too_many_net_requests) AND (RetryCnt < c_max_retries))
          DO
        BEGIN
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            b17succ_fdir (FileId.fileName_gg00, FileId.fileName_gg00,
                  FileInfo, ftsShared_egg00 IN FileId.fileType_gg00, t,
                  NOT c_include_strcols);
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                IF  (FileId.fileTfn_gg00 <> tfnObj_egg00) OR  b01downfilesystem
                THEN
                    Finish := true
                ELSE
                    b30fdir_to_treeid (FileInfo, FileId)
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  trError_gg00 = e_file_not_found
            THEN
                BEGIN
                Finish       := true;
                trError_gg00 := e_ok
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  ((trError_gg00 = e_ok) OR (trError_gg00 = e_too_many_net_requests))
            AND
            (NOT Finish)
        THEN
            bd30_SendFileId (t, FileId, RetryCnt, SendCnt, mtype, false, false);
        (*ENDIF*) 
        IF  ((trError_gg00 = e_ok) AND (SendCnt = NumRepairServer))
            OR
            ((Finish) AND (SendCnt > 0))
            OR
            ((trError_gg00 = e_too_many_net_requests) AND (SendCnt > 0))
        THEN
            bd30wait_for_reply (t, SendCnt, ErrorRoot, NumRepairServer, Finish);
        (*ENDIF*) 
        IF  (NOT Finish) AND
            (
            (trError_gg00 = e_too_many_net_requests) AND
            (SendCnt      = 0                      ) AND
            (RetryCnt    >= c_max_retries          )
            )
        THEN
            BEGIN
            (* no server available *)
            trError_gg00 := e_ok;
            RetryCnt     := 0;
            b01pverify_participant (t, FileId, false, false);
            END;
        (*ENDIF*) 
        IF  (trError_gg00 = e_ok) AND (trRteCommPtr_gg00^.to_cancel)
        THEN
            trError_gg00 := e_cancelled
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    IF  trError_gg00 <> e_ok
    THEN
        bd30discard_task (t, SendCnt)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30discard_task (VAR t : tgg00_TransContext;
            VAR send_cnt: integer);
 
VAR
      aux_err      : tgg00_BasisError;
      child_mblock : tgg00_MessBlock;
      child_trans  : tgg00_TransChild;
      sendQualPart : tbd30_SendQualPart;
 
BEGIN
&ifdef TRACE
(* fight against usecheck *)
sendQualPart.sqp_Filler1_bd30 := 0; (* fight against usecheck *)
&endif
aux_err        := t.trError_gg00;
t.trError_gg00 := e_ok;
WHILE (send_cnt > 0) AND (t.trError_gg00 = e_ok) DO
    BEGIN
    g01mblock_init (t, m_nil, mm_nil, child_mblock);
    WITH child_mblock DO
        BEGIN
        mb_qual      := @sendQualPart;
        mb_qual_size := sizeof (sendQualPart);
        mb_qual_len  := mb_qual_size
        END;
    (*ENDWITH*) 
    (*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*)
    k90rcv_child (child_mblock, child_trans);
    (*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*)
    IF  t.trError_gg00 = e_ok
    THEN
        send_cnt := pred (send_cnt)
    (*ENDIF*) 
    END;
(*ENDWHILE*) 
IF  t.trError_gg00 = e_ok
THEN
    t.trError_gg00 := aux_err
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30compare_record (VAR m : tgg00_MessBlock;
            rec_ptr : tsp00_BufAddr;
            pos     : integer);
 
VAR
      comp_result    : tsp00_LcompResult;
      col            : integer;
      col_pos_buf    : integer;
      col_len_buf    : integer;
      col_pos_node   : integer;
      col_len_node   : integer;
      old_varcol_pos : tgg00_VarColPosList;
      new_varcol_pos : tgg00_VarColPosList;
 
BEGIN
WITH m, mb_trns^ DO
    BEGIN
    comp_result              := l_equal;
    col                      := mb_qual^.mupd_pos;
    trError_gg00             := e_duplicate_record;
    old_varcol_pos.vpl_last  := -1;
    new_varcol_pos.vpl_last  := -1;
    WHILE (col < mb_qual^.mupd_pos + mb_qual^.mupd_cnt)
          AND (trError_gg00 = e_duplicate_record) DO
        BEGIN
        g04locate_col (mb_qual^.mst_addr^[ col ], @mb_data^.mbp_rec,
              new_varcol_pos, col_pos_buf, col_len_buf);
        g04locate_col (mb_qual^.mst_addr^[ col ], @rec_ptr^[pos],
              old_varcol_pos, col_pos_node, col_len_node);
        s30cmp (mb_data^.mbp_buf, col_pos_buf, col_len_buf,
              rec_ptr^, col_pos_node, col_len_node, comp_result);
        IF  comp_result <> l_equal
        THEN
            trError_gg00 := e_duplicate_key;
        (*ENDIF*) 
        col := col + 1
        END
    (*ENDWHILE*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30wait_for_reply (VAR t : tgg00_TransContext;
            VAR send_cnt  : integer;
            VAR ErrorRoot : tsp00_PageNo;
            max_server    : integer;
            finish        : boolean);
 
VAR
      aux_err      : tgg00_BasisError;
      old_send_cnt : integer;
      child_mblock : tgg00_MessBlock;
      child_trans  : tgg00_TransChild;
      sendQualPart : tbd30_SendQualPart;
 
BEGIN
&ifdef TRACE
(* fight against usecheck *)
sendQualPart.sqp_Extended_bd30 := false; (* fight against usecheck *)
&endif
IF  t.trError_gg00 <> e_ok
THEN
    BEGIN
    (* *)
    (* trError_gg00 = e_too_many_net_requests *)
    (* *)
    aux_err        := t.trError_gg00;
    t.trError_gg00 := e_ok
    END
ELSE
    aux_err := e_ok;
(*ENDIF*) 
old_send_cnt := send_cnt;
WHILE (
      (t.trError_gg00 = e_ok                   ) AND
      ((send_cnt > 0) AND finish               ) OR
      ((send_cnt = max_server) AND (NOT finish))
      )
      OR
      (
      (aux_err = e_too_many_net_requests       ) AND
      (send_cnt = old_send_cnt                 )
      )
      DO
    BEGIN
    g01mblock_init (t, m_nil, mm_nil, child_mblock);
    WITH child_mblock DO
        BEGIN
        mb_qual      := @sendQualPart;
        mb_qual_size := sizeof (sendQualPart);
        mb_qual_len  := mb_qual_size
        END;
    (*ENDWITH*) 
    (*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=*)
    k90rcv_child (child_mblock, child_trans);
    (*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=*)
    IF  t.trError_gg00 = e_ok
    THEN
        BEGIN
        send_cnt := pred (send_cnt);
        IF  child_trans.tcdError_gg00 <> e_ok
        THEN
            BEGIN
            t.trError_gg00 := child_trans.tcdError_gg00;
            (* PTS 1105359 TS 2000-01-17 *)
            ErrorRoot      := gg06TransGetInt4 (child_trans.tcdTransId_gg00);
            (* PTS 1105359 *)
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDWHILE*) 
IF  (t.trError_gg00 = e_ok) AND (aux_err <> e_ok)
THEN
    t.trError_gg00 := aux_err;
&ifdef TRACE
(*ENDIF*) 
t01basis_error (bi, 'bd30wait end', t.trError_gg00);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30BadFile (
            VAR trans  : tgg00_TransContext;
            VAR fileId : tgg00_FileId);
 
VAR
      current : tbd_current_tree;
 
BEGIN
WITH trans DO
    BEGIN
    IF  (fileId.fileName_gg00 <> cgg_zero_fn) AND (fileId.fileRoot_gg00 <> NIL_PAGE_NO_GG00)
    THEN
        BEGIN
        IF  (fileId.fileRoot_gg00 = bd17GetFdirRoot    ) OR
            (fileId.fileRoot_gg00 = bd17GetLongFdirRoot)
        THEN
            BEGIN
            g01optextmsg (sp3p_knldiag, sp3m_error, csp3_bd_msg,
                  csp3_n_btree, MSG_FDIR_CORRUPTED);
            END
        ELSE
            BEGIN
            trError_gg00 := e_ok;
            bd30GetTree (trans, fileId, current, LOCK_TREE_EXCL_BD00, m_nil);
            b06file_opmsg (csp3_bad_file, current.curr_tree_id);
            IF  trError_gg00 = e_ok
            THEN
                bd30AddFileState (current, [f_bad]);
            (*ENDIF*) 
            IF  e_bad_datapage = trError_gg00
            THEN
                trError_gg00 := e_ok (* root page is bad ! *)
            ELSE
                bd30ReleaseTree (current);
            (*ENDIF*) 
            (* *)
            IF  trError_gg00 = e_ok
            THEN
                b17fadd_file_state (trans, fileId, [f_bad])
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        trError_gg00 := e_bad_datapage
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      bd30_DetermineMaxKeyLength (pNode : tbd_nodeptr) : tsp00_Int4;
 
VAR
      maxKeyLen : tsp00_Int4;
      recIndex  : tsp00_Int4;
      recPos    : tsp00_Int4;
      pRec      : tgg00_RecPtr;
 
BEGIN
maxKeyLen := 0;
IF  g01glob.bd_subtree
THEN
    BEGIN
    recIndex := FIRST_REC_INDEX_BD00;
    WHILE (recIndex <= (pNode^.nd_record_cnt - 1)) DO
        BEGIN
        recPos := pNode^.nd_pointer_list [MAX_POINTERINDEX_BD00 - recIndex];
        pRec   := @pNode^.nd_body [recPos];
        IF  maxKeyLen < pRec^.recKeyLen_gg00
        THEN
            maxKeyLen := pRec^.recKeyLen_gg00;
        (*ENDIF*) 
        recIndex := succ (recIndex)
        END
    (*ENDWHILE*) 
    END;
(*ENDIF*) 
bd30_DetermineMaxKeyLength := maxKeyLen;
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30_PnoCheckOpmsg (
            root    : tsp00_PageNo;
            trError : tgg00_BasisError);
 
VAR
      len    : integer;
      msg_no : tsp00_Int4;
      msg    : tsp00_C40;
 
BEGIN
msg_no := csp3_verify_check;
msg    := bsp_c40;
len    := 0;
g17nameto_line ('Base error:       ', len, msg);
len    := len + 1;
g17basis_err_to_line (trError, len, msg);
g01optextmsg (sp3p_console, sp3m_error, msg_no, csp3_n_check, msg);
(* *)
msg := bsp_c40;
len := 0;
g17nameto_line ('Root pageNo:      ', len, msg);
len    := len + 1;
g17trimint4_to_line (root, len, msg);
g01optextmsg (sp3p_console, sp3m_error, msg_no, csp3_n_check, msg);
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd30_SendFileId (
            VAR t          : tgg00_TransContext;
            VAR FileId     : tgg00_FileId;
            VAR RetryCnt   : integer;
            VAR SendCnt    : integer;
            messType       : tgg00_MessType;
            bWithUpdate    : boolean;
            bExtendedCheck : boolean);
 
VAR
      AuxError     : tgg00_BasisError;
      SendMBlock   : tgg00_MessBlock;
      SendTrans    : tgg00_TransChild;
      sendQualPart : tbd30_SendQualPart;
 
BEGIN
(* messType = m_migrate_obj_files=> migrate < 7.4.02.03        *)
(* messType = m_verify           => Warm And Cold Verify       *)
(* messType = m_get_object       => Read Ahead For OMS Pages   *)
(* *)
sendQualPart.sqp_FileId_bd30     := FileId;
sendQualPart.sqp_WithUpdate_bd30 := bWithUpdate;
sendQualPart.sqp_Extended_bd30   := bExtendedCheck;
(* *)
WITH t DO
    BEGIN
    (* trError_gg00 = e_too_many_net_requests *)
    AuxError     := trError_gg00;
    trError_gg00 := e_ok;
    k53child_trans_build (messType, FileId.fileRoot_gg00, SendTrans);
    g01mblock_init (t, messType, mm_participant, SendMBlock);
    WITH SendMBlock DO
        BEGIN
        mb_struct    := mbs_buf;
        mb_qual      := @sendQualPart;
        mb_qual_size := sizeof (sendQualPart);
        mb_qual_len  := mb_qual_size
        END;
    (*ENDWITH*) 
    (*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*)
    k90send (SendMBlock, SendTrans);
    (*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*)
    IF  trError_gg00 = e_ok
    THEN
        SendCnt := succ (SendCnt)
    ELSE
        IF  trError_gg00 = e_too_many_net_requests
        THEN
            BEGIN
            RetryCnt := succ (RetryCnt);
            vsleep (trTaskId_gg00, 1)
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  (trError_gg00 = e_ok) AND (AuxError = e_too_many_net_requests)
    THEN
        BEGIN
        RetryCnt     := 0;
        trError_gg00 := e_ok
        END;
&   ifdef TRACE
    (*ENDIF*) 
    t01basis_error (bi, 'bd30_Send   ', trError_gg00);
&   endif
    END
(*ENDWITH*) 
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
