LDA III and D-ISAM
A White Paper
By
Information Exchange Group, Inc.
(IEG)
June, 1998
Note: a full Word document containing pictures can be found at:
ftp://ftp.ieg-inc.com/ftp.ieg-inc.com/client/whitepapers/d-isam.doc
See our Support/File Exchange page for FTP details.
Introduction
This document describes the nature of the LDA III runtime database (D-ISAM). D-ISAM is provided to Unisys by a third party and has superseded C-ISAM which has limitations that are unacceptable in today's marketplace. Discussed in this document are:
- File "Cluster" Members
- Symbolic Files
- Database Files
- D-ISAM Limitations
- LINC Implications
IEG has developed several LDA runtime products and utilities requiring this information. Since Unisys did not provide this information, IEG has decided to make it public.
Disclaimer
The accuracy of information contained herein is not guaranteed. The information in this document has been discovered by experimentation and researching the resulting disk files. This document is subject to change as our understanding of D-ISAM evolves and as LDA III's usage of D-ISAM may change. Unless noted otherwise, the information relates to LDA 2.1 and later.
File "Cluster" Members
Each Usage I-O and Output ISPEC creates a "Cluster" of files in LDA III's run-time environment. All files in the cluster begin with the underscore character "_" and include the ISPEC name. Symbolic files are simple ASCII text files which describe the characteristics of the run-time database files.
Symbolic Files
_<Ispec>.DFN
_<Ispec>.DFN defines the file layout of _<Ispec>.DAT. It is created when you choose "Create Database" in run time. Its format is:
V 0 0 2 . 0 0 1 . 0 0 0
56 30 30 32 2E 30 30 31 2E 30 30 30 0A
(not in 1.3 and prior)
0 0 0 2 8
30 30 30 32 38 0A
20 0A
(not in 1.3 and prior)
s t d i o f l a g 0 A 1 0
73 74 64 69 6F 66 6C 61 67 20 30 20 41 20 31 20 30 0A
p d a t a r f l a g 1 A 1 0
70 64 61 74 61 72 66 6C 61 67 20 31 20 41 20 31 20 30 0A
D A T A R 2 A 1 5 0
44 41 54 41 52 20 32 20 41 20 31 35 20 30 0A
M A I N T 1 7 A 1 0
4D 41 49 4E 54 20 31 37 20 41 20 31 20 30 0A
O R D 1 8 A 1 0 0
4F 52 44 20 31 38 20 41 20 31 30 20 30 0A
_<Ispec>.PFN, if it exists, is the prior DFN file for the ISPEC when the layout has changed. It is created when you choose "Reorganize database" in run time and the layout of the ISPEC has changed.
_<ispec>_P.DFN
_<Ispec>_P.DFN is the Definition
file for all Profiles that target <ISPEC>. It is created when you choose "Create database" in run time. Its format is:
P S T D I O 0 1 0 1 0 0 0 0 F
50 53 54 44 49 4F 20 20 20 20 20 30 31 30 31 30 30 30 30 46 0A
I S T D I O
49 53 54 44 49 4F 0A
O O R D F F
4F 4F 52 44 20 20 20 20 20 20 20 46 46 0A
P P D A T A R 0 1 0 1 0 0 0 0 T
50 50 44 41 54 41 52 20 20 20 20 30 31 30 31 30 30 30 30 54 0A
I S T D I O
49 53 54 44 49 4F 0A
O D A T A R F F
4F 44 41 54 41 52 20 20 20 20 20 46 46 0A
P P N U M E R O 0 1 0 2 0 1 0 1 T
50 50 4E 55 4D 45 52 4F 20 20 20 30 31 30 32 30 31 30 31 54 0A
I S T D I O
49 53 54 44 49 4F 0A
O N U M E R O F T
4F 4E 55 4D 45 52 4F 20 20 20 20 46 54 0A
O O R D F F
4F 4F 52 44 20 20 20 20 20 20 20 46 46 0A
C M A I N T 3 T D
43 4D 41 49 4E 54 20 20 20 20 20 33 54 20 44 0A
_<Ispec>_P.PDF, if it exists, is the prior profile definition file. It is created when you choose "Reorganize database" in run time and the target ISPEC or a Profile has changed.
Database files
_<Ispec>.DAT
User data is stored in _<Ispec>.DAT files. A DAT file is created when you choose "Create database" in run time. DAT files are "square," that is all records within the same DAT file are the same length. Its format is described in the associated .DFN file. Data appears here in the order of record addition.
Y Y F i r s t D a t a r A F i r s t O r d
59 59 46 69 72 73 74 20 44 61 74 61 72 20 20 20 20 41 46 69 72 73 74 20 4F 72 64 20 0A
Y Y 3 D a t a r A 3 O r d
59 59 33 20 44 61 74 61 72 20 20 20 20 20 20 20 20 41 33 20 4F 72 64 20 20 20 20 20 0A
Y Y 2 D a t a r A 2 O r d
59 59 32 20 44 61 74 61 72 20 20 20 20 20 20 20 20 41 32 20 4F 72 64 20 20 20 20 20 0A
In 1.3 and priorall numeric data items are stored as double precision floating point using the IEEE 64 bit format thus taking up 8 bytes. In 2.1 and later, the numeric fields are simple character fields with lengths corresponding to the item’s length plus sign and decimal point, if any.
_<Ispec>.IDX Introduction
Data in the DAT file is always accessed
through the _<Ispec>.IDX file. This is the heart of D-ISAM. The layout of the IDX file is quite complex compared to the other files in the cluster, so a little background is necessary. The IDX file:
- Is accessed in "blocks," each of which is 2048 characters long.
- Contains "sizes" and "pointers."
- Sizes are 2-byte (16 bit) "integers." The leftmost bit is the sign - always zero; the rightmost bit is the least significant bit. Thus, a size can be from 0 through 32,767.
- Pointers are 4-byte (32 bit) "longs." The leftmost bit is the sign - always zero; the rightmost bit is the least significant bit. Thus, a Pointer can be from 0 through 2,147,483,647.
- Contains Indexes in the form of "trees" of "coarse" (optional) and "fine" tables for each Profile targeting the ISPEC.
- Coarse table entries point to another coarse table or to a fine table.
- Fine table entries point to a record in the DAT file. Each record in the DAT file will have an corresponding entry in a fine table.
Conceptually, the IDX file contains:
- Block "0"
- Pointers to the other parts of the IDX file
- Counts and statistics related to the indices and the DAT file
- "DK" table, a list of deleted (Purged) records in the DAT file.
- Index Descriptors
- Coarse and Fine Tables (indices)
_<ispec>.IDX Layout
Block "0"
- Is at the beginning of the IDX file.
- Byte 7 indicates blocksize used in address calculations below:
- 1 = 512 bytes (LDA 1.2)
- 7 = 2048 bytes (LDA 1.3)
- Byte 16 has a long pointer which may be to the beginning of the index descriptors. The actual address is obtained by multiplying this number (if greater than 0) -1 by blocksize.
- Byte 26 has a long pointer to the current DK table of purged record numbers. The actual address is obtained by multiplying this number (if greater than 0) -1 by blocksize.
- Byte 30 has a long pointer to the prior DK table address. The actual address is obtained by multiplying this number (if greater than 0) -1 by blocksize.
- Byte 34 has a long count of the number of records (including purged records) in the DAT file.
- Byte 42 has a long count of the number of update transactions
- Byte 46 has a long pointer which points to the beginning of the index descriptors. The actual address is obtained by multiplying this number by blocksize.
- Byte 99(?) has a long count of the number of file opens.
DK Table
- When a record is purged, its record
number is added to the end of the DK table and the DK table size is increased by 4 (length of a long).
- When records have been purged from the DAT table, new records are added in place of the most recently purged record (LIFO) by retrieving the record number from the final entry in the DK table and decreasing the DK table size by 4.
- The format of the DK table is:
- Integer table size (including the 2-byte integer).
- Long pointer to prior (?) DK table, if any.
- A series of long record numbers (one relative) which have been purged.
Index Descriptors
- D-ISAM uses this information to know where in IDX the first table ("root") is for each Profile and where the keys are in data records.
- The format of the Index Descriptor table is:
- Integer table size (including the 2-byte integer)
- A Long of zero (perhaps a pointer to an overflow).
- A Dummy entry:
- 00 07 (Entry size = 7 bytes)
- 00 00 00 00 00
- A series of Index Descriptors, one for each Profile, each with the format:
- Integer entry size (including the 2-byte integer)
- Long pointer, "r," to the Profile's "root" table
- Actual address (one relative) = 1 + (blocksize * (r - 1) )
- Integer of 00 00 or 00 80. 00 80 indicates the Profile allows duplicates.
- 01 00. I haven't seen anything else.
- 0n 00. Appears to be a Profile number, but it's the wrong format.
- Key Descriptors, one for each key, each having the form:
- Integer key size. This can be zero for the "dummy" Profile for Memos and Events. Remember that all numerics will be 8 bytes long (double precision) prior to 2.1.
- Integer position within the data record.
- One character Key Type:
- 00 = alpha
- 03 = numeric
- 80 = descending alpha
- 83 = descending numeric
- There is no indication of LIFP; this implies that LIFP conditions are evaluated at run time and the record is marked as a non-member.
- The rest of the block is filled with 00.
Coarse/Fine Tables
- As records are added to DAT, each Profile has an entry added pointing to the record and the data is checked against each Profile's membership criteria.
- As records are Purged from the DAT, the corresponding entry in each Fine table is marked as "not a member."
- As records are updated in the DAT, the conditions of membership in each Profile are reevaluated and the fine table membership flag is updated as required.
- Both types of tables share the same format:
- Integer table size (including the 2-byte integer). 00 02 means the table is empty.
- A series of entries each having the form:
- Key. If this is a coarse table, these items are a copy of the values from the final entry of the table pointed to by the long pointer below (unless this is the final entry in this table - in which case this equals the prior entry's key (I think this a D-ISAM bug). If this is a fine table, these items are a copy of the values from the data record in DAT pointed to by the long pointer below.
- One character validity flag (Y or N).
- User key values - size according to length in the Key Descriptor.
- Long duplicates resolver, only if duplicates are allowed. Key values along with the resolver make a unique value.
- Long pointer.
- If this is a coarse table, this points to another table in IDX. The actual address (one relative) is = 1 + (blocksize * (r - 1) )
- If this is a fine table this field contains record number (one relative) in the DAT file.
- The rest of the block up to the last four bytes is filled with 00
- Integer Profile number
- Table type "0n xx":
- "n" is the table level, zero being a fine table.
- "xx" is ignored.
D-ISAM limitations
These limits are not based on D-ISAM APIs or LDA III interpreter design - that information is not available. Hence, consider these limits as purely theoretical and more liberal than actual implementation limits.
| Limited Item |
Limit |
Basis of Limit |
| Number of ISPECs |
unknown |
|
| File size |
2,147,483,647 |
Size of byte pointer in file read/write operations |
| Number of Records |
2,147,483,647 |
Fine table record # field is a "long" |
| Number of Records with Duplicate key values |
2,147,483,647 |
Fine table duplicates resolver is a "long" |
| Record Size |
2,147,483,647 |
Size of byte pointer in memory accesses |
| Key starting position within record |
32,767 bytes |
Index descriptor key position field is an "integer" |
| Number of Profiles |
see below |
Index descriptor table size (32,767), number of Profiles and number of keys |
| Number of keys within a Profile |
6,550 |
Index descriptor table size (32,767) less 12. Each key descriptor requires 5 bytes. |
| Total key size within a Profile with no duplicates allowed |
16,372 bytes |
(Coarse table size less 4)/2 - 9. |
| Total key size within a Profile with duplicates allowed |
16,376 bytes |
(Coarse table size less 4)/2 - 5 |
Remember that any numeric key requires 8 bytes in 1.3 and prior.
Number of Profiles is limited by a combination of factors. The following relationship must hold:

Implications on LINC
- LU; EVERY reads records from the DAT via an implied Profile, such as the standard Component ordinate profile; thus records will be retrieved in a logical order. Even the EVENT has an implied Profile, and LU; EVERY EVENT will return records in the order they were added; thus results may differ from host LINC on some platforms where the Event would be read in physical order.
- DT; ACTUAL (<component>) reads the DAT file directly, skipping over purged records (records ending in hex 00). Note that due to record purging and re-additions, this order likely will not match the results of a LU; EVERY.
- Upon initial opening of a file, up to 7000 records may be added. After that, D-ISAM is instructed to do a "commit" after each record addition so that memory locks may be freed. Thus, records will add quickly at first, then quite slowly.
- Upon subsequent opens of a file, up to 7000 records may be added. After that, LB.STATUS is set to (*****) and no more records are added. (Why couldn't this be the same as initial open?)
- Upon subsequent opens of a file, up to 7000 records may be FLAGed. After that, the run time simply aborts. (They wanted to make it like the A-series 50,000 record limit, but smaller because it's a PC.) Note that EXCLUSIVE.USE is not available on the PC.
- Therefore, when loading test data, be cognizant of what's going on! Same for testing reports which update many records. The best approach is make the report recoverable (using your own pointers/logic), close the report and re-run the report.