As has been illustrated earlier, HDS refers to data objects by means of values held in character variables called locators. Of course, these character values are not HDS data objects themselves; they simply identify the data objects, whose internal details are hidden within the HDS system.
Each locator has a unique value which will not be re-used, and this property makes it possible to tell at any time whether a character value is a valid HDS locator or not. A locator’s validity depends on a number of things, such as its actual value (the value DAT__NOLOC6 is never valid for instance) and the previous history and current state of the HDS system (a locator which refers to a data object which has been deleted will no longer be valid). Note that locator values should not be explicitly altered by applications, as this may also cause them to become invalid.
Locator validity can be determined by using the routine DAT_VALID, which returns a logical value of .TRUE. via its VALID argument if the locator supplied is valid:
This is the only HDS routine to which an invalid locator may be passed without provoking an error.
The number of locators available at any time is quite large, but each locator consumes various computer resources which may be limited, so it is important to ensure that locators are annulled once they have been finished with, i.e. when access to the associated data object is no longer required.
Annulling an HDS locator renders it invalid and resets its value to DAT__NOLOC. It differs from simply setting the locator’s variable to this value, however, because it ensures that all resources associated with it are released and made available for re-use. A locator is annulled using the routine DAT_ANNUL, as follows:
Note that annulling an invalid locator will produce an error, but this will be ignored if the STATUS argument is not set to SAI__OK when DAT_ANNUL is called (i.e. indicating that a previous error has occurred). This means that it is not usually necessary to check whether a locator is valid before annulling it, so long as the only possible reason for it being invalid is a previous error which has set a STATUS value.
Since an HDS locator only refers to a data object and does not itself contain any data values, it is possible to have several locators referring to the same object. A duplicate locator for an HDS object may be derived from an existing one by a process called cloning, which is performed by the routine DAT_CLONE, as follows:
This returns a second locator LOC2 which refers to the same data object as LOC1.
Cloning is not required frequently, but it can occasionally be useful in allowing an application to “hold on” to a data object when a locator is passed to a routine which may annul it; i.e. you simply pass the original locator and keep the cloned copy.
Since data objects are stored in container files, HDS has to decide when to open and close these files (it would be very inefficient if a file had to be opened every time an object within it was referenced). To allow control over this, HDS locators are divided into two classes termed primary and secondary. It is primary locators that are responsible for holding container files open.
To be more specific, an HDS container file will remain open, so that data objects within it are accessible, for as long as there is at least one valid primary locator associated with it (that is, with one of the data objects within the file). Not surprisingly, those routines intended for opening container files (HDS_OPEN, HDS_NEW and HDS_WILD) will return primary locators – so that the file subsequently remains open. However, all other routines return secondary locators (with the exception of DAT_PRMRY, which may be used to manipulate this attribute – see §12.6).
The number of primary locators associated with an HDS container file is called its reference count and may be determined using the DAT_REFCT routine as follows:
Here, LOC is a locator associated with any object in the file and the reference count is returned via the integer REFCT argument. The file will remain open for as long as this value is greater than zero.
Normally, a file’s reference count will fall to zero due to annulling the last primary locator associated with it (usually the locator obtained when the file was originally opened), and at this point the file will be closed. Before this happens, however, any mapped primitive objects within it will be unmapped. In addition, any secondary locators that remain associated with data objects in the same file will be annulled (i.e. they will become invalid).7 No further reference to objects within the file may be made until it has been explicitly re-opened.
A locator may, at any time, be “promoted” to become a primary locator (thus incrementing the container file’s reference count) or “demoted” to become a secondary locator (and decrementing the reference count). This is done by using the DAT_PRMRY routine with its (first) SET argument set to .TRUE., thus:
With its first argument set to .FALSE., the same routine may also be used to enquire whether a locator is primary or not.
The main reason for promoting locators is to allow HDS objects to be passed between routines while ensuring that the associated container file remains open, so that the object remains accessible. For example, consider the following simple routine which returns a locator for a named object inside a container file:
Note how the temporary locator returned by HDS_OPEN is annulled after first promoting the secondary locator derived from it, so that the container file remains open. If this is the first time the file has been opened, its reference count will be 1 when this routine exits, so it will be closed when the caller later annuls the returned locator LOC.
6As defined in the include file DAT_PAR.
7You are advised not to depend on this mechanism for annulling secondary locators because you will not normally have complete control over a file’s reference count (for instance, it may be opened independently for some other purpose in the same piece of software).