Trailing-Edge
-
PDP-10 Archives
-
RMS-10_T10_704_FT2_880425
-
10,7/rms10/rmssrc/rmsfil.b36
There are 6 other files named rmsfil.b36 in the archive. Click here to see a list.
MODULE FILES =
BEGIN
GLOBAL BIND FILEV = 1^24 + 0^18 + 8; !EDIT DATE: 23-DEC-76
%([
FUNCTION: THIS MODULE CONTAINS ALL ROUTINES WHICH CREATE
AND PROCESS THE PROLOGUE BLOCKS WITHIN AN RMS-20
FILE.
AUTHOR: S. BLOUNT
THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
!COPYRIGHT (C) 1977, 1979 BY DIGITAL EQUIPMENT CORPORATION
********** TABLE OF CONTENTS **************
ROUTINE FUNCTION
======= ========
SETPLOG CREATE A FILE PROLOGUE BLOCK
IDXFILEPROLOG CREATE THE INDEXED FILE PROLOGUE
DOAREABLOCKS CREATE THE AREA DESCRIPTORS (INDEXED FILE ONLY)
DOKEYBLOCKS CREATE THE INDEX DESCRIPTORS (INDEXED FILE ONLY)
GETIDB LOCATE AN INDEX DESCRIPTOR BLOCK
REVISION HISTORY:
EDIT DATE WHO PURPOSE
==== ==== === ========
1 7-15 SEB ADD GETIDB
2 SEP-2-76 SEB ADD > 16 KEY DESCRIPTORS
3 29-SEP-76 SEB ADD AREADESCSIZE COMPUTATION
4 7-NOV-76 SEB TAKE OUT ADBAID
5 7-NOV-76 SEB FIX NXTBKT TO BE IN PAGES
6 16-DEC-76 SEB ADD REQUIRE BUFFER.REQ
7 23-DEC-76 SEB MAKE BKS=0 INTO BKS=1
*************************************************
* *
* NEW REVISION HISTORY *
* *
*************************************************
****************** Start RMS-10 V1.1 *********************
********************* TOPS-10 ONLY ***********************
PRODUCT MODULE SPR
EDIT EDIT QAR DESCRIPTION
====== ====== ===== ===========
100 8 Dev Make declarations for routine names
be EXTERNAL ROUTINE so RMS will compile
under BLISS V4 (RMT, 10/22/85).
***** END OF REVISION HISTORY *****
])%
%([ FORWARD DECLARATIONS ])%
%([ EXTERNAL DECLARATIONS ])%
EXTERNAL ROUTINE
CRASH, ! INTERNAL ERROR PROCESSOR
GPAGE,
PPAGE,
DUMP; ! DEBUGGING ROUTINE
%([ ERROR MESSAGES REFERENCED IN THIS MODULE ])%
EXTERNAL
! MSGPG0, ! FILE PROLOGUE EXTENDS PAST PAGE 0
MSGINPUT; ! BAD INPUT VALUES
REQUIRE 'RMSREQ';
EXTDECLARATIONS;
! SETPLOG
! =======
! THIS ROUTINE CREATES A FILE PROLOGUE IN FREE CORE
! WHEN A RMS-20 FILE IS INITIALLY CREATED.
! THE PROLOGUE DOES NOT INCLUDE THE END-BLOCK.
! THE PROLOGUE IS NOT WRITTEN OUT TO THE FILE
! UNTIL AFTER THE $CREATE IS DETERMINED TO
! HAVE BEEN SUCCESSFUL.
! THE FILE PROLOGUE IS ALWAYS WRITTEN AT THE ADDRESS
! CONTAINED IN THE GLOBAL VARIABLE "FPT".
!
! INPUT:
! <NONE>
! OUTPUT:
! <NONE>
!
! IMPLICIT INPUTS:
!
! FPT = ADDRESS OF THE FILE PROLOGUE IN CORE
!
! NOTES:
!
! 1. ALL FIELDS IN THE FILE PROLOGUE WHICH ARE COMMON
! FOR ALL FILE ORGANIZATIONS ARE INTIALIZED BY THIS
! ROUTINE. FIELDS WHICH ARE USED ONLY FOR INDEXED
! FILES (AREA, ADBOFFSET, KEYS, IDBOFFSET ), ARE SET
! UP BY THE CORRESPONDING ROUTINE (DOAREABLOCKS OR
! DOKEYBLOCKS) WHEN THE REST OF THE PROLOGUE STRUCTURES
! ARE CREATED. ALL RESERVED FIELDS IN THIS BLOCK
! ARE AUTOMATICALLY ZEROED BECAUSE THE PAGE ON WHICH
! THIS PAGE IS BEING CREATED IS A NEW FILE PAGE.
GLOBAL ROUTINE SETPLOG =
BEGIN
LOCAL
TEMP,
ENDPTR;
MAP
ENDPTR: POINTER;
TRACE ( 'SETPLOG' );
FPT [ BLOCKTYPE ] = FPBLOCK; ! SET FILE CODE
FPT [ BLOCKLENGTH ] = FPTSIZE; ! AND SIZE
FPT [ FPTRFM ] = .FAB [ FABRFM ]; ! RECORD FORMAT
FPT [ FPTBSZ ] = .FAB [ FABBSZ ]; ! BYTE-SIZE
FPT [ FPTBKS ] = .FAB [ FABBKS ]; ! USE BUCKET SIZE IN FAB
FPT [ FPTORG ] = .FAB [ FABORG ]; ! ORGANIZATION
FPT [ FPTRAT ] = .FAB [ FABRAT ]; ! ATTRIBUTES
FPT [ FPTMRS ] = .FAB [ FABMRS ]; ! MAX REC SIZE
FPT [ FPTMRN ] = .FAB [ FABMRN ]; ! MAX FILE SIZE
%([ **NOTE THAT THE NXTBKT FIELD IN THE PROLOGUE IS SET
BY DOKEYBLOCKS, WHEN EACH INDEX DESCRIPTOR BLOCK IS
INITIALLY CREATED. ])%
%([ THE OTHER FIELDS ARE ALREADY CLEAR BECAUSE THIS
IS A NEW FILE PAGE ])%
%([ SET UP THE END BLOCK FOR SEQUENTIAL/RELATIVE FILES ])%
ENDPTR = .FPT + .FPT [ BLOCKLENGTH ]; ! ADJUST NEW POINTER
ENDPTR [ WHOLEWORD ] = ENDBLOCK ^ LEFTLSH + ENDBLOCKSIZE;
GOODRETURN
END; %( OF SETPLOG ROUTINE )%
! IDXFILEPROLOG
! ==============
! THIS ROUTINE IS USED TO CREATE ALL BLOCKS WITHIN
! THE FILE PROLOGUE WHICH ARE UNIQUE TO
! INDEXED FILES. THIS ROUTINE CREATES THE
! FOLLOWING BLOCKS:
! 1) AREA DESCRIPTORS
! 2) INDEX DESCRIPTORS
! INPUT:
! <NONE>
! OUTPUT:
! TRUE: OK
! FALSE: ERROR
! NO FREE PAGES FOUND FOR MULTI-PAGE PROLOGUE
! IMPLICIT INPUTS:
!
! PLOGPAGE PAGE NUMBER OF FREE PAGE WHICH CONTAINS
! THE FIRST PAGE OF THE FILE PROLOGUE.
!
! ROUTINES CALLED:
! DOKEYBLOCKS
! DOAREABLOCKS
GLOBAL ROUTINE IDXFILEPROLOG =
BEGIN
EXTERNAL ROUTINE
DOKEYBLOCKS,
DOAREABLOCKS;
LOCAL
WINDOWNUMBER, ! PAGE NUMBER OF FILE WINDOW
FILEPAGENUMBER; ! NUMBER OF THE FILE PROLOGUE PAGE
EXTERNAL
PLOGPAGE; ! TEMP WINDOW WHICH HOLDS PROLOGUE
TRACE ('INDXFILEPROLOG');
%([ SET UP THE PAGE NUMBER OF THE CURRENT PROLOGUE ])%
FILEPAGENUMBER = ZERO; ! ALWAYS START ON PAGE 0
WINDOWNUMBER = .PLOGPAGE; ! FIND WHERE PROLOGUE IS
%([ CREATE THE AREA DESCRIPTORS ])%
CALDOAREABLOCKS ( RLCI ( WINDOWNUMBER ),
RLCI ( FILEPAGENUMBER ));
%([ CREATE ALL INDEX DESCRIPTOR BLOCKS ])%
RETURN CALLDOKEYBLOCKS (LCI ( WINDOWNUMBER ),
LCI ( FILEPAGENUMBER ))
END;
! DOAREABLOCKS
! ============
! THIS ROUTINE CREATES THE AREA DESCRIPTORS IN THE
! PROLOGUE OF AN INDEXED FILE.
! INPUT:
! WINDOWNUMBER PAGE NUMBER WHERE PROLOGUE IS CURRENTLY MAPPED
! FILEPAGENUMBER FILE PAGE # OF THE FILE PROLOGUE ( ALWAYS 0 )
! OUTPUT:
! <NONE>
! GLOBALS USED:
! <NONE>
GLOBAL ROUTINE DOAREABLOCKS ( WINDOWNUMBER, FILEPAGENUMBER ):NOVALUE =
BEGIN
ARGUMENT (WINDOWNUMBER,REFERENCE); ! PROCESS WINDOW NUMBER
ARGUMENT (FILEPAGENUMBER,REFERENCE); ! PAGE # OF PROLOGUE
REGISTER
MOVINGPTR, ! TEMPORARY POINTER VARIABLE
ADBPTR, ! PTR TO AREA DESCRIPTOR
AREAINDEX, ! INDEX FOR ADB
PROLOGPTR, ! PTR TO FILE PROLOGUE
DEFALTBKZ, ! DEFAULT SIZE OF THE BUCKET
AREACOUNT; ! COUNT OF AREA DESCRIPTORS
LOCAL
XABPTR; ! POINTER TO USER XAB
MAP
PROLOGPTR: POINTER,
MOVINGPTR: POINTER,
ADBPTR: POINTER,
XABPTR: POINTER;
TRACE ( 'DOAREABLOCKS' );
%([ SET UP SOME POINTERS ])%
PROLOGPTR = .WINDOWNUMBER ^ P2W; ! PTR TO WINDOW
ADBPTR = .PROLOGPTR [ BLOCKLENGTH ] + .PROLOGPTR;
%([ CREATE A NULL HEADER FOR THIS BLOCK ])%
ADBPTR [ WHOLEWORD ] = ( ADBCODE ^ BLKTYPELSH );
AREACOUNT = 1; ! START OFF WITH 1 AREA
%([ CREATE THE DEFAULT AREA ])%
DEFALTBKZ = .FAB [ FABBKS ]; ! SET UP DEFAULT BUCKET SIZE
IF .DEFALTBKZ IS ZERO THEN DEFALTBKZ = DEFBUCKETSIZE; ! SET UP DEFAULT
ADBPTR [ .AREACOUNT, ADBBKZ ] = .DEFALTBKZ; ! STORE BKZ IN FIRST ADB
%(NOTE THAT THE AREA ID IS ALREADY 0 SO WE DONT HAVE TO SET IT)%
%([ CREATE AN ENTRY FOR EACH ADB ])%
XABPTR = .FAB [ FABXAB ]; ! GET FIRST XAB
UNTIL .XABPTR IS ZERO
DO
BEGIN
IF .XABPTR [ XABCOD ] IS CODAREA ! DO ONLY FOR AREA ALLOCATION XAB'S
THEN
BEGIN
AREAINDEX = ( .AREACOUNT * AREADESCSIZE ) + 1;
AREACOUNT = .AREACOUNT + 1; ! BUMP THE NUMBER OF AREAS
IF ( ADBPTR [ .AREAINDEX, ADBBKZ ] = .XABPTR [ XABBKZ ])
IS ZERO
THEN %( WE MUST USE THE DEFAULT BUCKET SIZE )%
ADBPTR [ .AREAINDEX, ADBBKZ ] = .DEFALTBKZ
END; %( OF WHILE XABCOD IS CODAREA )%
%([ FETCH ADDRESS OF NEXT XAB IN CHAIN ])%
XABPTR = .XABPTR [ XABNXT ] ! ADVANCE XAB
END; %(OF UNTIL XABPTR IS ZERO)%
%([ FILL IN THE LENGTH OF THE ADB IN THE BLOCK HEADER ])%
ADBPTR [ BLOCKLENGTH ] = (.AREACOUNT * AREADESCSIZE ) + 1; ! PLUS 1 FOR THE HEADER
%([ FILL IN SOME PROLOGUE INFO ABOUT THE ADB ])%
PROLOGPTR [ FPTAREAS ] = .AREACOUNT; ! FILL IN NUMBER OF AREAS
PROLOGPTR [ FPTADB ] = .ADBPTR; ! AND ADDRESS OF ADB OFFSET
RETURN ! NO STATUS RETURN
END; %( OF DOAREABLOCKS )%
! DOKEYBLOCKS
! ===========
! THIS ROUTINE CREATES THE INDEX DESCRIPTORS WHICH ARE PUT
! IN THE PROLOGUE OF AN INDEXED FILE.
! EACH INDEX DESCRIPTOR CONTAINS ALL INFORMATION WHICH
! IS REQUIRED BY RMS-20 TO PROCESS A RECORD
! ACCORDING TO THE PARTICULAR KEY.
!
! THE CHAIN OF INDEX DESCRIPTORS BEGINS IMMEDIATELY FOLLOWING
! THE AREA DESCRIPTORS IN THE FILE PROLOGUE. EACH IDB IS
! LINKED TO THE NEXT ONE.
! INPUT:
! PROCESS PAGE INTO WHICH FILE PROLOGUE IS MAPPED
! FILE PAGE # OF THE FILE PROLOGUE
! OUTPUT:
! TRUE: OK
! FALSE: ERROR
! NO FREE PAGES LEFT FOR MULTI-PAGE PROLOGUE
! GLOBALS USED:
! <NONE>
GLOBAL ROUTINE DOKEYBLOCKS ( WINDOWNUMBER, FILEPAGENUMBER ) =
BEGIN
ARGUMENT (WINDOWNUMBER,VALUE); ! PROCESS PAGE #
ARGUMENT (FILEPAGENUMBER,VALUE); ! PAGE # OF PROLOGUE
EXTERNAL ROUTINE
MAKEIDB;
LOCAL
MULTIPAGEFLAG,
XABPTR,
PROLOGPTR,
IDBPTR,
LASTIDBPTR;
MAP
PROLOGPTR: POINTER,
IDBPTR: POINTER,
XABPTR: POINTER,
LASTIDBPTR: POINTER;
LOCAL IDBCOUNT;
LOCAL IDBLEN; !# OF WDS IN AN IDB
TRACE ( 'DOKEYBLOCKS' );
%([ ASSUME THAT THIS IS A ONE-PAGE PROLOGUE ])%
MULTIPAGEFLAG = FALSE;
%([ SET UP SOME POINTERS ])%
PROLOGPTR = .WINDOWNUMBER ^ P2W;
IDBPTR = .PROLOGPTR [BLOCKLENGTH] + .PROLOGPTR; !HOP OVER FILE DATA
IDBLEN = .IDBPTR [ BLOCKLENGTH ] + .IDBPTR; !HOP OVER AREA BLKS
IDBPTR = .IDBLEN; !OTHWISE BLISS CLOBS IT
LOOKAT ( ' ADDR OF IDB: ',IDBPTR );
%([ MAKE FILE PROLOGUE POINT HERE ])%
PROLOGPTR [ FPTIDB ] = .IDBPTR; ! FILL IN PROLOGUE
IDBCOUNT = ZERO; ! CLEAR KEY COUNTER
LASTIDBPTR = ZERO; ! SHOW THIS IS FIRST
%([ WE WILL NOW SCAN THE XAB CHAIN ])%
XABPTR = .FAB [ FABXAB ]; ! GET CHAIN ADDRESS
UNTIL .XABPTR IS ZERO ! SCAN FOR KEY XAB'S
DO
BEGIN
%([ CHECK IF THIS IS A KEY XAB ])%
IF .XABPTR [ XABCOD ] IS CODKEY
THEN
BEGIN
%([ CREATE AN INDEX DESCRIPTOR BLOCK ])%
CALLMAKEIDB ( %(PTR TO IDB)% LPT ( PROLOGPTR ),
%(INDEX DESC)% LPT ( IDBPTR ),
%(XAB)% LPT ( XABPTR ));
%([ MAKE THIS IDB POINT TO WHERE THE NEXT ONE
IS LIKELY TO GO ])%
IDBLEN = .IDBPTR [BLOCKLENGTH]; !GET AN IDB'S LEN
IDBPTR [ IDBNXT ] = ( .FILEPAGENUMBER ^ P2W )
+ ( (.IDBPTR + .IDBLEN) AND OFSETMASK );
LASTIDBPTR = .IDBPTR; !SAVE FOR POSSIB ALT IDBNXT
INC ( IDBPTR, .IDBLEN); !PT AT NEXT 1
%([ IS THERE ROOM FOR ONE MORE IDB ON THIS PAGE? ])%
IF ( ( .IDBPTR + .IDBLEN ) ^W2P )
ISNT !DOES END GO TO NEXT P?
( .WINDOWNUMBER )
THEN %(YES, WE WILL OVERLAP ONTO THE NEXT PAGE)%
BEGIN
INC ( FILEPAGENUMBER, 1 ); ! GOTO NEXT PAGE
LASTIDBPTR [ IDBNXT ] = .FILEPAGENUMBER ^ P2W;
%([ DO WE NEED A NEW PAGE? ])%
IF .MULTIPAGEFLAG IS FALSE
THEN
BEGIN
MULTIPAGEFLAG = TRUE;
RTRACE(%STRING(' ALLOCATING EXTRA PLOG PAGE...',%CHAR(13),%CHAR(10)));
IF (WINDOWNUMBER = CALLGPAGE ( PCI ( 1 ) )) IS FALSE
THEN RETURN FALSE
END %(OF IF WE NEED NEW PAGE)%
ELSE $CALL (PAGOUT, !FLUSH PREV PG
%(JFN)% .FST[FSTJFN],
%(TO)% .FILEPAGENUMBER-1,
%(FROM)% .WINDOWNUMBER,
%(COUNT)% 1);
%([ NOW, MAP THE NEXT PAGE INTO OUR WINDOW ])%
$CALL (PAGIN,
%(JFN)% .FST[FSTJFN],
%(FROM)% .FILEPAGENUMBER,
%(TO)% .WINDOWNUMBER,
%(ACCESS)% AXUPD,
%(COUNT)% 1);
IDBPTR = .WINDOWNUMBER ^ P2W;
END; %(OF IF WE WENT OVER TO NEXT PAGE)%
IDBCOUNT = .IDBCOUNT + 1 ! BUMP COUNT
END; %(OF IF THIS IS A KEY XAB)%
%([ FETCH THE NEXT XAB IN THE CHAIN ])%
XABPTR = .XABPTR [ XABNXT ] ! GO TO NEXT XAB
END; %( OF WHILE .XABPTR ISNT ZERO )%
%([ CLEAR THE NEXT POINTER IN THE LAST IDB WE MADE ])%
IF .LASTIDBPTR ISNT ZERO THEN LASTIDBPTR [ IDBNXT ] = ZERO;
%([ DID WE ALLOCATE AN EXTRA PAGE FOR THE PROLOGUE ])%
IF .MULTIPAGEFLAG
THEN BEGIN
$CALL (PAGOUT,
%(JFN)% .FST[FSTJFN],
%(TO)% .FILEPAGENUMBER,
%(FROM)% .WINDOWNUMBER,
%(COUNT)% 1);
CALLPPAGE ( VCI ( WINDOWNUMBER ), PCI ( 1 ), PCI ( TRUE ))
END;
%([ WE NOW HAVE CREATED ALL INDEX DESCRIPTORS.
WE MUST STORE THE KEY COUNT
IN THE FILE PROLOGUE ])%
PROLOGPTR [ FPTKEYS ] = .IDBCOUNT;
LOOKAT ( '# OF IDB-S:', IDBCOUNT );
%([ ALSO, RE-SET THE NXTBKT FIELD IF WE HAD A MULTI-PAGE
PROLOGUE ])%
PROLOGPTR [ FPTNXTBKT ] = ( .FILEPAGENUMBER + 1 ) ;
SIZEOFFILE = .PROLOGPTR [FPTNXTBKT] ^ P2W; ![%46] DENOTE PROL IN FILE
$CALL (ADJEOF, .FST[FSTJFN], .SIZEOFFILE, FALSE);
![%46] SET IN CASE $CONN NEV DONE
RETURN TRUE
END; %( OF DOKEYBLOCKS )%
! MAKEIDB
! =======
! THIS ROUTINE CREATES A SINGLE INDEX DESCRIPTOR
! IN THE PROLOGUE OF AN INDEXED FILE. EACH
! DESCRIPTOR COMPLETELY DESCRIBES THE CHARACTERISTICS
! OF A PARTICULAR RECORD KEY. EACH XAB WHICH
! IS USED TO CREATE THESE DESCRIPTORS HAS ALREADY
! BEEN CHECKED FOR ERRORS.
! THE GENERAL STRUCTURE OF AN INDEX DESCRIPTOR IS:
!
! HEADER ( 1 WORD )
! GENERATED INFORMATION ( FIXED-LENGTH )
! USER XAB ( VARIABLE LENGTH )
! KEY NAME ( 6 WORDS )
!
! THE FOLLOWING FIELDS ARE SET UP BY THIS ROUTINE:
! BLOCKTYPE
! BLOCKLENGTH
! LEVELS ( ASSUMED TO BE 0 BECAUSE THIS IS A NEW PAGE )
! ALL FIELDS WHICH ARE FETCHED FROM THE XAB
! KEY-NAME
!
! THE FOLLOWING FIELDS ARE <NOT> SET UP BY THIS ROUTINE AND
! ARE LISTED WITH A DESCRIPTION OF WHO SETS THEM UP:
! ROOT WHEN THE ROOT IS INITIALLY ALLOCATED
! NXTIDB WHEN THE NEXT IDB IS CREATED (BY DOKEYBLOCKS)
! INPUT:
! POINTER TO START OF FILE PROLOGUE
! POINTER TO PLACE TO WRITE IDB
! POINTER TO USER XAB
! OUTPUT:
! <NO STATUS RETURNED>
!
GLOBAL ROUTINE MAKEIDB ( PROLOGPTR, IDBPTR, XABPTR ):NOVALUE =
BEGIN
ARGUMENT (PROLOGPTR,BASEADD); ! PROLOG ADDRESS
ARGUMENT (IDBPTR,BASEADD); ! OUR ADDRESS
ARGUMENT (XABPTR,BASEADD); ! XAB
REGISTER
MOVINGPTR,
SIZEOFXAB,
TEMPAC;
MAP
PROLOGPTR: POINTER,
IDBPTR: POINTER,
XABPTR: POINTER,
MOVINGPTR: POINTER;
LOCAL
TEMP;
MAP
TEMPAC: FORMAT;
TRACE ( 'MAKEIDB' );
%([ SET THE SIZE OF THIS XAB ])%
SIZEOFXAB = .XABPTR [ BLOCKLENGTH ];
%([ FILL IN HEADER OF IDB ])%
IDBPTR [ BLOCKHEADER ] = ( IDBCODE ^ BLKTYPELSH ) + .SIZEOFXAB + IDBSIZE;
%([ WE WILL NOW MOVE THE ENTIRE USER'S
XAB INTO THIS BLOCK. NOTE THAT WE
ASSUME THAT ALL FIELDS ARE INITIALLY ZERO
(SINCE THIS IS A VIRGIN FILE PAGE).
THEREFORE, WE DONT HAVE TO CLEAR ANY FIELDS ])%
MOVINGPTR = .IDBPTR + IDBXABOFFSET; ! POINT TO XAB
%([ MOVE THE ENTIRE XAB INTO THE FILE IDB ])%
MOVEWORDS ( %( FROM )% .XABPTR,
%( TO )% .MOVINGPTR,
%( SIZE )% .SIZEOFXAB );
XABPTR = .MOVINGPTR; ! RESET THE POINTER TO THE NEW XAB POSITION
%([ WE HAVE NOW MOVED THE XAB IN. WE
MUST CHECK IF THERE IS A KEY-KAME
AND, IF SO, MOVE IT TO THIS ADB ])%
IF ( TEMPAC = .XABPTR [ XABKNM ] ) ISNT ZERO
THEN
MOVEWORDS ( %( FROM )% .TEMPAC,
%( TO )% .MOVINGPTR + .SIZEOFXAB,
%( SIZE )% KEYNAMESIZE );
%([ LETS SEE IT ])%
%IF DBUG %THEN
CALLDUMPIDB ( BPT ( IDBPTR ) );
ENDDEBUG;
%FI
RETURN
END; %( OF MAKEIDB )%
! GETIDB
! ======
! ROUTINE TO LOCATE AN INDEX DESCRIPTOR BLOCK IN THE PROLOGUE
! OF AN INDEXED FILE. THIS ROUTINE ASSUMES THAT THE GLOBAL
! "KDB" IS SET TO POINT TO THE CURRENT KEY DESCRIPTOR BLOCK.
! THIS ROUTINE WILL LOCATE THE ASSOCIATED INDEX DESCRIPTOR
! AND RETURN A POINTER TO IT. IT IS THE CALLER'S RESPONSIBILITY
! TO FLUSH THE BUCKET DESCRIPTOR WHICH IS RETURNED.
! NOTES:
!
! 1. LOCKING IS <<NEVER>> DONE FOR THE FILE PROLOGUE
! INPUT:
! BKTDESC ADDRESS OF CALLER'S BUCKET DESCRIPTOR
! OUTPUT:
! FALSE: ERROR
! NOT FALSE: ADDRESS IN CORE OF INDEX DESCRIPTOR
! ROUTINES CALLED:
! GPAGE
GLOBAL ROUTINE GETIDB ( BKTDESC ) =
BEGIN
ARGUMENT (BKTDESC,BASEADD); ! BUCKET DESCRIPTOR
MAP
BKTDESC: POINTER;
EXTERNAL ROUTINE
GETBKT; ! GET A BUCKET
LOCAL
FILEBUCKET: FORMAT; ! BUCKET NUMBER OF THE INDEX DESCRIPTOR
REGISTER
FILEADDRESS, ! ADDRESS OF THE IDB
IDBPTR: POINTER;
TRACE ( 'GETIDB' );
CHECKEXACTCOUNT;
%([ FETCH THE ADDRESS OF THE INDEX DESCRIPTOR ON DISK ])%
FILEADDRESS = .KDB [ KDBIDBADDR ]; ! GET ADDRESS
FILEBUCKET = ( .FILEADDRESS ^ W2P ) ^ P2B; ! CONVERT TO BUCKET NUMBER
%([ GET THE BUCKET WHICH CONTAINS THIS IDB ])%
IF CALLGETBKT ( %(BKT #)% LCI ( FILEBUCKET ),
%(BKZ)% PCI ( 1 ),
%(LOCK FLAG)% PCI ( FALSE ),
%(BKT DESC)% BPT ( BKTDESC ) ) IS FALSE
%([ DID ANYTHING HAPPEN? ])%
THEN RETURN FALSE; ! RETURN FALSE ON ERROR
%([ FORM A IN-CORE POINTER TO THE INDEX DESCRIPTOR ])%
IDBPTR = ( .BKTDESC [ BKDBKTADR ] ) OR ( .FILEADDRESS AND OFSETMASK );
RETURN .IDBPTR
END; %(OF GETIDB)%
END
ELUDOM