MFS PROGRAMMING & USAGE
Published By | Date | Version | Knowledge Level | Keywords |
---|---|---|---|---|
Revelation Technologies | 14 NOV 1989 | 2.X | EXPERT | %RECORDS%, @-variables, @LIST.ACTIVE, @NEXT.FS, sample, program, Next, Aborting, Disabling, Accessing, file+, also, Calling,, Direct, call, different, files, Accounts,, Non-SYSPROG, Arguments, modifying+, names, Assembly, language, Attaching, after, changing, file, handle, installation, using, volume, name, Audit, trail, calling, system, argument, during, FLUSH, INSTALL, BFS,, definition, BFS-bound, Branching+, Btree, index, Buffers, caching, Bypassing, with, direct, calls, Caching, Calling, directly, from, R/BASIC, next, list, CASE, statement, Cataloging, Changing, CLEARSELECT, CODE, Compatibility, Compiling, Compression, CREATE.FILE, CREATE.MEDIA, Current, accessing, Cursors, Data, passing, De-installing, object, code, Debugger, Debugging,during, development, Decryption, Encryption, DELETE.FILE, Detaching, DICT.MFS, Dictionary, problems, with+, current, Direction,READNEXT, function+, Dispatching+, Environmental, Bond, Example |
MFS's - PART VI
Accessing the Advanced Revelation File Name
When executing record-oriented calls such as READ.RECORD and WRITE.RECORD, the MFS does not know the Advanced Revelation file name of the file it is accessing. The only file information available to the MFS at the time is the file handle.
Some MFSs require access to the name of the file as seen by users. For instance, an audit trail MFS will likely wish to stamp the Advanced Revelation file name on entries in the log. Many MFSs must also use the file name, or information based on it, to open and access related files. An example is SI.MFS, which must open the ! file associated with a data file.
Examining the FILES File
There is no simple method to derive the file name from the file handle. One method of fetching the name is to select the FILES file, examining each entry until a match is made on the file handle. In effect, the MFS must execute the equivalent of this R/LIST sentence in order to return the file name:
"SELECT FILES WITH HANDLE = ":HANDLE
This method is acceptable for applications in which performance is not an issue. The FILES file is memory-resident, and a SELECT … READNEXT … READ loop to parse it is not as time-intensive as an equivalent operation against a disk-based file. Nonetheless, applications in which there is much record I/O will suffer unduly using this method.
Modifying the File Handle
A second method is to make the Advanced Revelation file name part of the file handle. This guarantees that the file name is always available whenever the file handle is passed to the MFS.
In this method, the MFS traps the OPEN.FILE call as the BFS is returning the file handle back to R/BASIC. During an OPEN.FILE call, the Advanced Revelation file name is available in the NAME argument. The MFS simply concatenates the file name onto the file handle with a delimiter before returning to the calling program. The R/BASIC program itself is not affected; it merely stores the handle until the next statement requiring it is executed.
When concatenating the two arguments, the MFS should avoid using delimiter characters that might otherwise appear in either argument. Characters to avoid include "!", "_", and "." (all of which frequently appear in the Advanced Revelation file name), as well as subvalue and value marks, which appear in the handle.
When subsequent file handle-oriented calls are made to the MFS, the handle will be returned to the MFS exactly the way the MFS has constructed it. The MFS must then strip the file name from the handle before passing the handle on for further processing.
The following code fragment illustrates how the OPEN.FILE logic might look in an MFS that is tracking the Advanced Revelation file handle:
OPEN.FILE: FS = DELETE(BFS,1,1,1) NEXTFS = FS<1,1,1> CALL @NEXTFS(CODE, FS, HANDLE, NAME, FMC,RECORD, STATUS) * add filename onto front of file handle, * delimit with special character RECORD = NAME:@TM:RECORD RETURN
In this example, the MFS delimits the file name and file handle with a text mark (@TM).
The same MFS uses logic as illustrated below to parse the file name out of the handle for the MFS calls that require a file handle:
* all following labels share the same logic CLEARSELECT: SELECT: READNEXT: READ.RECORD: READO.RECORD: WRITE.RECORD: DELETE.RECORD: LOCK.RECORD: UNLOCK.RECORD: * get clear file name, strip from file handle FILE.NAME = FIELD(HANDLE, @TM , 1) REAL.HANDLE = FIELD(HANDLE, @TM , 2) FS = DELETE(BFS, 1, 1, 1) NEXTFS = FS<1,1,1> CALL @NEXTFS(CODE,FS,REAL.HANDLE,NAME,FMC,RECORD, STATUS) RETURN
Maintaining a File Name Table
Yet another means for tracking the Advanced Revelation file name is for the MFS to maintain a table of file names and handles. This method is useful if the MFS programmer does not wish to carry the filename on the file handle for fear of interfering with other filing systems.
One strategy is to create a labelled common area in the MFS. In a simple scenario, the common area contains two dynamic arrays, one for file names and one for file handles.
When a file is first opened, the MFS traps both the file name and the file handle after the BFS has returned these. The MFS stores the file name in one array, and the file handle in the corresponding location in the second array. When access to the file name is required, the MFS can locate the file handle in its array, and extract the corresponding file name.
Because the file handle can change during a session – for example, if a file has an MFS added and is reattached – the file handle is updated in the labelled common area each time the file is opened.
The following example code fragment illustrates a method to establish the arrays. In this example, the file name is stored as passed to the MFS, in the format filename*account.
COMMON /FILENAME/ FILES.ARRAY,HANDLES.ARRAY (other processing here) OPEN.FILE: * call BFS in order to get file handle FS = DELETE(BFS,1,1,1) NEXTFS = FS<1,1,1> CALL @NEXTFS(CODE, FS, HANDLE, NAME, FMC,RECORD, STATUS) * load handle and file name into labelled common IF STATUS THEN LOCATE NAME IN FILES.ARRAY USING @FM SETTING POS THEN HANDLES.ARRAY<POS> = RECORD END ELSE FILES.ARRAY<-1> = NAME HANDLES.ARRAY<-1> = RECORD END END RETURN
Once the arrays have been established, the MFS can extract the file name at any time that it has the file handle available. The following code fragment illustrates a method by which the READ.RECORD logic might extract the file name:
READ.RECORD: * search handle array to get position LOCATE HANDLE IN HANDLES.ARRAY USING @FM SETTING POS THEN * extract corresponding file name FILE.NAME = FILES.ARRAY<POS> END FS = DELETE(BFS,1,1,1) NEXTFS = FS<1,1,1> CALL @NEXTFS(CODE, FS, HANDLE, NAME,FMC, RECORD, STATUS) RETURN
Locks and Unlocks
In a network environment, an MFS should expect to receive calls that involve record and file locks. As with other aspects of the system, however, an MFS programmer must understand the underlying technology of locking in order to take full advantage of this group of calls.
Lock Semaphores
In order to remain compatible with the variety of networks supported in Advanced Revelation, the system uses a standard protocol for the establishment of locks. This is based on lock semaphores.
When an R/BASIC LOCK statement is executed, the system uses the file handle and record key information (if locking a record) to create a lock semaphore. In order to accommodate all potential network locking schemes, the semaphore is simplified by hashing the file and record information into a reduced eight-byte format.
Local Lock Table
The resulting semaphore is then stored in a lock table local to the workstation. This is done for several reasons.
First, Advanced Revelation supports the capability for programmers to attempt multiple locks on the same record. In trapping these locks locally, the system reduces lock overhead by avoiding extra lock calls made to the network. If a record is already locked by the local station, this can be detected without an additional call to the network.
Second, storing locks locally gives Advanced Revelation the ability to report that a lock has already been set by that station. (This is done by testing STATUS( ) after a lock has failed.) Some networks do not permit a station to lock the same record twice, and do not report back the proper error condition.
Finally, the hashing scheme Advanced Revelation uses to create the semaphores allows the possibility that entirely different file and record combinations can produce the same semaphore. By maintaining a local lock table, Advanced Revelation can detect this and arbitrate conflicts arising from duplicate semaphores. Only non-duplicated semaphores are passed through to the filing system.
A lock is thus processed at two levels. The first is within the system before a call is made to the filing system. Only after the internal lock table has been examined – and only if necessary – is the lock call passed through to the MFS.
As a result, not all lock calls can be trapped at the MFS level. For example, if a station has a record locked, and attempts to lock it again from a different program or level of execution, the MFS will never receive a lock call. Instead, the system will have already detected a conflict based on the local lock table, and will have returned the proper response to R/BASIC.
The same is true of unlock calls. If the system can resolve an unlock call by referencing only the local lock table, it will do so. In these cases, as with the lock calls, the MFS will never receive the unlock call.
If the lock or unlock call does pass through to the MFS and down to the BFS, the filing system will return information about the lock and its status.
Note: Lock information returned by the BFS should never be altered by an MFS, as it will be stored in the local lock table, and be used to coordinate with other locks.