next up previous contents index
Next: FZFILE - initialize Up: User specifications for Previous: EventsRuns, and

Outline of usage for medium Disk or Tape

Before using FZ, the routines MZEBRA and MZSTOR must have been called. FZ uses the system division of the primary store to hold the control-information about all its files. One bank per file is used, containing the parameters of the file, the statistics of usage of the file, and also the physical record buffer, if the file format is 'exchange'.

Initialization

Before using a particular file, it should be opened, normally with the Fortran OPEN statement or with the C interface routine CFOPEN (except for files which are read/written by special machine-dependent packages, such as IOPACK on IBM). The ZEBRA handling of this file must be initialized by calling FZFILE.

Machine-dependent details about opening files are given in chapter gif.

The call to FZFILE specifies the properties of the file and the processing direction, for example:

    CALL FZFILE (LUN,0,'.')    native mode, input only, disk file

    CALL FZFILE (LUN,0,'IO')   native mode, disk file,
                               input-output or output-input,

    CALL FZFILE (LUN,0,'XO')   exchange mode, output only, disk file

    CALL FZFILE (LUN,0,'D')    exchange mode, input only, disk file
                               reading with direct-access Fortran

    CALL FZFILE (LUN,0,'TL')   exchange mode, input only,
                               tape file to be read via the C Library
Note that the Fortran systems on some Unix machines, like on Sun or Silicon Graphics, are not capable of handling fixed-length records in sequential mode, ie. RECORDTYPE='FIXED' is not available in their Fortran OPEN statement. In this case one has to use the direct-access mode, or the C library mode, of FZ for exchange format files.

If one is debugging a program, it can be useful to set the logging level of FZ for this file to 2 with

      CALL FZLOGL (LUN,2)
causing FZ to print a log message whenever it is called for this file.

Input

To simply read the next data-structure, one calls for example with:

      PARAMETER   (NUHMAX=100)
      DIMENSION    IUHEAD(NUHMAX)
      COMMON /QUEST/IQUEST(100)

      NUH = NUHMAX
      CALL FZIN (LUN, IXDIV, LSUP,JBIAS, '.', NUH,IUHEAD)
      IF (IQUEST(1).NE.0)    GO TO special
This will read the next d/s into the division indicated by IXDIV, it will transfer the user-header-vector into IUHEAD*, NUHMAX words at most, returning in *NUH* its useful size. It will connect the d/s read into a higher level d/s (if any) according to the parameters !LSUP and JBIAS, which have the same significance as with MZLIFT or ZSHUNT.

On normal completion FZIN returns IQUEST(1)=0; a positive value indicates an exception, like Start-of-run or End-of-data; a negative value signals trouble. IQUEST(1) must be tested after every call to FZIN.

Frequently one is interested in processing only a particular kind of data-structure, wanting to rapidly skip any others which might be on the file. To make this possible the data must be organised to contain all the information relevant to selection in the user header vector, because one can ask FZIN to start the d/s by reading the pilot information only, delivering the user header vector to the caller, leaving the bank-material in suspense, waiting for a decision. If the d/s is to be rejected, all the work of bringing it into memory with adjustment of the links can be saved.

To get the user header vector of the next d/s one specifies the S option (Select) in a first call to FZIN; a second call with the A option will transfer the d/s to memory, for example:

C--       Ready to select next d/s

   11 NUH = NUHMAX
      CALL FZIN (LUN, IXDIV, 0,0, 'S', NUH,IUHEAD)
      IF (IQUEST(1).NE.0)    GO TO special
      IF (not wanted)        GO TO 11

C--       Accept pending D/S

      CALL FZIN (LUN, IXDIV, LSUP,JBIAS, 'A', 0,0)
      IF (IQUEST(1).NE.0)    GO TO special
Whilst accepting is done by an explicit call with the A option, rejection is done implicitly by asking for the next d/s.

Having reached the end of the input file (or having decided to stop input for some other reason), one can get the statistics of file usage printed by

      CALL FZENDI (LUN,option)
'option' indicates the further action to be taken on this file, such as REWIND and re-start reading from the beginning, or start writing on the file positioned by reading it, or simply terminate.

Beware: for exchange format files one can switch from input to output only after having read an end-of-run or end-of-file.

