Previous Topic

Next Topic

RebuildIFile

Incremental ISAM rebuild.

Short Name

RBLIFIL()

Type

ISAM function

Declaration

COUNT RebuildIFile(pIFIL ifilptr)  

Description

RebuildIFile() rebuilds the data file and index files referenced by the IFIL structure pointed to by ifilptr. The file(s) to be rebuilt MUST be closed. RebuildIFile() opens the file(s), performs the rebuild, and closes the files upon completion.

RebuildIFile() does the following:

  1. Resets the update corrupt flag updflg in the header of the data file.
  2. Rebuilds the internal delete stack chain in fixed-length files and rebuilds the internal delete management index in variable-length files.
  3. Removes the existing index file and builds an index, optimized for both size and speed, over the existing data file.
  4. If a SRLSEG exists, RebuildIFile() finds the highest serial number in use and updates the file header with that value.

The user data is not affected in any way.

If you desire the files to be rebuilt in directories that are not specified until run-time, then ifilptr->pfilnam should not be finalized until run-time.

If RESOURCES are defined, and if ifilptr->tfilno is set to updateIFIL, RebuildIFile() automatically places the current IFIL array into a resource record in the data file - even if the data file was created without resources. After writing the IFIL structure, RebuildIFile() checks to see if the IIDX or ISEG arrays have changed. If changes are detected, the new structures replace any existing structures in the data file or will be added if no structures were previously present.

Note: Do not use RebuildIFile() to add indices to an existing index, since the member headers are all at the front of the physical file with the key values afterward, and there is no slack space to add new member headers without recreating the physical index file. Therefore, first delete the physical index file and then do the rebuild if additional index members are added. You may also use PermIIndex() or TempIIndexXtd() as described in Section F.197 “PermIIndex” on page F-310 and Section F.259 “TempIIndexXtd” on page F-438.

Rebuild times can be optimized by increasing the number of temporary sort files used. Increase the #define MAX_HANDLES found in ctsort.h from its default of 50 to a larger number up to the maximum of 255. The value to use is a function of the size of the index to be rebuilt and the number of available file handles and is best determined by performing timing tests on the target system. The temporary files created during rebuild are c-tree Plus files. After changing ctsort.h, recompile the entire c-tree Plus library, including removing the object files and library, and the rebuild application.

The path and/or drive of the temporary sort files can be modified in non-server mode with minor changes to ctsort.h and ctsort.c as follows:

Change approximately line 32 of ctsort.h from:

   #define WORK_DRIVE_OR_PATH ""

to:

   pTEXT WORK_DRIVE_OR_PATH;

Now declare WORK_DRIVE_OR_PATH as an ‘extern’ in the rebuild application and assign the desired path. See also the GetCtTempFileName() function description.

A second method for decreasing rebuild times is to link the rebuild application with a single-user c-tree Plus library so that index caching will be used. To increase the size of the index cache, increase the number of index buffers (i.e., bufs parameter to InitISAM() or the first number of the parameter file initialization record). The index cache uses a hashing algorithm, therefore the larger the index cache the faster the rebuild will be. The size of the index cache can be calculated as follows:

memory(in bytes) = bufs *(sect * 128 + MAXLEN + 128)

MAXLEN, the maximum key length defined in ctopt2.h, defaults to 1024 bytes.

Automatic Duplicate Purge Logic - Prior to c-tree Plus V6.7, rebuilding a file with duplicate key values on an index for which duplicates were not allowed terminated the rebuild completely or left the indices in an inconsistent state. The index not supporting duplicates would not have an entry for the record while the other indices would have an entry for the record. For consistency, this is still the default behavior, but details concerning the duplicate keys are sent to a temporary text file instead of the console. The name of the temporary file is sent to the console and to CTSTATUS.FCS. This information is not subject to the RB_OUTPUT define. It happens automatically and may not be disabled.

Records containing the unwanted duplicates are marked deleted, and none of the indices will have an entry for this record. A copy of each deleted duplicate record is stored in a temporary file, which notes the position, length, and content of the record. CTSTATUS.FCS contains entries indicating how many duplicate keys were rejected, the name of the data file, the name of the temporary file, and a message indicating successful completion of the duplicate purge.

