Locating, adding, deleting, locking, and unlocking entries in tables such as the file control table (FCT), application file control table (AFCT), data set name block table (DSNT), and terminal control table (TCT) are performed by the table manager program, DFHTMP. Entries in these tables are also called "resources". Because the structures of tables vary as entries are added or deleted, and a quick random access is required, a hash table mechanism is used to reference the table entries. In addition because fast access is needed for generic locates and ordered lists of entries, a getnext chain with a range table is used.
The hash table is a set of pointers that are the addresses of directory elements of table entries. A directory element is a set of pointers; one of these pointers is the address of the table entry, the remaining pointers are the addresses of the next elements of various chains used in the different operations of the table manager. An example of a hash table is shown in Figure 75.
The table manager logically combines the characters of the name of the resource, and transforms the result to give an integer that is evenly distributed over the hash table size.
When an entry is located or added, the table manager places it at the head of its chain. Thus frequently used entries tend to have the minimum search times.
If the hash chains become very long, the table manager creates a larger hash table if storage is available. The hash table is enqueued before and dequeued after the reorganization, so that no references to the table can be made during reorganization.
Some requests to TMP are not full key locates, but rather generic locates with a partial key. For example, requests to find all terminals whose Termid starts with two specified characters. To enable these requests, a getnext chain is maintained which orders all the directory elements alphabetically by key. There is also a ‘range table’ which holds pointers to certain elements along the getnext chain and a count of how many intermediate elements there are in each range.
This range table is hunted with a binary search to find the range in which a given key (full or partial) will reside, and then the getnext chain is used to find a match (if one exists) for the search condition.
A range will be split into two equal ranges if the number of intermediate elements rises above a threshold which depends on the number of ranges and the number of elements in the table. So the ranges are dynamic, and do not depend on any particular key distribution.
The number of ranges in the table is determined when the hash table is created, and if all the ranges are full, but a range should be split, a reorganization of the ranges takes place, which increases the range threshold by a factor of 2.
A separate hash table, called the secondary index, is created for certain TMP tables, which allows the same entry to be located by another key. In certain secondary indexes, the names do not need to be unique (whereas in the primary index the name is always unique). The secondary index entry is deleted at the same time the entry in the primary index is deleted.
For example, a secondary index is created for DSNAME blocks. This allows table entries to be accessed via secondary keys, using the DSNAME block number in the case of DSNAME blocks.
Certain tables also have aliases as distinct from secondary indexes. These are alternative names for the table entry, which can be used to locate a table entry. They exist in the same index as the primary name, and are not included in a getnext chain, rather they form an alias chain from the primary entry.
The table manager performs the following functions:
Read locks are used to prevent a table entry being deleted by the table manager.
A read lock is a fullword of storage. When DFHKCP attaches a task, it allocates storage for a number of local read locks; this storage is addressed by TCATMRLP in the TCA. Local read locks are not acquired for table entries that cannot be deleted.
Global read locks are used by the CICS® modules that are executed independently of any task. They reside in the table manager static storage area (TMS) that is addressed by SSATMP in the static storage address list (SSA).
These locks are released by:
Read locks are always obtained against the primary index entry even if the request is against a secondary index or an alias.
For Getnext requests on secondary indexes, a browse token is used to hold the name of the previously found entry. The token consists of the name found in the secondary index (which may not be unique) and the name in the primary index (which is unique).
The address of the directory entry cannot be used instead of this logical name because the entry may be returned unlocked, and so may be deleted when the next getnext request is received.
The getnext consists of locating the entry in the secondary index which has a the correct primary index, if it exists, and then moving forward in the getnext chain. If it does not, an entry with a matching secondary index name, but a higher primary index name is located, if one exists. If that also does not exist, an entry with a higher name in the secondary index is located. This requires that entries on the getnext chain for ordered both by secondary index name and also when identical secondary index names exist, by primary index name.
A table entry is moved into quiesce state by a quiesce request if no read locks (including ones obtained by the issuing task) exist for the entry. When a table entry moves into quiesced state, it is unable to be located. Locating tasks can choose to ignore or wait for quiesced entries to be unquiesced or deleted.
If the quiesce request is performed with the commit option, the only ways to release the quiesced state are:
For commit requests, the delete takes place immediately the request completes. Otherwise, if an entry is not deleted or unquiesced by the end of the UOW the TM DWE will unquiesce the entry. In this case, a delete does not take effect until the end of the UOW.
Figure 76 shows the relationship of the table manager control blocks. A general procedure for finding the required table entries in a partition dump is as follows:
TMASKT1 = reserved
TMASKT2 = reserved
TMASKT3 = reserved
TMASKT4 = addr of profile table (PFT) entries
TMASKT5 = addr of FCT entries
TMASKT7 = addr of local terminal (TCTE) entries
TMASKT8 = addr of remote terminal and connection (TCNT) entries
TMASKT9 = addr of local connection (TCTS) entries
TMASKT10 = addr of AFCT entries
TMASKT11 = addr of DSNAME entries (by name)
TMASKT12 = addr of DSNAME entries (by block ID)*
TMASKT13 = addr of partner resource table (PRT)
entries
TMASKT14 = reserved
TMASKT15 = addr of local terminal NETNAME table (TCNT) entries
TMASKT16 = addr of autoinstall terminal model (AITM)
table entries
TMASKT17 = addr of signon table (SNT) entries
TMASKT18 = addr of session (TCSE) entries
TMASKT19 = addr of remote connection entries (TCSR)*
TMASKT20 = addr of indirect connection entries (TCSI)*
TMASKT21 = addr of connection NETNAME (TCSN) entries*
TMASKT22 = addr of remote terminal entries (TCTR)*
TMASKT23 = addr of generic connection NETNAME (TCSM) entries*
TMASKT24 = addr of remote terminal NETNAME (TCNR) entries*
* - Secondary index
Use the following formula to find the offset of the individual scatter table:
Length(TMATTV) * (n-1) + X'08'
Where n = position in table (see above - TMASKTn)
To find Length(TMATTV) (and the value of n) see the CICS Data Areas manual.