.ad 8
.bm 8
.fm 4
.bt $Copyright (c) 2000-2005 SAP AG$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $SQL$Project Distributed Database System$VBD18$
.tt 2 $$$
.tt 3 $JuergenP$diskfiledirectory$$2000-02-10$
***********************************************************
.nf
 
 .nf
 
    ========== licence begin  GPL
    Copyright (c) 2000-2005 SAP AG
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end
.fo
 
 
.fo
.nf
.sp
Module  : diskfiledirectory
=========
.sp
Purpose : external file directory
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :
 
        PROCEDURE
              b18add_dfdir (VAR fn : tgg00_Filename;
                    VAR fi            : tbd_fileinfo;
                    VAR current_dfdir : tbd_current_tree);
 
        PROCEDURE
              b18del_dfdir (VAR fn : tgg00_Filename;
                    VAR fi            : tbd_fileinfo;
                    VAR current_dfdir : tbd_current_tree);
 
        PROCEDURE
              b18lcreate_lcl_tfdir (VAR t : tgg00_TransContext);
 
        PROCEDURE
              b18ldrop_lcl_tfdir (VAR t : tgg00_TransContext);
 
        PROCEDURE
              b18next_dfdir (VAR fn : tgg00_Filename;
                    VAR fi            : tbd_fileinfo;
                    VAR current_dfdir : tbd_current_tree);
 
        PROCEDURE
              b18repl_dfdir (VAR fn : tgg00_Filename;
                    VAR fi            : tbd_fileinfo;
                    VAR current_dfdir : tbd_current_tree);
 
        PROCEDURE
              b18search_dfdir (VAR fn : tgg00_Filename;
                    VAR fi            : tbd_fileinfo;
                    VAR current_dfdir : tbd_current_tree);
 
        PROCEDURE
              bd18CreateFdir (
                    VAR trans      : tgg00_TransContext;
                    VAR permFileId : tgg00_FileId;
                    VAR longFileId : tgg00_FileId;
                    VAR tempFileId : tgg00_FileId);
 
        PROCEDURE
              bd18RestartFdir (
                    VAR trans      : tgg00_TransContext;
                    permFileRoot   : tsp00_PageNo;
                    longFileRoot   : tsp00_PageNo;
                    VAR permFileId : tgg00_FileId;
                    VAR longFileId : tgg00_FileId;
                    VAR tempFileId : tgg00_FileId);
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              filesysteminterface_1 : VBD01;
 
        VAR
              b01niltree_id : tgg00_FileId;
 
      ------------------------------ 
 
        FROM
              nodehandling : VBD13;
 
        PROCEDURE
              bd13GetNode (VAR Current : tbd_current_tree;
                    Pno          : tsp00_PageNo;
                    PageLockMode : tbd00_PageLockMode;
                    NodeReq      : tbd_node_request;
                    VAR Nptrs    : tbd_node_ptrs);
 
        PROCEDURE
              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);
 
      ------------------------------ 
 
        FROM
              task_temp_data_cache : VBD21;
 
        PROCEDURE
              b21lcl_tfdir_root (temp_cache_ptr : tgg00_TempDataCachePtr;
                    is_set  : boolean;
                    VAR pno : tsp00_PageNo);
 
      ------------------------------ 
 
        FROM
              treehandling : VBD30;
 
        PROCEDURE
              bd30BuildCurrent (
                    VAR trans   : tgg00_TransContext;
                    VAR fileId  : tgg00_FileId;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              bd30DropTree (
                    VAR current     : tbd_current_tree;
                    longColumnCount : integer;
                    bOnlyEmpty      : boolean);
 
        PROCEDURE
              bd30GetTree (
                    VAR trans            : tgg00_TransContext;
                    VAR fileId           : tgg00_FileId;
                    VAR current          : tbd_current_tree;
                    messType             : tgg00_MessType;
                    bLockTreeExcl        : boolean;
                    bSynchronizeExclLock : boolean);
 
        PROCEDURE
              bd30SearchRecord(
                    VAR current      : tbd_current_tree;
                    VAR recKey       : tsp00_Key;
                    recKeyLen        : tsp00_Int4;
                    bLockLeafExcl    : boolean;
                    VAR nptr         : tbd_node_ptrs;
                    VAR recIndex     : tsp00_Int4;
                    VAR neighbs      : tbd_neighbors;
                    VAR searchResult : tbd_searchresult);
 
        PROCEDURE
              bd30ReleaseTree (
                    VAR current : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              leafhandling : VBD31;
 
        PROCEDURE
              b31add_to_leaf (VAR b : tbd00_FDirEntry;
                    VAR nptr    : tbd_node_ptrs;
                    index       : integer;
                    left        : tsp00_PageNo;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b31append_to_leaf (VAR b : tbd00_FDirEntry;
                    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        : tbd00_FDirEntry;
                    VAR current  : tbd_current_tree);
 
        PROCEDURE
              b31next_search (
                    VAR nptr    : tbd_node_ptrs;
                    VAR index   : integer;
                    VAR current : tbd_current_tree);
 
        PROCEDURE
              b31repl_in_leaf (VAR b : tbd00_FDirEntry;
                    VAR nptr    : tbd_node_ptrs;
                    index       : integer;
                    left        : tsp00_PageNo;
                    VAR current : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              GG_cpp_auxiliary_functions : VGG06;
 
        PROCEDURE
              gg06SetNilRef (VAR PageRef : tgg91_PageRef);
&       ifdef TRACE
 
      ------------------------------ 
 
        FROM
              Test_Procedures : VTA01;
 
        PROCEDURE
              t01basis_error (layer : tgg00_Debug;
                    nam   : tsp00_Sname;
                    b_err : tgg00_BasisError);
 
        PROCEDURE
              t01int4 (debug : tgg00_Debug;
                    nam : tsp00_Sname;
                    int : tsp00_Int4);
 
        PROCEDURE
              t01page (layer : tgg00_Debug;
                    VAR n   : tbd_node;
                    start_p : tsp00_Int4;
                    stop_p  : tsp00_Int4);
&       endif
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              b31add_to_leaf;
 
              tgg00_Rec tbd00_FDirEntry
 
        PROCEDURE
              b31append_to_leaf;
 
              tgg00_Rec tbd00_FDirEntry
 
        PROCEDURE
              b31get_from_leaf;
 
              tgg00_Rec tbd00_FDirEntry
 
        PROCEDURE
              b31repl_in_leaf;
 
              tgg00_Rec tbd00_FDirEntry
&             ifdef TRACE
 
        PROCEDURE
              t01page;
 
              tsp00_Page tbd_node
&             endif
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : JuergenP
.sp
.cp 3
Created : 1979-11-09
.sp
.cp 3
.sp
.cp 3
Release :      Date : 2000-02-10
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
 
The external file directory, consisting of the directory for
permanent files and the directory for temporary files, contains
exactly one entry for all created files.  Each entry is made up
of a file name fn and file information fi; the file information
field ftype indicates whether the entry belongs to a temporary
or a permanent file.
.sp 2
   b18create_dfdir(perm_dfdir,temp_dfdir,t,e)
.sp
This routine must be called during system generation.  It creates
the file directory.  Afterwards, the directory does not yet contain
any entries.  In addition, the current tree information is sent
in perm_dfdir/temp_dfdir to the permanent/temporary directory.
.br
Acknowledgements in e:
 - e_ok
 - b_disk_not_accessible.
.sp 2
   bd18RestartFdir(fdir_1_root,fdir_2_root,perm_dfdir,
                    temp_dfdir,t)
.sp
This routine must be called each time the system is restarted.
It creates a completely new directory for temporary files.
In addition, the current tree information is sent in
perm_dfdir/temp_dfdir to the permanent/temporary directory.
.br
Acknowledgements in e:
 - e_ok
 - e_disk_not_accessible.
.sp 2
   b18add_dfdir(fn,fi,current_dfdir,e)
.sp
Forms a new entry from fn and fi and inserts this entry in the
external file directory, if the directory contains no other file
entry with the same name and enough space is available for a new
entry.
.br
Acknowledgements in e:
 - e_ok
 - b_duplicate_filename
 - b_disk_not_accessible.
.sp 2
   b18repl_dfdir(fn,fi,current_dfdir,e)
.sp
In the external file directory, replaces the file information of
the entry with the name fn, if such an entry is present, with
the new file information fi.
.br
Acknowledgements in e:
   - e_ok
   - b_file_not_found
   - b_disk_not_accessible.
.sp 2
   b18del_dfdir(fn,fi,current_dfdir,e)
.sp
Deletes the entry with the file name fn from the external file
directory, if such an entry is contained in the directory.
.br
Acknowledgements in e:
 - e_ok
 - b_file_not_found
 - b_disk_not_accessible.
.sp 2
   b18search_dfdir(fn,fi,current_dfdir,e)
.sp
Searches the external file directory for an entry with the file name
fn.  If this entry is contained in the directory, its file
information fi is fetched.
.br
Acknowledgements in e:
 - e_ok
 - b_file_not_found
 - b_disk_not_accessible.
.sp 2
   b18next_dfdir(fn,fi,current_dfdir,e)
.sp
Searches the external file directory for the entry following
the entry with the file name fn.  If such an entry is contained
in the file directory, its file information fi is fetched and
the file name sent to fn.
.br
Acknowledgements in e:
 - e_ok
 - b_file_not_found
 - b_no_next_record
 - b_disk_not_accessible.
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
 
The file directory (diskfiledirectory) is managed by a
permanent file with the defined root segment first_fdirpagenumber
(see pagestore VBD10) and by a temporary file.  The result is that
there is no restriction in the number of possible file entries.
.sp
When the directory file is initialized, only the empty root segment
exists.  In the directory, the file entries are handled like normal
records whose keys are file names with a fixed length
(maxfilenamelength).  When the system is restarted, entries relating
to temporary files are deleted.
.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    :
 
 
CONST
      c_set_pno = true;
 
 
(*------------------------------*) 
 
PROCEDURE
      b18add_dfdir (VAR fn    : tgg00_Filename;
            VAR fi            : tbd_fileinfo;
            VAR current_dfdir : tbd_current_tree);
 
VAR
      result          : tbd_searchresult;
      index           : tsp00_Int4;
      nptr            : tbd_node_ptrs;
      neighbs         : tbd_neighbors;
      FDirEntry       : tbd00_FDirEntry;
      pKey            : ^tgg00_Lkey;
 
BEGIN
nptr.np_ptr   := NIL;
nptr.np_cbptr := NIL;
WITH FDirEntry DO
    BEGIN
    fdirFill1_bd00          := 0;
    fdirFill2_bd00          := 0;
    fdirFileName_bd00       := fn;
    fdirFileNameLength_bd00 := FN_MXGG00
    END;
(*ENDWITH*) 
pKey := @FDirEntry;
bd30SearchRecord (current_dfdir, pKey^.keyVal_gg00, pKey^.keyLen_gg00,
      LOCK_LEAF_EXCL_BD00, nptr, index, neighbs, result);
WITH current_dfdir, curr_trans^ DO
    BEGIN
&   ifdef TRACE
    t01basis_error (bd, 'b18add fdir ', trError_gg00);
    t01int4        (bd, 'result      ', ord(result));
&   endif
    IF  trError_gg00 = e_ok
    THEN
        IF  result = thisfound
        THEN
            trError_gg00 := e_duplicate_filename;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        WITH FDirEntry DO
            BEGIN
            IF  fi.fi_descr = []
            THEN
                fdirEntryLength_bd00 := STD_FDIRENTRY_MXBD00
            ELSE
                fdirEntryLength_bd00 := FDIRENTRY_MXBD00;
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
        FDirEntry.fdirFileInfo_bd00 := fi;
        WITH neighbs DO
            CASE result OF
                nonefound :
                    b31add_to_leaf (FDirEntry, nptr, FIRST_REC_INDEX_BD00,
                          ln, current_dfdir);
                nextfound :
                    b31add_to_leaf (FDirEntry, nptr, index, ln, current_dfdir);
                lastfound :
                    b31append_to_leaf (FDirEntry, nptr, index,
                          NINETY_PERCENT_COV_BD00, ln, current_dfdir)
                END;
            (*ENDCASE*) 
        (*ENDWITH*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_bad_datapage
    THEN
        trError_gg00 := e_bad_fdir;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current_dfdir, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b18del_dfdir (VAR fn : tgg00_Filename;
            VAR fi            : tbd_fileinfo;
            VAR current_dfdir : tbd_current_tree);
 
VAR
      result          : tbd_searchresult;
      index           : tsp00_Int4;
      pno             : tsp00_PageNo;
      nptr            : tbd_node_ptrs;
      neighbs         : tbd_neighbors;
      FDirEntry       : tbd00_FDirEntry;
      pKey            : ^tgg00_Lkey;
 
BEGIN
nptr.np_ptr   := NIL;
nptr.np_cbptr := NIL;
WITH FDirEntry DO
    BEGIN
    fdirFill1_bd00          := 0;
    fdirFill2_bd00          := 0;
    fdirFileName_bd00       := fn;
    fdirFileNameLength_bd00 := FN_MXGG00
    END;
(*ENDWITH*) 
pKey := @FDirEntry;
bd30SearchRecord (current_dfdir, pKey^.keyVal_gg00, pKey^.keyLen_gg00,
      LOCK_LEAF_EXCL_BD00, nptr, index, neighbs, result);
WITH current_dfdir, curr_trans^ DO
    BEGIN
    IF  trError_gg00 = e_ok
    THEN
        IF  result <> thisfound
        THEN
            trError_gg00 := e_file_not_found;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        pno := nptr.np_ptr^.nd_id;
        b31get_from_leaf (nptr, index, false, FDirEntry, current_dfdir);
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            fi := FDirEntry.fdirFileInfo_bd00;
            IF  NOT (fid_user_ref in fi.fi_descr)
            THEN
                gg06SetNilRef (fi.fi_user_ref);
            (*ENDIF*) 
            bd13GetNode (current_dfdir, pno, plmLock_ebd00, nr_for_update, nptr);
            IF  trError_gg00 = e_ok
            THEN
                b31del_from_leaf (nptr, index, neighbs.ln, current_dfdir);
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN
        IF  f_unloaded in fi.fi_state
        THEN
            trError_gg00 := e_file_unloaded;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  trError_gg00 = e_bad_datapage
    THEN
        trError_gg00 := e_bad_fdir;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current_dfdir, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b18lcreate_lcl_tfdir (VAR t : tgg00_TransContext);
 
VAR
      nptr         : tbd_node_ptrs;
      fileId       : tgg00_FileId;
      current_fdir : tbd_current_tree;
 
BEGIN
WITH t DO
    BEGIN
    trError_gg00  := e_ok;
    nptr.np_ptr   := NIL;
    nptr.np_cbptr := NIL;
    bd18_InitFileId ([ftsTemp_egg00], fileId);
    bd30BuildCurrent (t, fileId, current_fdir);
    b13new_root (nptr, current_fdir);
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        nptr.np_ptr^.nd_pmode   := nptr.np_ptr^.nd_pmode + [pmFdir_egg00];
        nptr.np_ptr^.nd_trailer := nptr.np_ptr^.nd_header;
        b21lcl_tfdir_root (t.trBdTcachePtr_gg00, c_set_pno, nptr.np_ptr^.nd_id);
        b13w_release_node (nptr, current_fdir)
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b18ldrop_lcl_tfdir (VAR t : tgg00_TransContext);
 
CONST
      c_only_empty = true;
 
VAR
      fileId       : tgg00_FileId;
      current_fdir : tbd_current_tree;
 
BEGIN
WITH t DO
    BEGIN
    bd18_InitFileId ([ftsTemp_egg00], fileId);
    b21lcl_tfdir_root (trBdTcachePtr_gg00, NOT c_set_pno, fileId.fileRoot_gg00);
    (* PTS 1124326 TS 2003-09-23 *)
    IF  fileId.fileRoot_gg00 <> NIL_PAGE_NO_GG00
    THEN
        BEGIN
        bd30BuildCurrent (t, fileId, current_fdir);
        fileId.fileBdUse_gg00 := fileId.fileBdUse_gg00 + [bd_release_acc];
        bd30GetTree (t, fileId, current_fdir, m_drop,
              LOCK_TREE_EXCL_BD00, NOT SYNC_EXCL_LOCK_BD00);
        IF  trError_gg00 = e_ok
        THEN
            bd30DropTree (current_fdir, 0, NOT c_only_empty);
        (*ENDIF*) 
        bd30ReleaseTree (current_fdir);
        fileId.fileBdUse_gg00 := fileId.fileBdUse_gg00 - [bd_release_acc];
        IF  trError_gg00 = e_bad_datapage
        THEN
            trError_gg00 := e_ok
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b18next_dfdir (VAR fn : tgg00_Filename;
            VAR fi            : tbd_fileinfo;
            VAR current_dfdir : tbd_current_tree);
 
VAR
      result          : tbd_searchresult;
      index           : tsp00_Int4;
      nptr            : tbd_node_ptrs;
      neighbs         : tbd_neighbors;
      FDirEntry       : tbd00_FDirEntry;
      pKey            : ^tgg00_Lkey;
 
BEGIN
nptr.np_ptr   := NIL;
nptr.np_cbptr := NIL;
WITH FDirEntry DO
    BEGIN
    fdirFill1_bd00          := 0;
    fdirFill2_bd00          := 0;
    fdirFileName_bd00       := fn;
    fdirFileNameLength_bd00 := FN_MXGG00
    END;
(*ENDWITH*) 
pKey := @FDirEntry;
bd30SearchRecord (current_dfdir, pKey^.keyVal_gg00, pKey^.keyLen_gg00,
      NOT LOCK_LEAF_EXCL_BD00, nptr, index, neighbs, result);
WITH current_dfdir.curr_trans^ DO
    BEGIN
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        IF  result = nonefound
        THEN
            trError_gg00 := e_no_next_record
        ELSE
            BEGIN
            IF  result <> nextfound
            THEN
                b31next_search (nptr, index, current_dfdir);
            (* might return b_no_next_record*)
&           ifdef TRACE
            (*ENDIF*) 
            t01basis_error (bd, 'b18next fdir', trError_gg00);
            t01page        (bd, nptr.np_ptr^, 1,
                  nptr.np_ptr^.nd_bottom -1);
&           endif
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                b31get_from_leaf (nptr, index, false, FDirEntry,
                      current_dfdir);
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    fn := FDirEntry.fdirFileName_bd00;
                    fi := FDirEntry.fdirFileInfo_bd00;
                    IF  NOT (fid_user_ref IN fi.fi_descr)
                    THEN
                        gg06SetNilRef (fi.fi_user_ref)
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_bad_datapage
    THEN
        trError_gg00 := e_bad_fdir;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current_dfdir, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b18repl_dfdir (VAR fn : tgg00_Filename;
            VAR fi            : tbd_fileinfo;
            VAR current_dfdir : tbd_current_tree);
 
VAR
      result          : tbd_searchresult;
      index           : tsp00_Int4;
      nptr            : tbd_node_ptrs;
      neighbs         : tbd_neighbors;
      FDirEntry       : tbd00_FDirEntry;
      pKey            : ^tgg00_Lkey;
 
BEGIN
nptr.np_ptr   := NIL;
nptr.np_cbptr := NIL;
WITH FDirEntry DO
    BEGIN
    fdirFill1_bd00          := 0;
    fdirFill2_bd00          := 0;
    fdirFileName_bd00       := fn;
    fdirFileNameLength_bd00 := FN_MXGG00
    END;
(*ENDWITH*) 
pKey := @FDirEntry;
bd30SearchRecord (current_dfdir, pKey^.keyVal_gg00, pKey^.keyLen_gg00,
      LOCK_LEAF_EXCL_BD00, nptr, index, neighbs, result);
WITH current_dfdir, curr_trans^ DO
    BEGIN
    IF  trError_gg00 = e_ok
    THEN
        IF  result <> thisfound
        THEN
            trError_gg00 := e_file_not_found;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  trError_gg00 = e_ok
    THEN (* thisfound*)
        BEGIN
        WITH FDirEntry DO
            BEGIN
            IF  fi.fi_descr = []
            THEN
                fdirEntryLength_bd00 := STD_FDIRENTRY_MXBD00
            ELSE
                fdirEntryLength_bd00 := FDIRENTRY_MXBD00;
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
        FDirEntry.fdirFileInfo_bd00 := fi;
        b31repl_in_leaf (FDirEntry, nptr, index, neighbs.ln, current_dfdir)
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_bad_datapage
    THEN
        trError_gg00 := e_bad_fdir;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current_dfdir, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b18search_dfdir (VAR fn : tgg00_Filename;
            VAR fi            : tbd_fileinfo;
            VAR current_dfdir : tbd_current_tree);
 
VAR
      result          : tbd_searchresult;
      index           : tsp00_Int4;
      nptr            : tbd_node_ptrs;
      neighbs         : tbd_neighbors;
      FDirEntry       : tbd00_FDirEntry;
      pKey            : ^tgg00_Lkey;
 
BEGIN
nptr.np_ptr   := NIL;
nptr.np_cbptr := NIL;
WITH FDirEntry DO
    BEGIN
    fdirFill1_bd00          := 0;
    fdirFill2_bd00          := 0;
    fdirFileName_bd00       := fn;
    fdirFileNameLength_bd00 := FN_MXGG00
    END;
(*ENDWITH*) 
pKey := @FDirEntry;
bd30SearchRecord (current_dfdir, pKey^.keyVal_gg00, pKey^.keyLen_gg00,
      NOT LOCK_LEAF_EXCL_BD00, nptr, index, neighbs, result);
WITH current_dfdir.curr_trans^ DO
    BEGIN
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        IF  result <> thisfound
        THEN
            trError_gg00 := e_file_not_found
        ELSE
            BEGIN
            b31get_from_leaf (nptr, index, false, FDirEntry, current_dfdir);
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                fi := FDirEntry.fdirFileInfo_bd00;
                IF  NOT (fid_user_ref in fi.fi_descr)
                THEN
                    gg06SetNilRef (fi.fi_user_ref)
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  trError_gg00 = e_bad_datapage
    THEN
        trError_gg00 := e_bad_fdir;
    (*ENDIF*) 
    IF  nptr.np_ptr <> NIL
    THEN
        b13r_release_node (nptr, current_dfdir, lru_normal)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd18CreateFdir (
            VAR trans      : tgg00_TransContext;
            VAR permFileId : tgg00_FileId;
            VAR longFileId : tgg00_FileId;
            VAR tempFileId : tgg00_FileId);
 
VAR
      nptr         : tbd_node_ptrs;
      current_fdir : tbd_current_tree;
 
BEGIN
WITH trans DO
    BEGIN
    trError_gg00  := e_ok;
    nptr.np_ptr   := NIL;
    nptr.np_cbptr := NIL;
    bd18_InitFileId ([ftsPerm_egg00, ftsConcurrent_egg00], permFileId);
    bd30BuildCurrent (trans, permFileId, current_fdir);
    b13new_root (nptr, current_fdir);
    IF  trError_gg00 = e_ok
    THEN
        BEGIN
        permFileId.fileRoot_gg00 := nptr.np_ptr^.nd_id;
        nptr.np_ptr^.nd_pmode    := nptr.np_ptr^.nd_pmode + [pmFdir_egg00];
        nptr.np_ptr^.nd_trailer  := nptr.np_ptr^.nd_header;
        b13w_release_node (nptr, current_fdir);
        IF  trError_gg00 = e_ok
        THEN
            BEGIN
            bd18_InitFileId ([ftsPerm_egg00, ftsConcurrent_egg00], longFileId);
            bd30BuildCurrent (trans, longFileId, current_fdir);
            b13new_root (nptr, current_fdir);
            IF  trError_gg00 = e_ok
            THEN
                BEGIN
                longFileId.fileRoot_gg00 := nptr.np_ptr^.nd_id;
                nptr.np_ptr^.nd_pmode    := nptr.np_ptr^.nd_pmode + [pmFdir_egg00];
                nptr.np_ptr^.nd_trailer  := nptr.np_ptr^.nd_header;
                b13w_release_node (nptr, current_fdir);
                IF  trError_gg00 = e_ok
                THEN
                    BEGIN
                    bd18_InitFileId ([ftsTemp_egg00, ftsShared_egg00, ftsConcurrent_egg00],
                          tempFileId);
                    bd30BuildCurrent (trans, tempFileId, current_fdir);
                    b13new_root (nptr, current_fdir);
                    IF  trError_gg00 = e_ok
                    THEN
                        BEGIN
                        tempFileId.fileRoot_gg00 := nptr.np_ptr^.nd_id;
                        nptr.np_ptr^.nd_pmode    := nptr.np_ptr^.nd_pmode + [pmFdir_egg00];
                        nptr.np_ptr^.nd_trailer  := nptr.np_ptr^.nd_header;
                        b13w_release_node (nptr, current_fdir)
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd18RestartFdir (
            VAR trans      : tgg00_TransContext;
            permFileRoot   : tsp00_PageNo;
            longFileRoot   : tsp00_PageNo;
            VAR permFileId : tgg00_FileId;
            VAR longFileId : tgg00_FileId;
            VAR tempFileId : tgg00_FileId);
 
VAR
      nptr         : tbd_node_ptrs;
      current_fdir : tbd_current_tree;
 
BEGIN
trans.trError_gg00 := e_ok;
nptr.np_ptr        := NIL;
nptr.np_cbptr      := NIL;
(* perm *)
bd18_InitFileId ([ftsPerm_egg00, ftsConcurrent_egg00], permFileId);
permFileId.fileRoot_gg00 := permFileRoot;
(* strcol *)
bd18_InitFileId ([ftsPerm_egg00, ftsConcurrent_egg00], longFileId);
longFileId.fileRoot_gg00 := longFileRoot;
(* temp *)
(* curr_root must be initialized *)
bd18_InitFileId ([ftsTemp_egg00, ftsShared_egg00, ftsConcurrent_egg00], tempFileId);
bd30BuildCurrent (trans, tempFileId, current_fdir);
b13new_root (nptr, current_fdir);
IF  trans.trError_gg00 = e_ok
THEN
    BEGIN
    tempFileId.fileRoot_gg00 := nptr.np_ptr^.nd_id;
    nptr.np_ptr^.nd_pmode    := nptr.np_ptr^.nd_pmode + [pmFdir_egg00];
    nptr.np_ptr^.nd_trailer  := nptr.np_ptr^.nd_header;
    b13w_release_node (nptr, current_fdir)
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd18_InitFileId (
            fileType   : tgg00_FiletypeSet;
            VAR fileId : tgg00_FileId);
 
BEGIN
WITH fileId DO
    BEGIN
    fileId         := b01niltree_id;
    fileType_gg00  := fileType;
    fileBdUse_gg00 := [];
    IF  ftsPerm_egg00 IN fileType
    THEN
        fileTfn_gg00 := tfnTable_egg00
    ELSE
        BEGIN
        fileTfn_gg00     := tfnTemp_egg00;
        fileTfnTemp_gg00 := ttfnErrorText_egg00;
        (* see temp_req_limit check in b10req_pno *)
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
