*DECK DB$SR88 
USETEXT MD10CTX 
USETEXT CUGBATX 
USETEXT UTMPTTX 
USETEXT MDBCMTX 
      PROC DB$SR88; 
  
      BEGIN 
 #
* *   DB$SR88 - CREATE PIT ENTRY AND UPDATE VIT  PAGE  1
* *   J. G. SERPA                                DATE  09/29/80 
* *   BOB MCALLESTER - TABLE SEGMENTATION        DATE  03/30/84 
* 
* DC  PURPOSE 
* 
*     CREATE A PERMANENT FILE INFORMATION ENTRY AND UPDATE THE VERSION
*     INFORMATION TABLE TO REFLECT THE CURRENT AREA.
* 
* DC  ENTRY CONDITIONS
* 
*     AREACNT CONTAINS THE NUMBER OF ENTRIES IN THE AREA DIRECTORY. 
*     AREAORD CONTAINS THE ORDINAL OF THE CURRENT AREA IN THE AREA
*     DIRECTORY TABLE.
*     MDPFINFO CONTAINS THE PERMANENT FILE INFORMATION FOR THE CURRENT
*     AREA. 
*     VERSCNT CONTAINS THE NUMBER OF ENTRIES IN THE VERSION DIRECTORY.
* 
* DC  EXIT CONDITIONS 
* 
*     IF THE AREA OR INDEX PF IS NOT UNIQUE, DIAGNOSTIC 137 IS ISSUED.
*     RETURN IS TO DB$NO. 
*     IF THE AREA REQUIRES AN INDEX FILE BUT ONE IS NOT SPECIFIED,
*     DIAGNOSTIC 128 IS ISSUED. 
*     IF THE AREA DOES NOT REQUIRE AN INDEX FILE, BUT ONE IS SPECIFIED, 
*     DIAGNOSTIC 104 IS ISSUED. 
*     IF ANY OF THE LOG OPTIONS AREA SPECIFIED WITHOUT THE APPROPRIATE
*     SCHEMA FILE BEING SPECIFIED, DIAGNOSTIC 140 IS ISSUED.
*     IF RECOVER IS SPECIFIED AT THE AREA LEVEL, BUT BASIC RECOVERY 
*     FILE IS NOT SPECIFIED, DIAGNOSTIC 147 IS ISSUED.
* 
* DC  CALLING ROUTINES
* 
*     DB$SNTX - SYNTAX CRACKER (SYNGEN) 
* 
* DC  CALLED ROUTINES 
* 
# 
      XREF FUNC DB$MDPF B;   # VALIDATE PF UNIQUENESS                  #
      XREF PROC DB$DIAG;     # ISSUE DIAGNOSTICS                       #
      XREF PROC DB$NO;       # SYNTAX TABLE DRIVER -NO- RETURN         #
      XREF PROC DB$RNRD;     # RANDOM READ                             #
      XREF PROC DB$RNRW;     # RANDOM REWRITE                          #
      XREF PROC DB$UAOS;     # ADJUST OFFSET FOR SWAPPED OUT SEGMENTS  #
      XREF PROC DB$UAWS;     # ADJUST WORK SPACE IN MANAGED MEMORY     #
# 
* 
* DC  NON LOCAL VARIABLES MODIFIED
# 
      XREF ARRAY DB$RNFT;;   # FET FOR RANDOM I/O                      #
# 
* DC  DESCRIPTION 
* 
*     IF THE AREA PERMANENT FILE IS NOT UNIQUE (DB$MDPF = FALSE), ISSUE 
*     DIAGNOSTIC 137. 
*     SEARCH THE PERMANENT FILE INFORMATION TABLE (PIT) FOR AN ENTRY
*     THAT IS NOT IN USE. IF NOT FOUND, CALL DB$UAWS TO ADD ENOUGH SPACE
*     TO THE PIT TO ACCOMODATE ONE MORE ENTRY. UPDATE THE VERSION 
*     INFORMATION TABLE ENTRY FOR THIS AREA (VERSION NAME AND PIT 
*     OFFSET). MOVE PERMANENT FILE INFORMATION FROM MDPFINFO TO THE PIT.
*     SET AREA LEVEL FLAGS IN THE PIT. IF THE AREA INFORMATION TABLE
*     ENTRY FOR THIS AREA INDICATES THAT AN INDEX FILE IS REQUIRED BUT
*     ONE IS NOT SPECIFIED, ISSUE DIAGNOSTIC 128. IF NO INDEX FILE IS 
*     REQUIRED, BUT ONE WAS SPECIFIED, ISSUE DIAGNOSTIC 104.
*     IF AN INDEX FILE HAS BEEN SPECIFIED, COPY THE PERMANENT FILE
*     INFORMATION FROM MDPFINFO TO THE PIT. 
*     IF THE LOG BEFORE RECORDS OR LOG AFTER RECORDS FLAGS ARE SET
*     FOR THE AREA, BUT NO JOURNAL LOG FILE HAS BEEN SPECIFIED FOR THE
*     SCHEMA, ISSUE DIAGNOSTIC 140. IF THE LOG BEFORE BLOCKS FLAG IS
*     SET, BUT QUICK RECOVERY FILE HAS NOT BEEN SPECIFIED FOR THE 
*     SCHEMA, ISSUE DIAGNOSTIC 140. 
*     IF THE RECOVER FLAG IS SET, BUT BASIC RECOVERY FILE HAS NOT BEEN
*     SPECIFIED FOR THE SCHEMA, ISSUE DIAGNOSTIC 147. 
*     EXIT IS TO DB$NO. 
* 
 #
  
  
      BASED ARRAY ARINFO [0:0] S(DFMDAIEN);  # AREA INFORMATION TABLE  #
        BEGIN 
