
FML32 Tid-Bits
This article describes some fundamental FML32 concepts that are intended to help you better understand your code. I assume that you already know how to create and compile a FML32 Field Table, and that you know how to set the environment variables appropriately. If not, then see the FML Programmers Guide in the BEA Tuxedo on-line documentation.
Return to Top of Page
The base number in the FML32 Field Table plus the Relative Numeric value of the field are added to the Starting Field ID for each data type, and the resulting number is the Field ID. Field Ids can be between 1 and 33,554,431 for FML32, however Ids 0 through 100 are reserved for Tuxedo system use. Your base number should always be 100 or greater.
| Field Data Type |
Starting Field ID Number (FML32) |
| short |
0 |
| float |
1100663297 |
| double |
134217728 |
| string |
167772160 |
| carray |
201326592 |
| long |
33554432 |
| char |
67108864 |
There are definitely situations where this little bit of knowledge becomes valuable, and is demonstrated here by two real world examples.
Return to Top of Page
In this first case, a programmer hard-coded the Field ID value for a carray field in a client program, then at some point all of the carray fields in the Field Table were changed to string types, however the client program was never modified to reflect the new Field Ids. You would expect the client to encounter an error, however it continued to work without producing error messages.
The reason is that the algorithm used to calculate the Field slot in the Field Table results in a index pointer to the same slot, even though the Field Type was changed.
Consider the following FML32 Field Table:
| *base 100 |
| #name |
number |
type |
flags |
comments |
| F_FIELD1 |
1 |
carray |
- |
- |
| F_FIELD2 |
2 |
carray |
- |
- |
| F_FIELD3 |
3 |
carray |
- |
- |
The Field Ids are calculated by summing the Starting Field ID for the Field Type (in this case 201326592) plus the base (100) plus the Field Reference number (1,2,3). The resulting Field Ids would be:
| F_FIELD1 |
201326693 |
| F_FIELD2 |
201326694 |
| F_FIELD3 |
201326695 |
The programmer hard-coded the value 201326693 in the client which resolves to F_FIELD1 when and FML32 function is called (which is as expected):
Fname32( 201326593 ) returns "F_FIELD1"
However, when the Field Type is changed from carray to string, the resulting Field Ids are:
| F_FIELD1 |
167772261 |
| F_FIELD2 |
167772262 |
| F_FIELD3 |
167772263 |
and Fname32( 201326593 ) still returns "F_FIELD1".
Return to Top of Page
The reason is that 201326593 and 167772261 both resolve to the same slot in the Field Table array.
That is: (201326593 - 201326592) = (167772261 - 167772160) = 101 = F_FIELD1
To see this in action, perform the following test on your system. Create a FML32 Field Table with the following fields and be sure to include it in the FLDTBLDIR32 and FIELDTBLS32 environment variables:
| *base 0 |
|
|
|
|
| #name |
number |
type |
flags |
comments |
| F_FIELD0 |
3516 |
carray |
- |
- |
| *base 3500 |
|
|
|
|
| #name |
number |
type |
flags |
comments |
| F_FIELD1 |
1 |
string |
- |
- |
| F_FIELD16 |
16 |
string |
- |
- |
Create a file called tstclt.c (see source below) and compile it using:
buildclient -o tstclt -f tstclt.c
#include <stdio.h>
#include <string.h>
#include <atmi.h>
#include <fml32.h>
int main(int argc, char *argv[])
{
char *cp;
if((cp = Fname32( 201330108 )) != (char *)NULL )
fprintf( stderr, "Fname32( 201330108 ) = %s\n", cp );
else
fprintf( stderr, "%s\n", Fstrerror32(Ferror32) );
if( (cp = Fname32( 201330108 )) != (char *)NULL )
fprintf( stderr, "Fname32( 167775676 ) = %s\n", cp );
else
fprintf( stderr, "%s\n", Fstrerror32(Ferror32) );
return( 0 );
}
|
When you run the tstclt program it produces the following output:
Fname32( 201330108 ) = F_FIELD0 Fname32( 167775676 ) = F_FIELD0
Now comment out or remove Field0 from the FML Field Table and run the test again. Can you guess what will happen if you add Field0 back in and remove Field16?
Return to Top of Page
In a second case, an application (JSH) wrote the following error message to the ULOG:
JSH.28145: Fname(167775677) failed in [Service]: error=5.
This error was received after moving the entire application into a QA environment. The steps used to track down the problem were as follows:
- Subtract the Starting Field ID (167772160) from 167775677 which left 3517.
- Search the Field Table for a field whose Base and Field Reference number add up to 3517.
The following is a sample of the Field Table (field names have been changed):
.
.
.
*base 3500
#name number type flags comments
F_FIELD1 1 string - -
F_FIELD2 2 string - -
F_FIELD3 3 string - -
F_FIELD4 4 long - -
F_FIELD5 5 string - -
F_FIELD6 6 string - -
F_FIELD7 7 long - -
F_FIELD8 8 long - -
F_FIELD9 9 string - -
F_FIELD10 10 string - -
F_FIELD11 11 string - -
F_FIELD12 12 string - -
F_FIELD13 13 string - -
F_FIELD14 14 string - -
F_FIELD15 15 string - -
F_FIELD16 16 string - -
*base 4000
.
.
.
|
We can see that a service is returning a Field (to the JSH) that has been removed from the Field Table. The largest Field Reference number in the 3500 range is 16, not 17. A quick check of a prior version of the Field Table revealed that F_FIELD17 (with a Field Reference number of 17) had been inadvertently removed from the Field Table that was just promoted to QA.
The fix was a simple matter of ensuring that the appropriate FML Field Table was promoted along with the rest of the application.
Return to Top of Page
In Summary, it is never a good idea to hard-code Field ID values in your clients or services. The best approach for ease of maintenance is to use the Fldid32() function to determine Field Ids at run-time. This approach does incur a performance penalty because it requires a function call for each FML32 field.
A major benefit of using Fldid32() is that production changes to the FML32 Field Table do not require re-compilation (except for field deletions). If performance is a concern, then include the generated C header file and use the #defined constants in your programs, but keep in mind that any change to the FML32 Field Table will require re-compilation of your programs.
And lastly, using the Starting Field Ids listed above can help you track down FML32 anomalies in your programs.
~end of Aurora Information Systems' White Paper Series #8
"FML32 Tid-Bits "~
Return to Top of Page
Do you find this information interesting?
Consider employment with Aurora!
|
|
Do you need help implementing your Middleware app? Aurora can make your life easier.
|
|