*DECK     DB$FSET 
USETEXT CDCSCTX 
      PROC DB$FSET; 
      BEGIN 
 #
* *   DB$FSET -- SELECT AND SET A FIT            PAGE  1
* *   R L MCALLESTER                             DATE  08/19/86 
* 
* DC  PURPOSE 
* 
*     WHEN A FIT IS EXPECTED TO SUPPORT A SERIES OF AAM CALLS,
*     SUCH AS A SERIES OF GETNR CALLS, A FIT IS SELECTED WHICH CAN
*     HOPEFULLY BE DEDICATED TO THAT SERIES OF CALLS. 
* 
*     RETAINING A FIT THROUGH A SERIES OF SEEK OR GET-NEXT CALLS
*     PERMITS AAM TO RETAIN THE PTREE INFORMATION FOR THE SEQUENCE. 
*     THIS AVOIDS SOME REPOSITIONING LOGIC THAT MIGHT OTHERWISE 
*     BE REQUIRED.
* 
*     WHEN POSSIBLE, A FIT IS SELECTED THAT IS ALREADY IN USE FOR 
*     CURRENT USER. 
*     THAT FIT IS SET FOR THE OPERATION TO BE PERFORMED.
* 
* DC  ENTRY CONDITIONS
* 
*     P<RSB> IS SET.               RUN-UNIT STATUS BLOCK. 
*     P<RSARBLK> IS SET.           RUN-UNIT STATUS BLOCK AREA CONTROL 
*                                  BLOCK. 
*     P<FPT> IS SET.               FILE PARAMETER TABLE.
*     P<TQT> IS SET.               TASK QUEUE TABLE.
*     P<OFT> IS SET.               OPEN FILE TABLE. 
* 
* DC  EXIT CONDITIONS 
* 
*     NORMAL EXIT 
*       UFT HAS BEEN SELECTED AND IS SET UP.
*       P<UFT> IS SET.
*       ENTRY CONDITIONS ARE UNCHANGED. 
* 
*     FPCFPOS VALUES
*         NO CHANGE - 
*           THE UFT THAT THIS JOB LAST USED IS ASSIGNED.
* 
*         TRUE -
*           THE UFT THAT THIS JOB LAST USED IS NOT AVAILABLE. 
* 
* DC  CALLING ROUTINES
* 
*     DB$DEL$    DELETE CONTROL SYMBIONT
*     DB$GETN    A SEQUENTIAL READ
*     DB$REW$    REWRITE CONTROL SYMBIONT 
*     DB$SEK     SEEK A RECORD
*     DB$WR2J    BEFORE IMAGE JOURNAL LOGGING FOR WRITE 
*     DB$WR2K    WRITE AN AK RECORD WITH ZERO KEY VALUE 
* 
* DC  CALLED ROUTINES 
# 
      XREF PROC DB$FLOP;           # IDENTIFY FLOW POINT               #
      XREF PROC DB$PUNT;           # INTERNAL ERROR PROCESSOR          #
# 
* DC  DESCRIPTION 
* 
*     SELECT A FIT TO USE FOR THIS TASK.
*     THE ORDER OF CHOICE IS:   
* 
*         1. THE ONE BEING USED FOR THIS TASK.
*         2. THE OLDEST ONE THAT IS BEING USED SEQUENTIALLY.
* 
*     MARK THE FIT FOR USE BY THIS TQT. 
*     SET UP VARIABLE FIT FIELDS FOR THIS I/O OPERATION.
*     RETURN. 
* 
 #
# 
*     NON-LOCAL VARIABLES 
# 
      XREF ARRAY DB$RA0;
        BEGIN 
        ITEM PRIOR I(00,24,18);    # PRIOR UFT                         #
        ITEM NEXT  I(00,42,18);    # NEXT UFT                          #
        END 
  
  
  
#     E X E C U T A B L E   C O D E   F O R   D B $ F S E T            #
  
  
      IF P<RCB> GR 0
        AND RCOFTLOC[0] NQ LOC(OFT) 
        AND RCOFTLOC[0] NQ 0
      THEN
        BEGIN 
        DB$PUNT("DB$FSET 1"); 
        END 
  
  
#     SELECT A FIT.                                                    #
  
      P<UFT> = FPUFT[0];
      IF P<UFT> LQ 0
        OR P<UFT> GR NEXT [ -NEXT[O"65"] ]
        OR UFTQT[0] NQ LOC(TQT) 
        OR B<0,42>UFFITLFN[0] NQ OFFITLFN[0]
      THEN
                             # A PREVIOUSLY USED FIT IS NOT AVAILABLE  #
        BEGIN 
        P<UFT> = LOC(OFUFT[0]); 
        P<UFT> = UFPRIOR[0];       # SELECT THE OLDEST ONE             #
  
#       MARK THIS UFT FOR USE BY THIS USER.                            #
  
        FPUFT[0] = LOC(UFT);
        UFTQT[0] = LOC(TQT);
        FPCFPOS[0] = TRUE;
  
        CONTROL IFGR DFFLOP,0;
            DB$FLOP("FSET-NA"); 
            END 
          ELSE
                             # THE PREVIOUSLY USED FIT IS AVAILABLE    #
            BEGIN 
            DB$FLOP("FSET-AV"); 
        CONTROL ENDIF;
  
        END 
  
#             IF THE ASSIGNED UFT IS NOT ALREADY LINKED                #
#             IN THE NEWEST POSITION (OR IN THE OFT), RELINK IT.       #
  
#             THE NEWEST UFT IS THE NEXT FROM THE OFT.                 #
#             THE OLDEST UFT IS THE PRIOR FROM THE OFT.                #
  
      IF NEXT[LOC(OFUFT[0])] NQ LOC(UFT)
        AND LOC(OFUFT[0]) NQ LOC(UFT) 
      THEN
        BEGIN 
                             # DELINK UFT FROM OLD POSITION            #
        NEXT[UFPRIOR[0]] = UFNEXT[0]; 
        PRIOR[UFNEXT[0]] = UFPRIOR[0];
                             # LINK IT AS NEXT FROM THE OFT            #
        UFNEXT[0] = NEXT[LOC(OFUFT[0])];
        UFPRIOR[0] = LOC(OFUFT[0]); 
        NEXT[UFPRIOR[0]] = LOC(UFT);
        PRIOR[UFNEXT[0]] = LOC(UFT);
        END 
  
#     SET VARIABLE FIELDS IN THE UFT.                                  #
  
      UFFITES[0] = 0;              # CLEAR ERROR STATUS                #
      UFFITFNF[0] = FALSE;         # NO FATAL ERROR                    #
      UFFITWSA[0] = FPFITWSA[0];   # WORKING STORAGE AREA ADDRESS      #
      UFFITMKL[0] = FPFITMKL[0];   # MAJOR KEY LENGTH                  #
      UFFITKA [0] = FPFITKA [0];   # KEY ADDRESS                       #
      UFFITKEYD[0] = FPFITKEYD[0]; # RKW, RKP, KP AND KL               #
  
      RETURN; 
      END 
      TERM