*CALL MDARIDCLS                    AREA INFORMATION TABLE 
        END 
  
      BASED ARRAY ARDIR [0:0] S(DFMDADEN);   # AREA DIRECTORY TABLE    #
        BEGIN 
*CALL MDARDDCLS                    AREA DIRECTORY TABLE 
        END 
  
      BASED ARRAY MDSCENTRY [0:0] S(1);  # SCHEMA DIRECTORY TABLE      #
        BEGIN 
*CALL MDSCDDCLS              SCHEMA DIRECTORY TABLE 
        END 
  
      BASED ARRAY VERSDIR [0:0] S(DFMDVDEN);  # VERSION DIRECTORY TABLE#
        BEGIN 
*CALL MDVDTDCLS              VERSION DIRECTORY TABLE
        END 
  
      BASED ARRAY VERINFO [0:0] S(DFMDVIEN); # VERSION INFO TABLE      #
        BEGIN 
*CALL MDVITDCLS              VERSION INFORMATION TABLE
        END 
  
      ITEM ACTENT;                 # ACTIVE ENTRIES IN THE PIT         #
      ITEM BUFLOC;                 # BUFFER LOCATION FOR RANDOM I/O    #
      ITEM BUFOFFSET;              # OFFSET FOR SEGMENTED TABLE        #
      ITEM I;                      # INDEX VARIABLE                    #
      ITEM LENGTH;                 # LENGTH FOR RANDOM I/O             #
      ITEM NEXTSEG;                # NEXT SEGMENT TO BE LOADED         #
      ITEM OFFSETV;                # OFFSET INTO VIT TABLE             #
      ITEM ORIGSEG;                # SEGMENT ORIGINALLY RESIDENT       #
      ITEM PITLENG;                # LENGTH OF PIT                     #
      ITEM PITOFFSET;              # OFFSET INTO PERM FILE INFO TABLE  #
      ITEM PRUNUM;                 # PRU NUMBER FOR RANDOM I/O         #
      ITEM TOTENT;                 # TOTAL ENTRIES IN THE PIT          #
  
  
  
  
