/****************************************************************************** * * Definitions for PI/open Dynamic (LH) files * * Module %M% Version %I% Date %H% * * (c) Copyright 1998 Ardent Software Inc. - All Rights Reserved * This is unpublished proprietary source code of Ardent Software Inc. * The copyright notice above does not evidence any actual or intended * publication of such source code. * ******************************************************************************* * * Maintenence log - insert most recent change descriptions at top * * Date.... GTAR# WHO Description......................................... * 10/14/98 23801 SAP Change copyrights. * 05/17/96 18433 WSM Changes to allow conversion on any platform. * 06/21/94 14342 ALC Added new block type to detect files where * conversion started. * 05/19/94 14011 ALC Added def's for AK file removal. * 05/05/94 13934 ALC Removed unused detail. * 10/20/93 12303 ALC Initial implementation * Module constructed from a number of PI/open * include files. * ******************************************************************************/ /* * PI/open file configuration parameters */ #define MAX_BLOCK 4 /* maximum block allowed */ #define MAX_IDLEN 220 /* maximum PI/open ID length */ #define MAX_OPTIONS 10 /* Max number of UFS types supported */ #define OPTION_BUFFER_BYTES 800 /* Storage for option strings in hdr */ #define LH_FIRSTINDEXSUBFILE 2 /* First AK index file suffix */ #define MAX_SUBFILES 256 /* Max AK suffix is 1 less */ /* * offsetof(): Constant expression the value of which is the offset in bytes * from the beginning of a structure 'type' of the member 'identifier' * (which cannot be a bit field). */ #if defined(offsetof) #undef offsetof #endif #define offsetof(type, identifier) ((char*)&((type*)0)->identifier - (char*)0) /* * Types of blocks in PI/open dynamic files */ #define BT_MINVALUE 29030 /* minimum legal type */ #define BT_FREEBLOCK 29030 /* block on free list */ #define BT_ALLOCBLOCK 29031 /* just allocated block */ #define BT_PRIMARY 29032 /* primary file header */ #define BT_OVERFLOW 29033 /* overflow file header */ #define BT_BUCKET 29034 /* bucket containing records */ #define BT_BIGRECORD 29035 /* data for a big record */ #define BT_OPTIONDATA 29036 /* data block for options like AK */ #define BT_MAXVALUE 29036 /* maximum legal type */ #define BT_CONVERTING 29037 /* Converting to uniVerse, illegal PI/open value */ /* * Macros to split block-number-size values into block numbers * and block sizes. Block number is stored in lower 24 bits of * a bin(31), and block size is stored in upper 8 bits. */ #define BNS_MODVALUE 16777216 /* value to split block and size (2^24) */ #define HEADER_BLOCK 0 /* block number for file headers */ /* * Macros to build a bns value from a blocknumber and blocksize * and obtain the block number or block size from a bns value */ #define bns_number(bns) ((bns) % BNS_MODVALUE) #define bns_size(bns) ((bns) / BNS_MODVALUE) /* * Structure of block headers for each type of block. * This structure appears at the beginning of every type of block. * The first part of this structure is common among all types of * blocks. Later parts of the definition describe variant sections * of the structure based on block type. */ typedef struct lh_params_t lh_params_t; struct lh_params_t { short b_hash; /* which hash algorithm to use */ short b_bucketsize; /* block size of each primary bucket */ int b_minmod; /* smallest number of groups allowed */ int b_bigrecordchars; /* data size for using big records */ short b_minload; /* minimum desirable loading factor */ short b_maxload; /* maximum desirable loading factor */ }; typedef struct lh_state_t lh_state_t; struct lh_state_t { uint b_modulus; /* current number of groups in file */ int b_modvalue; /* current power of two for split */ int b_nextsplit; /* next bucket for splitting */ }; typedef struct lh_state2_t lh_state2_t; struct lh_state2_t { int b_loadwords; /* non-big record words in the file */ }; typedef struct lh_fileinfo_t lh_fileinfo_t; struct lh_fileinfo_t { lh_params_t b_lhparams; /* user selectable parameters */ lh_state_t b_lhstate; /* written to file whenever changed */ lh_state2_t b_lhstate2; /* written to file when closed */ }; typedef struct lh_options_t lh_options_t; struct lh_options_t { int b_optionblock[MAX_OPTIONS]; /* array of data pointers */ char b_optionbuffer[OPTION_BUFFER_BYTES]; /* local storage for data */ }; typedef struct primary_block_t primary_block_t; struct primary_block_t { lh_fileinfo_t b_lhfileinfo; lh_options_t b_options; /* optional data for things like AK */ }; typedef struct overflow_block_t overflow_block_t; struct overflow_block_t { int b_blocks; /* total number of blocks in overflow file */ short b_lastblocksize; /* size of last block in file */ int b_freeblocks[MAX_BLOCK]; /* free list headers for free list */ int b_freecounts[MAX_BLOCK]; /* count of blocks in each list */ }; typedef struct bucket_block_t bucket_block_t; struct bucket_block_t { int b_groupnumber; /* group number this bucket belongs to */ short b_records[1]; /* first location for record storage */ }; typedef struct bigrecord_block_t bigrecord_block_t; struct bigrecord_block_t { int b_hashvalue; /* full hash value of record id this is for */ char b_recorddata[2]; /* first location of record data storage */ }; typedef struct optiondata_block_t optiondata_block_t; struct optiondata_block_t { short b_optiondatalen; /* length of data string */ char b_optiondata[2]; /* data string */ }; typedef struct block_header_t block_header_t; struct block_header_t { int b_bns; /* current block number and size */ short b_type; /* block type */ short b_headerwords; /* size of header (words) */ int b_sequence; /* sequence number within a chain */ int b_nextbns; /* next block number and size in chain of blocks */ short b_prevsize; /* size of previous block */ union b_vardata { primary_block_t primary_block; overflow_block_t overflow_block; bucket_block_t bucket_block; bigrecord_block_t bigrecord_block; optiondata_block_t optiondata_block; } b_vardata; }; /* * Format of a record. * The r_idlen field must be first, since it indicates the number of * words needed to examine the full record header including the id. * Negative values indicate deleted records or the end of the group. * The r_datablock field indicates where the data for the record is. * If zero, then the data begins on the next word after the record id. * If nonzero, then the data is in the specifed block number in the * overflow file, and this record ends after the record id. */ typedef struct record_header_t record_header_t; struct record_header_t { short r_idlen; /* length of id (bytes) */ int r_nextrecord; /* offset to next record header (words) */ int r_datalen; /* length of record data (bytes) */ int r_bigdatabns; /* big data block number and size, or zero */ char r_id[MAX_IDLEN]; /* storage for id (and possibly data) */ }; #define ID_DELETED -1 /* special id value for deleted record */ #define ID_ENDGROUP -2 /* special id value for end of group */ #define ID_ENDBLOCK -3 /* special id value for end of current block */ #define ID_MINVALUE -3 /* lowest magic id value */ /* * Record handling macros */ /* Return whether or not the record data is in large record blocks */ #define is_bigdata(rp) ((rp)->r_bigdatabns != 0) /* Return whether or not this record is deleted */ #define is_deleted(rp) ((rp)->r_idlen == ID_DELETED) /* Return whether or not this is the end of group */ #define is_endgroup(rp) ((rp)->r_idlen == ID_ENDGROUP) /* Return whether or not this is the end of the block */ #define is_endblock(rp) ((rp)->r_idlen == ID_ENDBLOCK) /* * Constants for handling PI/open UFS dynamic files * (partitioned, alternate key, and recoverable) */ #define FIRST_INDX_SUBFILE 2 #define NUM_AKFILES_FIELD 2 #define AU_FLAG_FIELD 3 #define FIRST_INDEX_FIELD 11 #define FIELD_NAME 2 #define NO_NULLS_FLAG 8 /* * Constant for determining the number of bytes in a primary block header */ #define PRIMARY_HEADER_BYTES (offsetof(block_header_t, b_vardata) + sizeof(primary_block_t)) /* END-CODE */