To implement the automatic duplicate purge behavior, where records with duplicate keys are purged from the data file and copied into a temporary file, one of the following two approaches is used:

  1. Incremental ISAM Structure Support (IFIL): Rebuilding files defined by an Incremental ISAM Structure is typically accomplished with RebuildIFile(). Setting ifilptr->tfilno to purgeIFIL, which is defined in ctport.h, instigates the new auto-purge logic. It is permissible to set ifilptr->tfilno to purgeIFIL + updateIFIL so both behaviors can be achieved.
  2. Parameter Files: For parameter files rebuilt with ctrbld.c, add #define ctRBLD_AUTO_PURGE when compiling ctrbld.c. This causes the parameter file rebuild to attempt automatic record purge if duplicate keys are rejected.

Note: If the record is longer than the operating system maximum unsigned integer (MUI), only MUI bytes are stored in the temporary file for this record. Typically, this will only be an issue with 16 bit systems where MUI will be 64K bytes.

To re-instate a deleted record, open the temporary file using c-tree Plus open calls, retrieve the desired record, and insert it back into the data file.

If purgeIFIL is used and a binary stream file can be opened, duplicate keys and bad serial numbers are automatically purged from the indices and the data records are deleted from the file. RebuildIFile() returns DUPJ_ERR (650) and the temporary stream file contains the deleted data records. This is an informational, not fatal, error.

If purgeIFIL is NOT used and an ASCII stream file can be opened, the duplicate keys and bad serial numbers are not added to the indices, but the data records remain in the file. RebuildIFile() returns DUPL_ERR (652), and lists the offending keys and data records in the stream file. Before V6.7, RebuildIFile() returned NO_ERROR (0) under this condition. DUPL_ERR is an informational, not fatal, error.

If a stream file cannot be opened, RebuildIFile() returns either KDUP_ERR (2) or KSRL_ERR (605) when duplicate keys and/or bad serial numbers are encountered. Further, no more indices are processed. That is, the rebuild does not run to completion as it does in the above two cases.

To rebuild a mirrored file, ensure the mirror is specified in ifilptr. RebuildIFile() copies the primary file to the mirrored name on successful completion.

Return

Value

Symbolic Constant

Explanation

0

NO_ERROR

Successful rebuild of ISAM files.

12

FNOP_ERR

Could not open file(s). Check isam_fil for the specific file number.

20

KMIN_ERR

Key length too large for node size.

22

FNUM_ERR

File number is out of range.

45

KLEN_ERR

Key length exceeds MAXLEN parameter in ctoptn.h.

46

FUSE_ERR

If ifilptr->dfilno >= 0, file number (range) already in use. If ifilptr->dfilno < 0, no block of numbers available.

107

IDRK_ERR

Too many index files for one data file. Increase MAX_DAT_KEY parameter in ctoptn.h.

109

IKRS_ERR

Too many key segments. Increase MAX_KEY_SEG parameter in ctoptn.h.

115

ISLN_ERR

Key segments do not equal key length.

120

RRLN_ERR

Not enough dynamic memory for record buffer.

122

RMOD_ERR

Attempt to change between fixed and variable length records.

123

RVHD_ERR

A variable-length record is not preceded by a valid record mark.

454

NSUP_ERR

Mirrored file rebuilds are not supported. Rebuild the primary if necessary and then copy to the mirrored file name.

484

485

 

Error opening sortwork file. Increase the number of file handles requested at c-tree Plus initialization time (InitISAM(), InitISAMXtd() or second value in parameter file Initialization Record).

605

KSRL_ERR

Bad serial number.

650

DUPJ_ERR

Informational: Duplicate records successfully purged.

652

DUPL_ERR

Duplicates found and listed in stream file.

See c-tree Plus Error Codes for a complete listing of valid c-tree Plus error values.

Example

extern IFIL    customer;
       COUNT   retval;

main() {

if (retval = InitISAM(10,10,16))
        printf("\nInitISAM error = %d",retval);

if (!(RebuildIFile(&customer)))
        printf("\nSuccessful rebuild");
    else
        printf("\nRebuildIFile isam_err = %d",isam_err);

CloseISAM();
}

Limitations

RebuildIFile() can be called from applications linked with the Standalone Multi-user (FPUTFGET) mode. RebuildIFile() opens the files in ctEXCLUSIVE mode, so no processes may access the file during rebuild. For performance reasons, single-user rebuilds are recommended.

To rebuild superfiles, call SuperfilePrepassXtd() prior to RebuildIFile().

See also

PermIIndex(), TempIIndexXtd(), GetCtTempFileName(), RebuildIFileXtd(), InitISAM(), CompactIFile(), SuperfilePrepassXtd(), and ISAM Functions in the c-tree Plus Programmer’s Reference Guide, which describes the ISAM parameters.