#     B E G I N  E X E C U T A B L E  C O D E  F O R  D B $ S R 8 8    #
  
  
  
      IF NOT DB$MDPF(MDPFINAME[FILETYPE"AREA"], 
          MDPFUNID[FILETYPE"AREA"],MDPFSNPN[FILETYPE"AREA"])
      THEN
        BEGIN 
        DB$DIAG(137,AREANAM);      # AREA PF IS NOT UNIQUE             #
        END 
      IF MDPFINAME[FILETYPE"INDEX"] NQ 0    # IF INDEX FILE SPECIFIED  #
      THEN
        BEGIN 
        ARINDEX[0] = TRUE;         # SET INDEX FILE SPECIFIED FLAG     #
        IF NOT DB$MDPF(MDPFINAME[FILETYPE"INDEX"],
                 MDPFUNID[FILETYPE"INDEX"],MDPFSNPN[FILETYPE"INDEX"]) 
        THEN
          BEGIN 
          DB$DIAG(137,MDPFINAME[FILETYPE"INDEX"]);  # PF NOT UNIQUE    #
          END 
        END 
      P<TLC> = B<42,18>PITBP; 
      P<PFINFO> = B<42,18>PITBP + TLCHLEN[0];  # POSITION PIT HEADER   #
      TOTENT = MDPITTOTENT[0];
      PITLENG = MDPITTOTENT[0] * DFMDPITEN; # LENGTH OF PIT            #
      ACTENT = MDPITACTENT[0];
      MDPITACTENT[0] = MDPITACTENT[0] + 1;  # TOTAL ACTIVE ENTRIES     #
      P<PFINFO> = LOC(PFINFO) + DFPITHDR;   # RELOCATE PIT             #
      IF ACTENT LS TOTENT 
      THEN
        BEGIN 
        ORIGSEG = TLCDSOR[0]; 
        PITOFFSET = DFPITHDR; 
        IF ORIGSEG NQ 0 
        THEN
          BEGIN 
          PITOFFSET = DFPITHDR + (TLCDSWL[0] * (ORIGSEG - DFTLCHL));
          END 
        FOR PITOFFSET = PITOFFSET 
          STEP DFMDPITEN           # STEP THROUGH THE PIT UNTIL        #
          WHILE PITOFFSET LQ PITLENG  # THE END OF THE PIT             #
            AND MDPITUSEF[0]       # OR AN AVAILABLE ENTRY IS FOUND    #
        DO
          BEGIN 
          P<PFINFO> = LOC(PFINFO) + DFMDPITEN; # POSITION TO NEXT PIT  #
  
          IF ORIGSEG NQ 0          # IF THERE ARE ANY DISK SEGMENTS    #
            AND LOC(PFINFO) GQ LOC(TLC) 
                + TLCHLEN[0] + TLCDSBW[0] + TLCDSWL[0]
          THEN                    # IT IS THE END OF THIS DISK SEGMENT #
  
            BEGIN                 # DO A CIRCULAR SCAN OF THE SEGMENTS #
            NEXTSEG = TLCDSOR[0] +1;
            IF NEXTSEG EQ TLCHLEN[0]
            THEN                   # AT THE LAST SEGMENT               #
              BEGIN                # GO TO THE FIRST SEGMENT           #
              NEXTSEG = DFTLCHL;
              PITOFFSET = DFPITHDR - DFMDPITEN; 
              END 
            IF NEXTSEG EQ ORIGSEG  # IF THE NEXT IS THE ORIGINAL       #
            THEN                   # ALL SEGMENTS HAVE BEEN SEARCHED   #
              BEGIN                # EXCEPT THE BUILD SEGMENT          #
              P<PFINFO> = LOC(TLC) + TLCHLEN[0] + TLCBSBW[0]; 
              PITOFFSET = DFPITHDR - DFMDPITEN
                            + (TLCDSWL[0] * (TLCHLEN[0] - DFTLCHL));
              ORIGSEG = 0;
              TEST PITOFFSET;      # CONTINUE SCAN IN THE BUILD SEGMENT#
  
              END 
                                   # SWAP IN THE NEXT SEGMENT          #
            BUFLOC = LOC(TLC) + TLCHLEN[0] + TLCDSBW[0];
            P<PFINFO> = BUFLOC; 
            IF TLCDSMF[0]          # IF THE MODIFIED FLAG IS SET       #
            THEN                   # REWRITE THE RESIDENT SEGMENT      #
              BEGIN 
              LENGTH = TLCSLEN[TLCDSOR[0]]; 
              PRUNUM = TLCSPRU[TLCDSOR[0]]; 
              TLCDSMF[0] = FALSE; 
              DB$RNRW(LOC(DB$RNFT),BUFLOC,LENGTH,PRUNUM); 
              END 
                                   # READ IN THE NEW SEGMENT           #
            LENGTH = TLCSLEN[NEXTSEG];
            PRUNUM = TLCSPRU[NEXTSEG];
            DB$RNRD(LOC(DB$RNFT),BUFLOC,LENGTH,PRUNUM); 
            TLCDSOR[0] = NEXTSEG; 
            TLCDSWL[0] = TLCSLEN[NEXTSEG];
            END 
          END 
        IF ORIGSEG NQ 0 
        THEN
          BEGIN 
          TLCDSMF[0] = TRUE;       # SET SEGMENT MODIFIED FLAG         #
          END 
        END 
      ELSE                         # SKIP THE SEARCH, ALL ARE ACTIVE   #
        BEGIN 
        PITOFFSET = PITLENG + DFPITHDR; 
        P<PFINFO> = LOC(TLC) + TLCHLEN[0] + TLCUSED[0]; 
        END 
      BUFOFFSET = LOC(PFINFO) - B<42,18>PITBP;
      IF PITOFFSET GQ PITLENG      # IF AVAILABLE ENTRY NOT FOUND      #
      THEN
        BEGIN 
        DB$UAWS(LOC(PITBP),DFMDPITEN); # ALLOCATE SPACE IN PIT         #
        BUFOFFSET = TLCUSED[0] + TLCHLEN[0] - DFMDPITEN;
        P<PFINFO> = B<42,18>PITBP + TLCHLEN[0];  # POSITION PIT HEADER #
        MDPITTOTENT[0] = MDPITTOTENT[0] + 1;  # UPDATE TOTAL ENTRIES   #
        END 
      P<VERSDIR> = VERDIRBP + 1;   # POSITION VERSION DIR. TABLE       #
      OFFSETV = (VERSCNT -1) * AREACNT * DFMDVIEN;
      P<TLC> = B<42,18>VERINFBP;
      DB$UAOS(OFFSETV); 
      P<VERINFO> = P<TLC> + TLCHLEN[0] + OFFSETV; 
      MDVITNAME[AREAORD-1] = MDVDTNAME[VERSCNT-1];  # SET VERSION NAME #
      MDVITFOFF[AREAORD-1] = PITOFFSET;             # SET PIT OFFSET   #
      P<PFINFO> = B<42,18>PITBP + BUFOFFSET;  # RESTORE PIT ENTRY PNTR #
      MDPITFLAGS[0] = AREAFLAGS[0];       # STORE AREA LEVEL FLAGS     #
      MDPITUSEF[0] = TRUE;                # SET ENTRY IN USE FLAG      #
      MDPITNOVER[0] = 1;                  # SET NUMBER OF VERSIONS     #
      P<GETENTRY> = LOC(MDPFWORD[FILETYPE"AREA"]);
      P<PUTENTRY> = LOC(MDPITPFINFO[0]);
      FOR I = 0 STEP 1
        UNTIL DFPFENTLEN - 1
      DO
        BEGIN 
        PUTINT[I] = GETINT[I];
        END 
      P<ARDIR> = ARDIRBP + 1 + DFMDADCW + (AREAORD - 1) * DFMDADEN; 
      MDADNPFN[0] = MDADNPFN[0] + 1;       # INCREMENT NUMBER OF PFNS  #
      P<ARINFO> = ARINFOBP + 1 + (AREAORD - 1) * DFMDAIEN;
      IF MDAIINDX[0]                  # IF INDEX FILE EXISTS           #
      THEN
        BEGIN 
  
