Google
 

Trailing-Edge - PDP-10 Archives - cuspbinsrc_2of2_bb-fp63b-sb - 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