UpdateHeader
Update the header portion of a c-tree file.
Short Name
PUTHDR()
Type
Low-Level function
Declaration
COUNT UpdateHeader(FILNO filno, LONG hdrval, COUNT mode)
Description
In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering
UpdateHeader() permits an application to update certain fields in a file’s header record provided the file is opened in ctEXCLUSIVE mode.
Mode |
Description |
---|---|
ctSERNUMhdr |
Ever increasing automatic sequence number. |
ctSUSSRLSEGhdr |
Suspend the serial segment handling for data file datno. (YES or NO). |
ctTSTAMPhdr |
Time stamp of last close after updates. |
ctNUMENThdr |
Number entries in file. |
ctTIMEIDhdr |
Creation time stamp used as part of unique ID. |
ctFLAVORhdr |
Change byte ordering. |
ctADDUNQFRShdr |
Add unique keys before allocating space for the data record from the data file. If a unique key add fails, the operation fails immediately; if it succeeds, the operation continues. |
ctALIGNhdr |
Change byte alignment. |
ctISAMKBUFhdr |
Disable/enable ISAM key buffering. |
ctISAMKBUFctx |
Disables/enable ISAM key buffering in the current context only. |
ctEXTSIZhdr |
Reset file extension size. |
ctLXTSIZhdr |
Change the large extent size in the XCREblk. For transaction controlled files, ctTRNLOG, this cannot be zero. |
ctMXFILZhdr |
Maximum file size in XCREblk (only if larger than the current value.) |
ctSCANCACHEhdr |
Toggles between the LRU cache algorithm and the scanner cache algorithm. Set hdrval to YES or NO to toggle. This mode is only valid for data files. |
ctSPLREFRESHhdr |
Refresh the dedicated cache pages so that they may be assigned to different pages of the file. |
ctSPLRESUMEhdr |
Restart the use of dedicated pages after a call to stop their use. |
ctSPLSTOPhdr |
Stop using dedicated cache for this file. |
ctIDfieldOverRide |
Turn on and off the ability to override automatic IDfield values. Override is per user, per file. Nonzero hdrval turns on; zero hdrval restores standard operation. |
ctSKIPSAVEhdr |
Suppresses or restores the update flag setting for the specified non-transaction-controlled file until it is physically closed and reopened. It is intended for temporary files not requiring persistence. |
ctSKIPSAVEISAMhdr |
Enables or disables file system cache flush calls for the specified data file and all its associated ISAM index files. |
ctIFIL3hdr |
Enables or disables (YES/NO) the V12 default IFIL resource storage format (see also the SUPPRESS_PATH_IN_IFIL server configuration keyword). The ctIFIL3hdr format supports several new naming options for alternate indexes (IFIL.aidxnam), and improves behavior when copying or renaming files with alternative index names. Disabling the ctIFIL3hdr for files using the new naming options may lead to the indexes becoming unusable. |
ctADDKYDFRhdr |
Toggles the deferred key add feature. |
ctLOCKDFRhdr |
Toggles the file state for deferred closes with pending locks on a file. |
ctTRNPERShdr |
Toggles the file state for persisted transaction unlock requests. |
ctIICThdr |
Enables the Immediate Independent Commit Transaction (IICT). This is an auto commit ISAM update executed while a transaction is pending for the same user (thread). IICT is independent of the existing transaction: it is as if another user/thread is executing the IICT. |
ctXFLSEThdr |
Sets extended file mode to lower-order two bytes of the hdrval parameter. |
ctXFL_ONhdr |
Turns on the lower-order two bytes of hdrval in the extended file mode. |
ctXFLOFFhdr |
Turns off the lower-order two bytes of hdrval in the extended file mode. |
ctUNIQUIDhdr |
Assigns a new unique file ID to the specified file. hdrval is ignored. File must be open in exclusive mode. Sets the file ID to a unique value using one of these methods:
|
ctMAXPARTMBRhdr |
Set maximum number of active partitions on a partitioned file. When a new partition is created, if the new number of active partitions exceeds the limit, the oldest partitions are purged. |
ctNOISMKEYUPDhdr |
Restrict ISAM key updates for calling connection only. Remains in effect for that open instance of the index file until its close, or it can be turned off with an additional PUTHDR() call of NO. |
Note: Use this function with extreme care as you are altering c-tree file headers, which can impact availability and/or integrity of your data. This function is intended more for advanced file recovery operations than for routine production use.
Automatic TRAN/noTRAN File Support
It is possible to create files in non-TRANPROC environments (e.g., FPUTFGET or single-user non-TRANPROC) which will be transaction ready, automatically, when they are opened in a TRANPROC environment. Further, they will automatically revert back to non-TRANPROC when returned to a non-TRANPROC environment.
In non-TRANPROC environments, it is possible to disable this behavior by adding #define ctBEHAV_NOTRANFILE to ctoptn.h.
LOGIDX
A subtle change in how the LOGIDX file mode bit is handled has been introduced: Setting the LOGIDX bit on in the file mode used to open a file (ctXFL_ONhdr) will enable this feature (high speed index recovery) even if the file was not created with this file mode.
Mirrored Files
File mirroring status is maintained as an extended header attribute. When disabling mirroring, this bit can be permanently un-set in all physical files with the MIRRORD value with the ctXLOFFhdr mode.
Working with Temporary Files
For a temporary, non-transaction-controlled file, it may be desirable to avoid rewriting the header with the update flag set. This can be achieved for a non-transaction-controlled file by calling PUTHDR(filno, YES, ctSKIPSAVEhdr). Calling PUTHDR(filno, NO, ctSKIPSAVEhdr) restores the normal behavior for a file.
PUTHDR() called with the ctSKIPSAVEhdr fails if the file is open in shared mode and the caller does not have file definition permission on the file; or if the file is a transaction-controlled (ctTRNLOG) file.
Byte Ordering and Byte Alignment
This capability is useful for forcing different file alignment; for example, forcing byte alignment for the packing of data files. Remember, when c-tree is requested to create a data file in non-server mode, the alignment is dictated by the compiler used to create the c-tree executable. For example, Microsoft C defaults to word alignment, and most Unix systems default to double word alignment. The c-tree test utility (cttest) can be used to determine the alignment for your compiler. In non-server mode, the file flavor for the data file is dictated by the underlying CPU (i.e., Intel typically Low/High or Little Endian/Big Endian and most Motorola and RISC CPU’s are High/Low or Big Endian/Little Endian). The c-tree index file is always High/Low, regardless of the underlying CPU.
In the client/server model, the FairCom Server dictates the byte ordering of the data file (i.e., High/Low vs. Low/High) while the client application dictates the data file alignment.
The hdrval values for the ctFLAVORhdr and ctALIGNhdr modes are:
mode |
hdrval |
Explanation |
---|---|---|
ctFLAVORhdr |
1 2 |
LOW_HIGH HIGH_LOW |
ctALIGNhdr |
1 2 4 8 |
byte aligned word aligned double word aligned quad word aligned |
In addition to updating the header fields, the corresponding schema fields are also updated if the file already contains a schema (from a PutDODA() call). Typical usage would be to create a file, call PutDODA(), and call UpdateHeader() with a new alignment value. For example, if the data is byte aligned in your record, (regardless of the systems inherent alignment), calling UpdateHeader() after calling PutDODA() permits the DODA to properly reflect the field alignment. See ctalgn.c in the \ctree\source directory as an example utility.
Performance Enhancement
This ISAM access mode can be set by the UpdateHeader() function to boost performance. This mode prevents c-tree from updating the internal index buffer for every key of the current ISAM record. Especially useful if a large number of keys are defined.
Each ISAM data file is assigned, for each user, a set of key buffers containing the current key image for each index for the current ISAM position. To speed record access UpdateHeader() accepts the ctISAMKBUFhdr mode, which turns on and off the support of the key buffers for a particular ISAM data file for the calling user, (i.e., NOT all users with the file open).
UpdateHeader(datno, (LONG) 1, ctISAMKBUFhdr) turns off key buffer support, speeding access to the data records. The effect on performance will be most notable when the data file supports many indexes. (Any non-zero LONG value for the second parameter will turn off support.)
UpdateHeader(datno,(LONG) 0,ctISAMKBUFhdr) turns back on key buffer support (which is the default state of an ISAM file).
Notes
If the key buffer support is turned off, then the current ISAM position for the data file is set to zero which implies no current ISAM position. This indicates the application cannot perform updates to the file since the key buffers are required. See the limitation section below.
Unlike the previous UpdateHeader() modes, this mode does not make a permanent change to the file header and therefore does NOT require the file to be opened exclusively, and only applies to the user making the call.
With key buffer suppression is on, the file cannot be traversed by one key then by a different key. Only the key that established the ISAM position (i.e., with FirstRecord(), etc.) can be used in NextRecord() or PreviousRecord(). If the data file is traversed in physical order, then no ISAM key buffer is supported.
When a record is retrieved in this mode, it is not possible to directly do a ReWriteRecord(). ReWriteRecord() returns KBUF_ERR (121) because the ISAM buffers are not being maintained. Perform a rewrite by first calling ReadIsamData().
Immediate Independent Commit Transaction (IICT)
The Immediate Independent Commit Transaction, IICT, permits a thread with an active, pending transaction to also execute immediate commit transactions, even on the same physical file that may have been updated by the still pending (regular) transaction. An IICT is essentially an auto commit ISAM update, but with the added characteristic that an IICT can be executed even while a transaction is pending for the same user (thread).
It is important to note that the IICT is independent of the existing transaction: it is as if another user/thread is executing the IICT. The following pseudo code example demonstrates this independence:
Example
If we did not switch to IICT mode, the second add would have failed with a KDUP_ERR (2); however, the IICT mode made the second add use a separate transaction and the second add found a pending add for key U, hence the TPND_ERR. Just as if another thread had a key U add pending.
A data file and it's associated indices are put into IICT mode with a call
PUTHDR(datno,1,ctIICThdr)
and are restored to regular mode with a call
PUTHDR(datno,0,ctIICThdr)
It is possible in c-tree for a thread to open the same file in shared mode more than once, each open using a different user file number. And it is possible to put one or more of these files in IICT mode while the remaining files stay in regular mode.
Note: If a file has been opened more than once by the same thread, then the updates within a (regular) transaction made to the different file numbers are treated the same as if only one open had occurred.
These special filno values enable specific IICT operations:
Override IDENTITY Values
PUTHDR() using the ctIDfieldOverRide mode can turn on and off the ability to override the automatic IDfield values. The override is on a per user, per file basis. A nonzero hdrval turns on the override, and a zero hdrval restores the standard operation. When the override is on for a data file that supports an IDfield, then an add record operation does not fill-in the IDfield value. Whatever is passed in the record buffer is used for the IDfield. And a rewrite permits the IDfield value to change instead of generating the IDFL_CHG error. When the override is enabled, add record operations do not consume IDfield values.
Scanner Cache Feature
The index cache pages are managed using a least-recently-used (LRU) scheme. For data files, the LRU scheme is not always effective. In particular, when data file access or updates involve many different records with little or no revisiting of records once they have been processed, the LRU scheme can result in many cache pages to be assigned to recently accessed records. But, at least from the user’s perspective, there is little chance of revisiting these pages.
The advanced FairCom DB header mode, ctSCANCACHEhdr, allows an alternative caching strategy. For details, see Scanner Cache.
File Extension Size
The stand-alone parameters dxtdsiz and ixtdsiz can be adjusted with the ctEXTSIZhdr parameter. File extensions less than 32768 bytes for superfile hosts, or less than 16KB for transaction processed files or mirrored files will not be permitted. If a smaller value is given, the minimum is used instead. No extension size may exceed 65,535 bytes for a Standard file. Use an Extended file to get much larger extension sizes.
Locking Behavior When Opening the Same File Multiple Times in the Same Connection
FairCom DB supports opening the same file multiple times in the same connection assigning a different file number to each file or, in c-treeDB, a different file handle.
For details, see FairCom Server enhanced locking control for files opened multiple times in the same connection.
Turn on Replication for a Table
Use the PUTHDR() function to turn on replication for a table. The table must meet the following requirements:
Note: If these requirements aren't met the PUTHDR() call will fail with an error such as 99 or 775.
Example
With FairCom DB, table creation and enabling replication must happen within the same transaction, as shown in this example.
/* start transaction */
ctdbBegin(hSession);
/* create table */
if (ctdbCreateTable(hTable, "custmast", CTCREATE_NORMAL | CTCREATE_TRNLOG)) {
/* error */
}
/* open table in exclusive mode */
if (ctdbOpenTable(hTable, "custmast", CTOPEN_EXCLUSIVE)) {
/* error */
}
/* turn on replication for the table */
if (PUTHDR(ctdbGetDatno(hTable), YES, ctREPLICATEhdr)) {
/* error */
}
if (ctdbCommit(hSession)) {
/* error */
}
ctdbCloseTable(hTable);
Verify replication
Use the ctrepd utility to verify that the creation of the table is written as replicated entries in the source server's transaction logs.
ctrepd 1 0 -inow -w -m -f SOURCE_SERVER_NAME
Where:
-inow is start at the current position
-w is wide format
-m is print file names
-f is wait for more entries (press <ctrl>-c to terminate)
Example ctrepd output
Replication log reader connected to data source.
(waiting for more log entries...)
Starting scan with log 7, position 3352334
log nbr log pos (in hex) opcode tranno fileid tstamp flags filename
7 3350130 0x00331e72 CHKPNT 0 0 0 0x00
(waiting for more log entries...)
7 3353817 0x00332cd9 OPNFIL 27702 1512 4294968811 0x00 custmast.dat
7 3353054 0x003329de BEGTRAN 27701 0 1694005047 0x00
7 3358133 0x00333db5 CREIFIL 27701 1512 0 0x00 custmast.dat
7 3358689 0x00333fe1 SETDEFBLK 27701 1512 0 0x00 custmast.dat
7 3361059 0x00334923 SETDEFBLK 27701 1512 0 0x00 custmast.dat
7 3362729 0x00334fa9 ADDRES 27701 1512 0 0x00 custmast.dat
7 3363763 0x003353b3 ENDTRAN 27701 0 1694005055 0x00
7 3363805 0x003353dd SUCTRAN 27701 0 0 0x00
(waiting for more log entries...)
7 3363847 0x00335407 CLSFIL 27703 1512 1694005064 0x00
(waiting for more log entries...)
Return
Value |
Symbolic Constant |
Explanation |
---|---|---|
0 |
NO_ERROR |
Successful update. |
48 |
FMOD_ERR |
ctISAMKBUFhdr called with index file. |
62 |
LERR_ERR |
File not opened exclusively. |
116 |
IMOD_ERR |
Invalid mode value or called for non-server system. |
463 |
UQID_ERR |
TIMEID matches existing file ID. |
See c-tree Error Codes for a complete listing of valid c-tree error values.
The following arbitrary example determines the number of active records in file number 1, inflates the count by 10, and overrides the number of active records in the header of the data file with the new value.
Example
LONG NbrRecords,i,worklong;
printf("\nNumber of records = %ld",NbrRecords = DATENT(1));
if (error = UpdateHeader(1,NbrRecords+10,ctNUMENThdr))
printf("\nreturn from UpdateHeader is %d",error);
See also
PutDODA(), FirstRecord(), NextRecord(), PreviousRecord(), ReWriteRecord(), ReadIsamData()