#     MOVE INDEX PERMANENT FILE INFORMATION FROM MDPFINFO TO THE       #
#     PERMANENT FILE INFORMATION TABLE.                                #
        P<PUTENTRY> = LOC(MDPITXNINFO[0]);
        P<GETENTRY> = LOC(MDPFWORD[FILETYPE"INDEX"]); 
        FOR I = 0 STEP 1
          UNTIL DFPFENTLEN - 1
        DO
          BEGIN 
          PUTINT[I] = GETINT[I];
          END 
        END 
      P<ARINFO> = ARINFOBP + 1 + (AREAORD - 1) * DFMDAIEN;
  
#     CHECK AREA INFORMATION TABLE ENTRY FLAGS AGAINST PERMANENT FILE  #
#     INFORMATION TABLE ENTRY FLAGS. ANY DISCREPANCY IN INDEX FILE     #
#     INFORMATION WILL BE DIAGNOSED.                                   #
  
      IF MDAIINDX[0]               # IF AREA REQUIRES AN INDEX FILE    #
        AND NOT ARINDEX[0]         # BUT NO INDEX FILE SPECIFIED       #
      THEN
        BEGIN 
        DB$DIAG(128,AREANAM);      # ISSUE DIAGNOSTIC                  #
        END 
      IF NOT MDAIINDX[0]           # IF AREA DOES NOT REQUIRE AN INDEX# 
        AND ARINDEX[0]             # FILE, BUT ONE IS SPECIFIED        #
      THEN
        BEGIN 
        DB$DIAG(104,AREANAM);      # ISSUE DIAGNOSTIC                  #
        END 
  
#     CHECK LOG OPTION FLAGS. DISCREPANCIES WILL BE DIAGNOSED          #
  
      P<MDSCENTRY> = SCDRBP + 1;   # POSITION SCHEMA DIRECTORY TABLE   #
      IF ((MDAILGBR[0]             # IF LOG BEFORE RECORDS             #
           OR MDAILGAR[0])         # OR LOG AFTER RECORDS              #
          AND NOT MDSCJLFG[SCHDIRP]) # AND JOURNAL LOG NOT SELECTED    #
        OR (MDAILGBB[0]            # OR LOG BEFORE BLOCKS              #
            AND NOT MDSCQRFG[SCHDIRP])  # AND QRF NOT SELECTED         #
      THEN
        BEGIN 
        DB$DIAG(140,AREANAM);      # ISSUE DIAGNOSTIC                  #
        END 
      IF MDAIRECV[0]               # IF RECOVER SPECIFIED              #
        AND NOT MDSCBRFG[SCHDIRP]  # BUT NO BRF HAS BEEN SELECTED      #
      THEN
        BEGIN 
        DB$DIAG(147,AREANAM);      # ISSUE DIAGNOSTIC                  #
        END 
      DB$NO;
  
      END 
      TERM
