238 lines
8.4 KiB
C
238 lines
8.4 KiB
C
|
/******************************************************************************
|
||
|
*
|
||
|
* 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 */
|