*DECK DB$MDPS 
USETEXT MDBCMTX 
USETEXT MDDEFTX 
USETEXT UTMPTTX 
      FUNC DB$MDPS(POINTER,(NEWPFN),(NEWID),(NEWPN)) B; 
      BEGIN 
 #
* *   DB$MDPS - SEARCH THE PFN TABLE             PAGE  1
* *   BOB MCALLESTER                             DATE  07/30/84 
* 
* DC  PURPOSE 
* 
*     SEARCH THE PFN TABLE FOR THE SPECIFIED ENTRY. 
* 
* DC  ENTRY CONDITIONS
* 
* D   PARAMETERS
# 
      ITEM POINTER;          # OUTPUT A POINTER TO THE ENTRY           #
      ITEM NEWPFN;           # PFN NAME, LEFT JUSTIFIED, ZERO FILLED   #
      ITEM NEWID;            # USER ID, LEFT JUSTIFIED, ZERO FILLED    #
      ITEM NEWPN;            # PACK NAME, INCLUDES FLAGS               #
# 
* D   ASSUMPTIONS 
* 
*     NONE
* 
* DC  EXIT CONDITIONS 
* 
*     IF A DUPLICATE IS FOUND - 
*       DB$MDPS IS TRUE.
*       POINTER POINTS TO THE NEXT GREATER ENTRY. 
*     IF A DUPLICATE IS NOT FOUND - 
*       DB$MDPS IS FALSE. 
*       POINTER POINTS TO THE DUPLICATE ENTRY.
* 
* DC  CALLING ROUTINES
* 
*     DB$MDDF                DELETE A PFN ENTRY 
*     DB$MDPF                ADD A PFN ENTRY
*     DB$MDPR                REPLACE A PFN ENTRY
* 
* DC  CALLED ROUTINES 
# 
      XREF PROC DB$MDPG;     # GET THE PFN SEGMENT FROM DISK           #
# 
* DC  NON-LOCAL VARIABLES MODIFIED
* 
*     TLC HEADER IF A NEW DISK SEGMENT IS LOADED. 
* 
* DC  DESCRIPTION 
* 
*     IF THERE IS A DISK SEGMENT INDEX, DO A BINARY SEARCH TO DETERMINE 
*     WHICH SEGMENT IS TO BE SEARCHED FOR THE ENTRY.
*     LOAD THAT SEGMENT IF NECESSARY. 
*     SEARCH THE RESIDENT TABLE FOR THE ENTRY.
 #
# 
*     LOCAL VARIABLES 
# 
      ITEM HIGH;             # HIGH END OF REMAINING SEARCH            #
      ITEM J;                # INDUCTION VARIABLE                      #
      ITEM LOW;              # LOW END OF REMAINING SEARCH             #
      ITEM MIDDLE;           # MIDDLE OF REMAINING SEARCH              #
      ITEM SEGORD;           # ORDINAL OF SEGMENT TO BE SEARCHED       #
  
      BASED ARRAY PFNTABLE; 
          BEGIN 
*CALL MDPFNDCLS 
          END 
  
  
  
#     B E G I N   D B $ M D P S   E X E C U T A B L E   C O D E .      #
  
  
# 
*     SEARCH THROUGH THE PFN TABLE FOR A DUPLICATE PFN
# 
      P<TLC> = B<42,18>PFUNCBBP;
      IF PFXL NQ 0                 # IF THERE IS AN INDEX              #
      THEN                         # DO A BINARY SEARCH OF THE INDEX   #
        BEGIN 
        LOW = 0;
        HIGH = (PFXL / DFPFUNENT) -1; 
        FOR J = J WHILE HIGH GQ LOW 
        DO
          BEGIN 
          MIDDLE = (LOW + HIGH) /2; 
          J = MIDDLE * DFPFUNENT; 
                                   # COMPARE PF NAME                   #
          IF B<0,42>NEWPFN GR PXPFNAME[J] 
          THEN
            BEGIN 
            LOW = MIDDLE +1;
            TEST J; 
  
            END 
          IF B<0,42>NEWPFN LS PXPFNAME[J] 
          THEN
            BEGIN 
            HIGH = MIDDLE -1; 
            TEST J; 
  
            END 
                                   # COMPARE USER NAME/ID              #
          IF B<0,42>NEWID GR PXPFNID[J] 
          THEN
            BEGIN 
            LOW = MIDDLE +1;
            TEST J; 
  
            END 
          IF B<0,42>NEWID LS PXPFNID[J] 
          THEN
            BEGIN 
            HIGH = MIDDLE -1; 
            TEST J; 
  
            END 
                                   # COMPARE PACK/FAMILY/SET           #
  
                             # ONCE AN INDEX VALUE IS ASSIGNED TO AN   #
                             # INDEX, THE VALUE REMAINS EVEN IF THE    #
                             # ENTRY OF THAT VALUE IS DELETED.         #
                             # THEREFORE, WE DONT ACCEPT AN EQUAL      #
                             # COMPARISON AT THIS LEVEL.               #
          IF NEWPN GQ PXPFW3[J] 
          THEN
            BEGIN 
            LOW = MIDDLE +1;
            TEST J; 
  
            END 
          HIGH = MIDDLE -1; 
          TEST J; 
  
          END 
