Persistent Variable Storage

Sometimes it is useful for an instance of an SBX to be able to store some data for a subsequent instance of the SBX to be able to use. There are several ways to accomplish this:

•   Pass the data back to the caller in a parameter, and have the caller then pass it back to next invocation of the SBX. The downside of this is that you burden the calling program with caring for data which it otherwise has no use for, reducing the degree of data encapsulation offered by the subroutine.

•   Store the data using COMMON.SBR. This can work for small amounts of data, but one problem here is that COMMON is subject to various global configuration options, which will interfere with the ability to use your SBX in different environments (i.e. reduces portability).

•   Store the data in a file. This avoids both of the issues listed above, but introduces a couple of its own. A minor issue is that storing data in a file is somewhat less efficient than memory based schemes, so might add significantly to the performance overhead of an SBX. A larger one is that in order to allow for each job to have its own inter-SBX storage facility, you’ll probably have to incorporate the job number or name into the storage filename, which means that you might end up creating a large number of files. And since the SBX can’t guarantee that the caller will give the SBX an opportunity to clean up after itself, you might end up littering the disk with files that have no meaning to the application (thus making it hard to know whether they can be deleted or not.) (You could reduce the file count by storing each job’s data as a record within a single file, but this introduces issues associated with maintaining the structure of the file.)

•   Store the data in user memory. This avoids all of the problems above. It doesn’t impose any responsibility on the calling program, assume anything about the environment, or add any disk I/O overhead. And, it is self-cleaning, since user memory modules are automatically deleted when an instance of A-Shell exits. So this would be the recommended method for most cases, provided you can count on A-Shell build 916 or higher. The following excerpt of sample code illustrates the technique.

 

map1 LOCAL'STORAGE             ! variables internal to SBX but needed between calls

   map2 VAR1,S,100             ! arbitrary variables used by the SBX

   map2 VAR2,F,6

   Etc.

map1 MODNAME,S,14,"SBX99.MEM"  ! arbitrary module name

 

!  To save the data in LOCAL'STORAGE for a subsequent instance of this SBX...

      xcall MIAMEX, MX_USRLOD, idx, modname, usrmem'nofile, local'storage

      if IDX <= 0 then goto UNABLE'TO'STORE'USRMEM   ! (error)

 

!  To retrieve the data from user memory into LOCAL'STORAGE...

      xcall MIAMEX, MX_USRIO, status, modname, 0, local'storage

 

!  To update the data in the user memory module directly from LOCAL'STORAGE,

!  (without deleting / recreating the module as with MX_USRLOD)...

      xcall MIAMEX, MX_USRIO, status, modname, 1, local'storage

 

!  To delete the module explicitly...

      xcall MIAMEX, MX_USRDEL, idx, modname

 

Prior to build 916, you could still use this strategy but would have to first create a sequential disk file in order to load it into memory. Also note that if you want to protect the module from being deleted inadvertently, you can use FLAGS argument to the MX_USRLOD and MX_USRDEL routines to lock and explicitly unlock the module.