White Paper Series: #8
Author: Donald A. Marsh, Jr.

About Aurora Information Systems, Inc. How to Contact Aurora Information Systems, Inc.
 

FML32 Tid-Bits

Download this White Sheet in PDF format. Right click your mouse and select SAVE TARGET AS or SAVE LINK AS.

Introduction to FML32 Concepts

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

Field Table

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

Case 1

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

Testing Case 1

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

Case 2

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:

  1. Subtract the Starting Field ID (167772160) from 167775677 which left 3517.
  2. 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

Summary

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.

Copyright © 2005 Aurora Information Systems, Inc. All rights reserved.
voice (407) 708-1040   .   fax (407) 708-1039