# 
*       ON COMPLETION OF THE BINARY SEARCH OF THE INDEX, "LOW" IS ONE 
*       GREATER THAN "HIGH".
*       THE ENTRY IS TO BE FOUND IN THE SEGMENT IDENTIFIED BY "HIGH". 
*       THE FIRST SEGMENT DOES NOT HAVE AN ENTRY IN THE INDEX, SO THE 
*       ADJUSTMENT FROM INDEX TABLE SUBSCRIPT TO SEGMENT ORDINAL IS 
*       (DFTLCHL +1). 
# 
        SEGORD = HIGH + DFTLCHL +1; 
        DB$MDPG(SEGORD);     # GET SEGMENT TO SEARCH                   #
        END 
# 
*     SET PFN BASED ARRAY TO POINT TO THE FIRST PFN ENTRY 
# 
      P<TLC> = B<42,18>PFUNCBBP;
      P<PFNTABLE> = LOC(TLC) + TLCHLEN[0] + DFMDPFNHD;
# 
*     DO A BINARY SEARCH OF THE RESIDENT PORTION OF THE TABLE.
# 
      LOW = 0;
      HIGH = (TLCDSWL[0] / DFPFUNENT) -1; 
      FOR J = J WHILE HIGH GQ LOW 
      DO
        BEGIN 
        MIDDLE = (LOW + HIGH) /2; 
        J = MIDDLE * DFPFUNENT; 
                                   # COMPARE PF NAME                   #
        IF B<0,42>NEWPFN GR MDPFNAME[J] 
        THEN
          BEGIN 
          LOW = MIDDLE +1;
          TEST J; 
  
          END 
        IF B<0,42>NEWPFN LS MDPFNAME[J] 
        THEN
          BEGIN 
          HIGH = MIDDLE -1; 
          TEST J; 
  
          END 
                                   # COMPARE USER NAME/ID              #
        IF B<0,42>NEWID GR MDPFNID[J] 
        THEN
          BEGIN 
          LOW = MIDDLE +1;
          TEST J; 
  
          END 
        IF B<0,42>NEWID LS MDPFNID[J] 
        THEN
          BEGIN 
          HIGH = MIDDLE -1; 
          TEST J; 
  
          END 
                                   # COMPARE PACK/FAMILY/SET           #
        IF NEWPN GR MDPFN3WRD[J]
        THEN
          BEGIN 
          LOW = MIDDLE +1;
          TEST J; 
  
          END 
        IF NEWPN LS MDPFN3WRD[J]
        THEN
          BEGIN 
          HIGH = MIDDLE -1; 
          TEST J; 
  
          END 
        POINTER = J;
        DB$MDPS = TRUE;            # ENTRY FOUND                       #
        RETURN; 
  
        END 
# 
*     HIGH POINTS TO THE NEXT LOWER ENTRY.
*     LOW POINTS TO THE NEXT GREATER ENTRY. 
*     USE LOW TO RETURN THE POINTER VALUE.
# 
      POINTER = LOW * DFPFUNENT;
      DB$MDPS = FALSE;             # ENTRY NOT FOUND                   #
      END 
      TERM