If one wants to read several different files on the same logical unit number (thereby possibly saving I/O buffers in the system), this can be done as indicated by this sketch, provided all the files have the same characteristics:

      OPEN (LUN,FILE=<file 1>,...)
      CALL FZFILE (LUN,0,opt)
         read first file
      CALL FZENDI (LUN,'NX')            new file to be connected

      OPEN (LUN,FILE=<file 2>,...)
         read second file
      CALL FZENDI (LUN,'NX')

      OPEN (LUN,FILE=<file 3>,...)
         read third file
            . . . . .
If the files are not of the same kind, for example if the first file is in native mode and the second file is in exchange mode, FZENDI must be told to forget all about the first file, so that a new file can be started on the same logical unit number, for example:
      OPEN (LUN,FILE=<file 1>,...)
      CALL FZFILE (LUN,0,'.')           native mode
         read first file
      CALL FZENDI (LUN,'TX')            terminate

      OPEN (LUN,FILE=<file 2>,...)
      CALL FZFILE (LUN,0,'X')           exchange mode
         read second file
      CALL FZENDI (LUN,'TX')
(This is necessary because the size and character of the FZ control bank depends on the nature of the file.)

Output

It may be desirable to group the output into 'runs', in which case one would start a new run with, for example:

      JRUN = run number
         . . .
      CALL FZRUN (LUN,JRUN,0,0)
It is possible to store user information into the 'start-of-run' record via the last two parameters of the call. There is however the danger, if this information is essential for the processing of the data of the run, that the start-of-run record may get lost due to read errors.

(An end-of-run record can be requested explicitly, but normally this is not necessary, since it is triggered by a new run, or by FZENDO.)

To ouput a d/s from the primary store, supported by the bank at !LHEAD, together with a user header vector in IUHEAD of NUH integer words, one may call:

      CALL FZOUT (LUN,0,LHEAD,0,'L',2,NUH,IUHEAD)
In this case, the material to be output is defined solely by the entry address !LHEAD into the d/s. Therefore FZOUT has to do a logical walk through the complete d/s by following all the structural links, to mark all the banks belonging to this d/s. A subsequent sequential scan over the memory constructs the table of the memory regions to be output. For a large d/s the time spent on this operation may be non-negligible; it can be saved if the user has organized his data such that the d/s to be output resides in a separate division (or divisions) of which it has exclusive use. In this case one can instruct FZOUT to simply output the complete division IXDIV (or divisions IXDIV1 + IXDIV2), whithout the need for the logical walk, by calling:
    [ IXDIV = MZIXCO (IXDIV1,IXDIV2,0,0) ]

      CALL FZOUT (LUN,IXDIV,LHEAD,0,'D',2,NUH,IUHEAD)
The entry address !LHEAD is still needed, no longer to define the data to be written, but for the receiver to find his way into the d/s read.

Although option 'D' saves the logical walk, FZOUT still has to do the sequential scan of the division[s] to identify the live banks to be written, and the dead banks to be suppressed. If the user knows that there are no dead banks, or that their volume is negligible, he can indicate this to FZOUT with the DI option, causing it to write the complete division[s] as it stands:

      CALL FZOUT (LUN,IXDIV,LHEAD,0,'DI',2,NUH,IUHEAD)

Occasionally the d/s to be written out is not described as easily as assumed above, for example one may want to write a data-structure minus some of its sub-structures. In this case (see section gif) the user may pre-mark the banks to be output and

      CALL FZOUT (LUN,IXDIV,LHEAD,0,'M',2,NUH,IUHEAD)
Output of a file must be terminated, to make sure that the last physical record is transfered from the buffer to the file, for example with:
      CALL FZENDO (LUN,'I')
to re-read the file just written; or with:
      CALL FZENDO (LUN,'TX')
if the program no longer needs this file.

The recommended procedure is to have a standard job-termination routine, called ZEND, normally called from the Main program. This routine is called also from the ZEBRA recovery system in case of abnormal job termination. Into this routine one should include a

      CALL FZENDO (0,'TX')
to terminate all pending output files. However, this call pulls in the non-negligible volume of code for the FZOUT complex, and should hence be present only for programs really using FZOUT.

Writing several different files to the same logical unit can be done in complete analogy to the case of reading; in the examples given above one has to add the 'O' option for FZFILE, and one has to change the calls to FZENDI into calls to FZENDO.



next up previous contents index
Next: FZFILE - initialize Up: User specifications for Previous: EventsRuns, and


Janne Saarela
Mon May 15 08:34:47 METDST 1995