gtpa2m20Application Programming

Creating a Logical Record Cache

To create a logical record cache, the application starts the newCache function, passing the following as inputs:

See TPF C/C++ Language Support User's Guide for more information about the newCache function.

The following shows the function to create a logical record cache:

long    newCache(const void  *  cache_name,
                 cacheTokenPtr  cachetokenReturn,
                 const long     primaryKeyLength,
                 const long     secondaryKeyLength,
                 const long     dataLength,
                 const long     numberEntries,
                 const long     castoutTime,
                 const long  *  type_of_cache,
                 const long  *  reserved);     

System Heap and the Hash Table

When logical record cache support creates a new cache, it resides in the system heap. The amount of system heap allocated is determined by the values passed on the newCache function for the primaryKeyLength, secondaryKeyLength, dataLength, and numberEntries parameters. The numberEntries parameter is used to determine the size of the hash table and the number of entries the cache must hold. Determine the minimum number of entries needed. If more entries are needed as shown by an unacceptable castout rate in the data collection reports, you can increase the value of the entries by entering the ZCACH command without changing the code. See TPF Operations for more information about the ZCACH command. See TPF System Performance and Measurement Reference for more information about the data collection reports.

To determine the size of the hash table, logical record cache support doubles the value passed for the number of entries and calculates the best prime number to use as the hash divisor. The resulting value becomes the size of the hash table. The size of an entry is calculated by adding the values for the primaryKeyLength, secondaryKeyLength, and dataLength parameters plus some TPF system overhead for chaining. Therefore, the amount of system heap allocated is determined by adding the following values together:

See TPF System Generation for more information about the system heap.

Cache Name

The cache name is used to define the cache and to allow other applications to connect to the cache by issuing their own newCache function call and specifying the same cache name. The first application to issue the newCache function for a specific cache name will cause the cache to be created and its attributes set. The newCache function call with the same cache name must pass parameters that are checked against the attributes of the cache and, if they are the same, the caller is connected to the cache. If the parameters and the attributes do not match, an error code is returned to the caller.

The cache name:

Note:
All cache names beginning with the letter I are reserved for IBM use. Additionally, all cache names beginning with the letters tpf in uppercase, lowercase, or mixed case are reserved for IBM use. See TPF Programming Standards for more information about naming conventions.

The following are examples of valid cache names:

The following are examples of cache names that are not valid:

 Aca 
Is less than 4 characters in length.

 AnameThatIsTooLong 
Is greater than 12 characters in length.

 TPFcache2 
Begins with IBM reserved letters.

 Icache6 
Begins with an IBM reserved letter.

 cache15* 
Contains an asterisk (*), which is an unsupported character.

cacheToken Value

The cacheToken is a value returned from the newCache function. The cacheToken value is returned in the field pointed to by the cacheTokenPtr parameter and is used for all other function calls to logical record cache support to identify the specific cache to act on. Whenever a specific cache is to be read, updated, or deleted, the cacheToken value identifies the cache. The passed token is validated by logical record cache support and, if it is not valid, an error code is returned to the caller and the function is not performed. The returned token can be saved and passed on all other iterations of code using the cache, or a newCache function can be started on every iteration of the code to retrieve the cacheToken value.

Examples

The following example shows how to define and use a cacheToken value:

#include <c$cache.h>
cacheToken      myCache;

Then set the cacheToken by issuing the following.

newCache (cache name,     /* name of the cache                    */
           &myCache,      /* address of where to store the token  */
           ...);          /* the remainder of the parameters      */
 

The following shows how cacheToken is used on a readCacheEntry function.

readCacheEntry(&myCache,    /* address of the token to use     */
             ......);       /* the remainder of the parameters */
 

Processor Unique and Processor Shared Caches

Logical record caching supports processor unique and processor shared caches. The cache type is passed as a parameter on the newCache function.

Examples

The following example shows how to pass the cache type on the newCache function.

/* To create a processor unique cache   */
 
   #include <c$cache.h>
   char  cacheType = Cache_ProcQ;  /* processor unique cache  */
 
   newCache(cache name,      /* name of the cache                   */
             &myCache,       /* address of where to store the token */
             ...             /* other parameters                    */
             &cacheType,     /* address of the cache type value     */
             NULL);          /* reserved set to NULL                */
 
/* To create a processor shared cache  */
 
   #include <c$cache.h>
   char  cacheType = Cache_ProcS; /* processor shared cache    */
 
   newCache (cache name,      /* name of the cache                   */
             &myCache,        /* address of where to store the token */
             ...              /* other parameters                    */
             &cacheType,      /* address of the cache type value     */
             NULL);           /* reserved set to NULL                */
 
 

castOutTime Value

The castOutTime parameter specifies the default time, in seconds, that an entry can exist in cache before it is considered old and must be replaced. This value is only used for processor unique caches or for processor shared caches that are not being managed using a CF to handle entry invalidations from other processors. If the cache is processor shared and connected to a CF cache structure, the castOutTime value is ignored. If there are no CFs available for use by the cache, the cache is still defined to be processor shared but operating in local mode and the castOutTime value is used.

The following example shows how to create a processor shared cache with primary and secondary keys.

#include <c$cache.h>
  char         cacheNameS[12] = "Shared_Cache";   /* cache name */
  char         cacheNameU[12] = "Unique_Cache";   /* cache name /
  cacheToken   myCacheShared;                /* where to save cacheToken   */
  cacheToken   myCacheUnique;                /* where to save cacheToken   */
  long         primaryKeyLgh = 255;          /* 255 byte primary key       */
  long         secondaryKeyLgh = 32;         /* 32 byte secondary key      */
  long         dataLgh = 48;                 /* 48 bytes of data           */
  long         numbEntries = 200;            /* 200 entries                */
  long         castOutTime = 60;             /* cast entry after 60 seconds*/
  char         cacheType = Cache_ProcS;      /* processor shared cache     */
 
  if( newCache ( cacheNameS,                 /* name of the cache                   */
                 myCacheShared,              /* address of where to store the token */
                 primaryKeyLgh,              /* maximum primary key length          */
                 secondaryKeyLgh,            /* maximum secondary key length        */
                 dataLgh,                    /* maximum data length                 */
                 numbEntries,                /* number of entries in cache          */
                 castOutTime,                /* cast out Time value                 */
                &cacheType,                  /* address of cache type value         */
                 NULL )                      /* reserved set to NULL                */
                           !=CACHE_SUCCESS)  /* successful create                   */
 {
      printf("error creating Shared_Cache"); /* write error msg  */
      exit(1);                               /* and exit         */
 }

The following example shows how you can create a processor unique cache with only primary keys and no castout time.

cacheType = Cache_ProcQ;         /* processor unique cache  */
 
if( newcache ( cacheNameU,                /* name of the cache                   */
               &myCacheUnique,            /* address of where to store the token */
               primaryKeyLgh,             /* maximum primary key length          */
               NULL,                      /* no secondary keys                   */
               dataLgh,                   /* maximum data length                 */
               numbEntries,               /* number of entries in cache          */
               NULL,                      /* cast out Time value                 */
               &cacheType                 /* address of cache type value         */
               NULL )                     /* reserved set to NULL                */
                       !=CACHE_SUCCESS)   /* successful create                   */
    {
        printf("error creating Unique_Cache");   /* write error msg     */
        exit(1);                                 /* and exit            */
    }