Trailing-Edge
-
PDP-10 Archives
-
RMS-10_T10_704_FT2_880425
-
10,7/rms10/rmssrc/rmsixm.b36
There are 6 other files named rmsixm.b36 in the archive. Click here to see a list.
MODULE IDX2 =
BEGIN
GLOBAL BIND IX2V = 1^24 + 0^18 + 4; !EDIT DATE: 8-MAR-77
%([
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
AUTHOR: S. BLOUNT
THIS MODULE CONTAINS ROUTINES WHICH MANIPULATE AND
ACCESS THE INDEX STRUCTURE OF AN INDEXED FILE. THE
ROUTINES CONTAINED IN THIS MODULE GENERALLY ARE LESS
USED THAN THE ONES IN "RMSIDX". THUS, THIS MODULE CAN
BE SELECTIVELY LOADED WITH OTHER MODULES WHICH ARE NOT
COMMONLY EXECUTED ( E.G., ERROR PROCESSING, DEBUGGING
ROUTINES, ETC ).
********** TABLE OF CONTENTS **************
ROUTINE FUNCTION
======= ========
MAKIDX CREATE AN INDEX STRUCTURE FOR A KEY
ALCROOT ALLOCATE A ROOT FOR AN INDEX
MAKROOT CREATE NEW ROOT ON ROOT SPLIT
ADJIPTR ADJUST THE INDEX POINTER FOR INDEX UPDATE
REVISION HISTORY:
EDIT DATE WHO PURPOSE
==== ==== === =======
1 29-SEP-76 SB UPDATE IDB LEVELS ON ROOT SPLIT
2 23-FEB-77 SB SET HIKEY FLAG IN INDEX RECORD
3 8-MAR-77 SB TAKE OUR BUG MSG IN ALCROOT
*************************************************
* *
* NEW REVISION HISTORY *
* *
*************************************************
****************** Start RMS-10 V1.1 *********************
********************* TOPS-10 ONLY ***********************
PRODUCT MODULE SPR
EDIT EDIT QAR DESCRIPTION
====== ====== ===== ===========
100 4 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 ])%
FORWARD ROUTINE ALCROOT; ! ALLOCATE A ROOT
%([ EXTERNAL DECLARATIONS ])%
EXTERNAL ROUTINE
ALCBKT, ! GET A DATA BUCKET
CRASH, ! DEBUGGING
GETIDB, ! READ THE INDEX DESCRIPTOR
DUMP, ! SAME
DUMPHEADER, ! DUMP THE BUCKET HEADER
! DUMPIRECORD, ! DUMP AN INDEX RECORD
MAKEIRECORD, ! MAKE AN INDEX RECORD
PUTBKT; ! PUT A BUCKET
%([ ERROR MESSAGES REFERENCED IN THIS MODULE ])%
EXTERNAL
MSGINPUT, ! BAD INPUT
MSGFAILURE; ! ROUTINE FAILED
REQUIRE 'RMSREQ';
EXTDECLARATIONS;
! MAKIDX
! =========
! ROUTINE TO INITIALIZE THE INDEX STRUCTURE FOR A SPECIFIC KEY.
! THIS ROUTINE PERFORMS THE FOLLOWING FUNCTIONS:
! 1. ALLOCATE AND FORMAT A ROOT BUCKET
! 2. UPDATE THE ROOT POINTER IN THE INDEX DESCRIPTOR
! IN THE FILE PROLOGUE, AND IN THE IN-CORE
! KEY DESCRIPTOR BLOCK
! 3. ALLOCATE AND FORMAT A NEW DATA BUCKET AND
! UPDATE THE POINTER IN THE PROLOGUE TO IT.
! 4. CREATE A SINGLE INDEX RECORD WHICH CONTAINS
! THE HIGHEST KEY VALUE POSSIBLE.
! INPUT:
! <NONE>
!
! ON INPUT, KDB MUST BE SET UP TO POINT TO THE KEY DESCRIPTOR
! BLOCK OF THE KEY.
! OUTPUT:
! TRUE: OK
! FALSE: ERROR
! <NONE>
! ROUTINES CALLED:
! ALCBKT
! ALCROOT
! DUMPIRECORD
! DUMP
! CRASH
GLOBAL ROUTINE MAKIDX =
BEGIN
LOCAL
DATABD: FORMATS[ BDSIZE ], ! BUCKET DESCRIPTOR FOR DATA BUCKET
ROOTBD: FORMATS[ BDSIZE ], ! BUCKET DESCRIPTOR FOR ROOT
DATAPTR: POINTER, ! PTR TO DATA BUCKET
ROOTPTR: POINTER, ! PTR TO ROOT BUCKET
IRECORDPTR: POINTER, ! PTR TO INDEX RECORD
ROOTBUCKET, ! BUCKET FOR INDEX ROOT
DATABUCKET; ! THE BUCKET NUMBER OF THE DATA
%([ VALUE OF THE HIGHEST KEY POSSIBLE...SEE NOTE BELOW ])%
LITERAL HIKEYVALUE = -1;
TRACE ( 'MAKIDX' );
%([ CHECK INPUT VALUES...JUST CHECK THE KDB POINTER ])%
CHECKINPUT (KDB,NEQ,ZERO);
CHECKEXACTCOUNT;
%([ ALLOCATE A ROOT BUCKET ])%
IF CALLALCROOT (%(LEVEL)% PCI ( SEQSETLEVEL ),
%(BKT-DESC)% LCT ( ROOTBD )) IS FALSE
THEN
RETURN FALSE;
%([ ALLOCATE A NEW DATA BUCKET ])%
IF CALLALCBKT (%(TYPE)% PCI ( BTYPEDATA ),
%(FLAGS)% PCI ( BHFLGEND ), ! END OF CHAIN
%(LEVEL)% PCI ( DATALEVEL ),
%(BKT-DESC)% LCT ( DATABD )) IS FALSE
THEN
RMSBUG ( MSGFAILURE );
%([ FORM A POINTER TO THIS BUCKET ])%
DATABUCKET = .DATABD [ BKDBKTNO ];
DATAPTR = .DATABD [ BKDBKTADR ];
DATAPTR [ BHNEXTBKT ] = .DATABUCKET; ! POINT TO ITSELF
%([ FORM A POINTER TO THE ROOT ])%
ROOTBUCKET = .ROOTBD [ BKDBKTNO ]; ! GET BKT # OF ROOT
ROOTPTR = .ROOTBD [ BKDBKTADR ];
%([ SET UP A PTR TO WHERE THE RECORD IS TO GO ])%
IRECORDPTR = .ROOTPTR + BHHDRSIZE;
%([ CREATE AN INDEX RECORD ])%
IRECORDPTR [ IRFLAGS ] = FLGHIKEY; ! SET HIGHEST KEY
IRECORDPTR [ IRBUCKET ] = .DATABUCKET;
INC ( IRECORDPTR, 1 );
%([ NOW, WE MUST CREATE A INDEX RECORD WITH THE HIGHEST
POSSIBLE KEY VALUE, WHICH IS -1. NOTE THAT THIS VALUE
MAY CAUSE PROBLEMS WHEN COMP KEYS ARE SUPPORTED. THUS,
IF AND WHEN THIS IS TRUE, A SPECIAL CHECK MAY HAVE TO
BE MADE FOR THESE KEY TYPES. ALSO, THE "FLGHIKEY" CAN
ALWAYS BE USED TO DETERMINE IF THIS IS THE SPECIAL
TYPE OF INDEX RECORD ])%
INCR J FROM 1 TO .KDB [ KDBKSZW ]
DO %(ONCE FOR EACH WORD OF THE KEY)%
BEGIN
IRECORDPTR [ WHOLEWORD ] = HIKEYVALUE; ! STORE THE HIGHEST POSSIBLE KEY
INC ( IRECORDPTR, 1 )
END; %(OF INCR LOOP)%
%([ RESET THE END-POINTER ])%
ROOTPTR [ BHNEXTBYTE ] = .IRECORDPTR - .ROOTPTR;
%([ RELEASE BOTH BUCKETS ])%
CALLPUTBKT ( %(UPDATE)% PCI ( TRUE ),
%(BKT-DESC)% LCT ( DATABD ) );
CALLPUTBKT ( %(UPDATE)% PCI ( TRUE ),
%(BKT-DESC)% LCT ( ROOTBD ) );
GOODRETURN
END; %(OF MAKIDX)%
! ALCROOT
! =========
! ROUTINE TO ALLOCATE A NEW ROOT FOR A PARTICULAR INDEX.
! THIS ROUTINE ALLOCATES A NEW ROOT, FORMATS IT,
! AND UPDATES THE ROOT BUCKET POINTER IN THE INDEX
! DESCRIPTOR BLOCK IN THE FILE PROLOGUE. IT ALSO
! UPDATES THE ROOT BUCKET NUMBER IN THE CURRENT
! IN-CORE KEY DESCRIPTOR BLOCK (POINTED TO BY KDB).
! INPUT:
! LEVEL = LEVEL # OF NEW ROOT
! ROOTBD = BUCKET DESCRIPTOR OF NEW ROOT (RETURNED)
! OUTPUT:
! TRUE: OK
! FALSE: ERROR
! ROOT HAS ALREADY BEEN CREATED
! NO BUCKETS LEFT IN FILE
! NOTES:
! 1. THE ROOT IS <NOT> WRITTEN OUT TO THE FILE
! IN THIS ROUTINE. THE CALLER IS RESPONSIBLE
! FOR DOING SO.
! ROUTINES CALLED:
! ALCBKT
! GETIDB
! DUMP
GLOBAL ROUTINE ALCROOT ( LEVEL, ROOTBD ) =
BEGIN
ARGUMENT (LEVEL,VALUE); ! LEVEL NUMBER
ARGUMENT (ROOTBD,BASEADD); ! NEW BUCKET BESC
LOCAL
IDBPTR: POINTER, ! PTR TO INDEX DESCRIPTOR
SAVESTATUS, ! USED TO SAVE STATUS
PLOGBKTDESC: FORMATS[ BDSIZE ]; ! BKT DESC OF PROLOGUE
REGISTER
ROOTPTR: POINTER;
MAP
ROOTBD: POINTER;
CHECKEXACTCOUNT;
TRACE ( 'ALCROOT' );
%([ FIRST, WE MUST FIND THE INDEX DESCRIPTOR ON DISK
AND MAKE SURE THAT A ROOT HAS NOT BEEN CREATED
SINCE WE OPENED THE FILE. ])%
IF ( IDBPTR = CALLGETIDB ( LCT (PLOGBKTDESC ) ) ) IS FALSE
THEN
RETURN FALSE;
%([ IS THERE NOW A ROOT ])%
IF .IDBPTR [ IDBROOT ] ISNT ZERO
THEN %(THERE IS A NEW ROOT)%
SAVESTATUS = FALSE ! REMEMBER WE DIDNT DO IT
ELSE
BEGIN
%([ THERE IS NO ROOT FOR THE FILE. WE MUST ALLOCATE
A NEW ROOT BUCKET ])%
IF CALLALCBKT ( %(TYPE)% PCI ( BTYPEINDEX ),
%(FLAGS)% PCI ( BHFLGROOT+BHFLGEND ),
%(LEVEL)% VCI ( LEVEL ),
%(BKTDESC)% BPT ( ROOTBD )) IS FALSE
THEN
RETURN FALSE;
ROOTPTR = .ROOTBD [ BKDBKTADR ];
IDBPTR [ IDBROOT ] = ( ROOTPTR [ BHNEXTBKT ] = .ROOTBD [ BKDBKTNO ]);
IDBPTR [ IDBLEVELS ] = SEQSETLEVEL; ! SET LEVEL #
SAVESTATUS = TRUE
END; %(OF ELSE THERE IS NO ROOT FOR THE FILE)%
%([ STORE THE NEW ROOT BUCKET # IN THE IDB ])%
KDB [ KDBROOT ] = .IDBPTR [ IDBROOT ] ;
CLRFLAG ( KDB [ KDBFLAGS ], FLGNOINDEX );
%([ RETURN THE BUCKET DESCRIPTOR FOR THE FILE PROLOGUE ])%
CALLPUTBKT ( %(NO UPDATE)% PCI ( FALSE ),
%(DESC)% LCT ( PLOGBKTDESC ) );
RETURN .SAVESTATUS
END; %(OF ALCROOT)%
! MAKROOT
! =======
! ROUTINE TO CREATE A NEW ROOT BUCKET WHEN THE OLD ROOT BUCKET
! SPLITS DUE TO A RECORD INSERTION.
! THIS ROUTINE DOES THE FOLLOWING OPERATIONS:
!
! 1. ALLOCATE NEW BUCKET
! 2. MOVE ALL DATA FROM OLD ROOT INTO THIS BUCKET
! 3. CREATE 2 INDEX RECORDS IN THE OLD ROOT
! 4. WRITE OUT THE NEW BUCKET (WITH DATA IN OLD ROOT)
! INPUT:
! OLDROOTBD BKT DESCRIPTOR OF OLD ROOT
! NEWBKTBD BKT DESCRIPTOR OF NEW BKT IN THE SPLIT
! OUTPUT:
! TRUE: OK
! FALSE: ERROR
! NO MORE BUCKETS
! ROUTINES CALLED:
! MAKEIRECORD
! ALCBKT
! DUMP
! PUTBKT
! GETIDB
GLOBAL ROUTINE MAKROOT ( OLDROOTBD, NEWINDEXBD ) =
BEGIN
ARGUMENT (OLDROOTBD,BASEADD); ! OLD ROOT
ARGUMENT (NEWINDEXBD,BASEADD); ! NEW BUCKET
MAP
OLDROOTBD: POINTER,
NEWINDEXBD: POINTER;
REGISTER
TEMPPTR: POINTER;
LOCAL
NEWBKTBD: FORMATS[ BDSIZE ], ! NEW ROOT DESCRIPTOR
NEWBUCKET, ! NEW ROOT BKT #
BUCKETNUMBER, ! TEMP STORAGE FOR A BUCKET NUMBER
ROOTLEVEL, ! LEVEL OF NEW ROOT
OLDROOTPTR: POINTER, ! SOME POINTERS
NEWBKTPTR: POINTER, ! SAME
INDEXRECORDPTR: POINTER,
SIZEOFKEY, ! SIZE OF THIS KEY STRING
LASTRECORDPTR: POINTER, ! PTR TO LAST REC IN OLD BUCKET
SPLITBKTPTR: POINTER,
PLOGBD: FORMATS[ BDSIZE ], ! DESCRIPTOR FOR PROLOGUE
IDBPTR: POINTER; ! PTR TO INDEX DESCRIPTOR
TRACE ('MAKROOT');
CHECKEXACTCOUNT;
%([ GET SOME POINTERS ])%
OLDROOTPTR = .OLDROOTBD [ BKDBKTADR ];
ROOTLEVEL = .OLDROOTPTR [ BHLEVEL ]; ! AND LEVEL #
%([ ALLOCATE A NEW BUCKET FOR THE NEW ROOT ])%
IF CALLALCBKT ( %(TYPE)% PCI ( BTYPEINDEX ),
%(FLAGS)% PCI ( ZERO ),
%(LEVEL)% LCI ( ROOTLEVEL ),
%(BKT)% LCT ( NEWBKTBD )) IS FALSE
%([ COULD WE ALLCATE A NEW BUCKET? ])%
THEN BADRETURN; ! NO
%([ GET A POINTER TO THE NEW BUCKET ])%
NEWBKTPTR = .NEWBKTBD [ BKDBKTADR ];
NEWBUCKET = .NEWBKTBD [ BKDBKTNO ];
%([ SET UP A POINTER TO WRITE INDEX RECORD ])%
INDEXRECORDPTR = .OLDROOTPTR + BHHDRSIZE;
%([ WE WILL NOW MOVE ALL THE DATA IN THE OLD ROOT INTO
THE BUCKET WHICH WE JUST ALLOCATED. THEN WE WILL
CREATE TWO NEW INDEX ENTRIES IN THE OLD ROOT ])%
MOVEWORDS ( %(FROM)% .OLDROOTPTR,
%(TO)% .NEWBKTPTR,
%(SIZE)% .OLDROOTPTR [ BHNEXTBYTE ] );
%([ SET THE NEXT-BUCKET FIELDS AND RESET THE FLAG FIELD
OF THE OLD ROOT BECAUSE "SPTINDEX" CLEARED THE END
FLAG BIT WHEN IT SPLIT THE INDEX BUCKET ])%
NEWBKTPTR [ BHFLAGS ] = ZERO; ! CLEAR OLD ROOT FLAGS
TEMPPTR = .NEWINDEXBD [ BKDBKTADR ]; ! PTR TO NEW BKT
TEMPPTR [ BHNEXTBKT ] = .NEWBUCKET;
OLDROOTPTR [ BHNEXTBKT ] = .OLDROOTBD [ BKDBKTNO ];
OLDROOTPTR [ BHFLAGS ] = BHFLGROOT + BHFLGEND;
%([ NOW, WE MUST FIND THE LAST INDEX RECORD IN THE OLD ROOT.
WE CAN DO THIS BECAUSE WE KNOW THE SIZE OF EACH INDEX
RECORD, AND WE KNOW WHERE THE BUCKET ENDS. ])%
SIZEOFKEY = .KDB [ KDBKSZW ]; ! SIZE OF KEY PORTION OF INDEX RECORD
LASTRECORDPTR = .NEWBKTPTR + .NEWBKTPTR [ BHNEXTBYTE ] - .SIZEOFKEY;
%([ LASTRECORDPTR NOW POINTS TO THE LAST KEY (NOT THE INDEX
RECORD, BUT THE ACTUAL KEY STRING) IN THE OLD ROOT BUCKET ])%
LOOKAT (' LAST-KEY-PTR: ',LASTRECORDPTR );
BUCKETNUMBER = .NEWBKTBD [ BKDBKTNO ];
%([ CREATE AN INDEX RECORD WHICH DESCRIBES WHAT USED TO BE THE OLD ROOT ])%
CALLMAKEIRECORD ( %(BKT)% LCI ( BUCKETNUMBER ),
%(PLACE)% LPT ( INDEXRECORDPTR ),
%(KEY)% LPT ( LASTRECORDPTR ) );
%([ SET UP TO WRITE NEXT INDEX RECORD ])%
INC ( INDEXRECORDPTR, .SIZEOFKEY + IRHDRSIZE ); ! BUMP PTR
LOOKAT (' NEXT IDX REC AT: ', INDEXRECORDPTR );
SPLITBKTPTR = .NEWINDEXBD [ BKDBKTADR ];
LASTRECORDPTR = .SPLITBKTPTR + .SPLITBKTPTR [ BHNEXTBYTE ] - .SIZEOFKEY;
LOOKAT (' ADR OF LAST KEY IN NEW BKT: ', LASTRECORDPTR );
BUCKETNUMBER = .NEWINDEXBD [ BKDBKTNO ];
%([ CREATE THE SECOND INDEX RECORD ])%
CALLMAKEIRECORD ( %(BKT)% LCI ( BUCKETNUMBER ),
%(PLACE)% LPT ( INDEXRECORDPTR ),
%(KEY)% LPT ( LASTRECORDPTR ) );
%([ RESET THE BUCKET HEADER DATA IN THE NEW ROOT ])%
OLDROOTPTR [ BHNEXTBYTE ] = BHHDRSIZE + ( 2 * ( IRHDRSIZE + .SIZEOFKEY ) );
%([ INCREMENT THE LEVEL NUMBER OF THE OLD ROOT ])%
INC ( OLDROOTPTR [ BHLEVEL ], 1 );
%([ UPDATE THE NUMBER OF LEVELS IN THIS INDEX IN THE
FILE PROLOGUE ])%
IF (IDBPTR = CALLGETIDB ( LCT (PLOGBD ) ) ) ISNT FALSE
THEN %(WE SUCCEEDED)%
BEGIN
IDBPTR [ IDBLEVELS ] = .OLDROOTPTR [ BHLEVEL ];
CALLPUTBKT ( %(NO UPDATE)% PCI ( FALSE ),
%(BKT)% LCT ( PLOGBD ) )
END; %(OF IF GETIDB WAS OK)%
%([ WE MUST NOW WRITE OUT ALL THE BUCKETS WHICH WERE
INVOLVED IN THIS OPERATION. WE HAVE THE FOLLOWING:
OLDROOTBD BKT CONTAINING NEW ROOT
NEWBKTTBD BKT WHICH NOW CONTAINS TOP HALF
OF OLD ROOT (I.E., 1ST BUCKET IN
THE LEVEL UNDER THE ROOT)
NEWINDEXBD BKT WHICH NOW CONTAINS BOTTOM HALF
OF OLD ROOT.
WE MUST WRITE THESE NON-ROOT BUCKETS OUT FIRST TO AVOID
DATA INTEGRITY PROBLEMS. ])%
CALLPUTBKT ( %(UPDATE)% PCI ( TRUE ),
%(SPLIT-BKT)% BPT ( NEWINDEXBD ) );
CALLPUTBKT ( %(UPDATE)% PCI ( TRUE ),
%(NEW ROOT)% LCT ( NEWBKTBD ) );
CALLPUTBKT ( %(UPDATE)% PCI ( TRUE ),
%(ROOT)% BPT ( OLDROOTBD ) );
GOODRETURN
END; %(OF MAKROOT)%
! ADJIPTR ADJUST INDEX POINTER
! =======
! ROUTINE TO ADJUST THE POINTER TO THE CURRENT INDEX RECORD SO AS
! TO CORRECTLY REFLECT THE PLACE WHERE A NEW INDEX RECORD SHOULD
! BE INSERTED. THIS ROUTINE IS CALLED ONLY WHEN THE KEY OF THE
! NEW HIGH RECORD IN A SPLIT BUCKET IS GREATER THAN THE KEY OF
! THE INDEX RECORD DENOTED BY THE PATH ARRAY. THIS IS CAUSED BY
! THE INSERTION OF A DUP WHICH MUST BE PLACED IN A DIFFERENT BUCKET
! FROM THE INITIAL SEARCH BUCKET. (SEE THE NOTES IN "IDXUPDATE" FOR
! A FULL DESCRIPTION OF WHAT'S HAPPENING).
!
! INPUT:
! RECDESC RECORD DESCRIPTOR PACKET
! RECPTR ADDRESS OF CURRENT INDEX RECORD
! USERPTR ADDRESS OF USER SEARCH KEY (NEW HI-KEY VALUE)
!
! INDEXBD BUCKET DESCRIPTOR OF CURRENT BUCKET
!
! OUTPUT:
! <TRUE ALWAYS>
!
! INPUT ARGS MODIFIED:
!
! RECORD DESCRIPTOR:
! RECPTR ADDRESS OF NEW CURRENT INDEX RECORD
!
! BUCKET DESCRIPTOR: NEW BUCKET DESCRIPTOR
GLOBAL ROUTINE ADJIPTR ( RECDESC, INDEXBD ) =
BEGIN
ARGUMENT (RECDESC,BASEADD);
ARGUMENT (INDEXBD,BASEADD);
MAP
RECDESC: POINTER,
INDEXBD: POINTER;
LITERAL NOLOCK = FALSE; ! DONT LOCK NEXT BUCKET
EXTERNAL ROUTINE
SINDEXBKT, ! SEARCH INDEX BUCKET
GTNBKT; ! GET NEXT BUCKET
LOCAL
NEXTBD: FORMATS[ BDSIZE ], ! USE FOR NEXT BUCKET
SAVEDSTATUS; ! TEMP STORAGE
TRACE ('ADJIPTR');
%([ WE NOW WANT TO REPOSITION OURSELVES ACCORDING TO THE HIGHEST
KEY IN THE OLD BUCKET, INSTEAD OF THE KEY OF THE NEW RECORD.
MOST LIKELY, THIS CALL WILL MOVE US DOWN ONE INDEX RECORD ])%
IF CALLSINDEXBKT (%(RD)%BPT ( RECDESC ),
%(BKT)% BPT ( INDEXBD ) ) ISNT FALSE
%([ IF WE SUCCEEDED, THEN WE CAN EXIT ])%
THEN
GOODRETURN;
%([ WE DIDN'T FIND IT. THIS MUST BE THE LAST INDEX RECORD
IN THE BUCKET ])%
RTRACE (' *****COULDNT ADJ I PTR');
SAVEDSTATUS = CALLGTNBKT (%(THIS BKT)% BPT ( INDEXBD ),
%(NEXT BKT)% LCT ( NEXTBD ),
%(NO LOCK)% PCI ( NOLOCK ) );
%([ RELEASE THE OLD ONE, REGARDLESS OF IF WE GOT THE NEXT ONE ])%
CALLPUTBKT ( %(NO UPDATE)% PCI ( FALSE ),
%(BKT)% BPT ( INDEXBD ) );
%([ START SEARCH AT TOP OF NEXT BUCKET ])%
RECDESC [ RDRECPTR ] = ZERO;
IF ( .SAVEDSTATUS IS FALSE )
OR
( CALLSINDEXBKT ( BPT (RECDESC ),
LCT ( NEXTBD ) ) IS FALSE )
THEN %([IF EITHER OF THESE FAILED, WE ARE REALLY SCREWED UP ])%
RMSBUG ( MSGFAILURE );
%([ RESET BUCKET DESCRIPTORS ])%
MOVEBKTDESC ( %(FROM)% NEXTBD, %(TO)% INDEXBD );
GOODRETURN
END;
END
ELUDOM