URL: http://www.firstbasesoftware.com/man/man3/getxhead.htm
Last modified: 12 September 1995
Copyright © by FirstBase Software.
[ Index of Contents] [ FirstBase RDBMS Overview]


NAME

getxhead, putxhead - read and write index header

SYNOPSIS

#include <firstbase/fb.h>

fb_getxhead(fd, bsmax, bsend)
int fd;
long *bsmax, *bsend;

fb_putxhead(fd, bsmax, bsend)
int fd;
long bsmax, bsend;

DESCRIPTION

As explained in the index(4) manual page, a database structure contains all of the elements needed for an entire database, including file names, descriptors and other variables that define an index. Fb_getxhead and fb_putxhead, along with a few other UNIX calls, enable the building and maintaining of complex (multi-field) flat FirstBase indexes.

Note: the following discussion concerns normal (flat) FirstBase indexes and does not apply to btree indexes. See btree(4) for more details on the FirstBase Btree+ indexes.

Formally, fb_getxhead and fb_putxhead read and write the header numbers needed to maintain a FirstBase index. Note that fb_getxhead uses two long pointers, i.e. the address to two long variables. In this manner, fb_getxhead reads two distinct variables from the index header fd. Fb_putxhead writes the two long values passed in to the index header indicated by fd.

But, fb_getxhead and fb_putxhead are just two of the pieces needed to update a complex index. The following discussion covers the complete index update task.

When a database is opened with an index using opendb(3), or when an index is tied to a database using openidx(3), the following variables from the database structure are initialized:

ifd
index file descriptor

ihfd
index header field descriptor

irecsiz
size of an index record

bsmax
binary search maximum, the index record count

bsend
binary search end point, i.e. the last sorted entry

irec
character buffer big enough for one index entry

ip
array of field pointers, the sort-by fields

afld
temporary space for a single field

bfld
temporary space for a single field

Each FirstBase index is a fixed length miniature database. Entering a new index entry into an open index is a two step procedure. The first step creates the string to be written to the index, while the second step does the actual write.

Again, the first step to adding a new index entry is to create the string to be written to the index. This index entry, the string that will be written to the index, needs to be well formed, i.e. it needs to be the exact number of characters or bytes to fit into an single index entry slot. The database variable irecsiz contains the total length of an index entry.

When a database index is opened, irecsiz is calculated by adding together the lengths of the fields being indexed (cdb_ip), plus a constant. Most of the constant represents the length of the record pointer, a string that is always FB_RECORDPTR (10) characters long. An additional one (1) is added to the constant to account for the NEWLINE at the end of the string. So, the constant added to the sum of the lengths is eleven (11).

It is also worth noting that the FirstBase data type of the fields being written to the index (the sort-by fields) determine whether the field is left or right justified. Numeric type fields (FB_OFNUMERIC) need to be right justified. Date fields require the shifting of the year to the front of the string. The FirstBase library routine makess(3) will produce the correct search string.

The following routine will create a proper string to be written to the index. Note that this routine depends on the index having been formally tied to the database via opendb(3) or openidx(3). If this is not the case, some of the variables from the list above will need to be provided.

   /*
    * make_entry - make an entry based on the current index
    */

   static make_entry(dp)
      fb_database *dp;

      {
         char buf[MAXLINE];
         int siz, i, ixfields;
         fb_field *fp;

         db->irec[0] = NULL;
         ixfields = dp->ifields - 1;
         for (i = 0; i < MAXBY && i < ixfields; i++){
            fp = dp->ip[i];
            strcpy(dp->afld, fp->fld);
            fb_makess(dp->afld, fp->type, fp->size);

            /* add this value to the index record buffer */
            strcat(dp->irec, dp->afld);
            }

         /* create the record pointer portion of the index record */
         sprintf(dp->afld, "%010ldn", dp->rec);
         strcat(dp->irec, dp->afld);
      }

The second step to adding an index entry to locate the proper place for this index entry to be written. To do this, fb_getxhead(3) is used to read header information about the index, seek to the the proper byte location, and write the index record entry. Once written, the index header is updated to reflect the new index entry.

The following code fragment does the job. Again, note that this code depends on the index being formally tied to the database, which may not be the case.

      /* get bsmax, bsend from index header file */
      fb_getxhead(dp->ihfd, &dp->bsmax, &dp->bsend);

      /* seek and write index entry */
      lseek(dp->ifd, dp->bsmax * dp->irecsiz, 0);
      write(dp->ifd, dp->irec, dp->irecsiz);

      /* redo header -- note: only bsmax changed */
      fb_putxhead(dp->ihfd, ++dp->bsmax, dp->bsend);

Using the above methods, a FirstBase multi-field flat indexes can be maintained at run time. Remember to close the file descriptors at some point -- closedb(3) will do this for those descriptors formally tied to the database structure. A sample program named key_add.c that puts this all together is in $FIRSTBASEHOME/applications/sample_src.

The FirstBase tool dbregen(1) can be used to resort an index and update the index header file without recreating the index (dbigen(1)).

SEE ALSO

btree(4), index(4), opendb(3), openidx(3), makess(3), endate(3), pad(3), rjustify(3).

DIAGNOSTICS

Fb_getxhead and fb_putxhead will return the error code FB_ERROR if any of the reads, writes, or seeks fail. An FB_AOK signal is returned on correct completion.

Note that neither of these routines implements any process locking around the critical sections, the read and write calls.


URL: http://www.firstbasesoftware.com/man/man3/getxhead.htm
Last modified: 12 September 1995
Copyright © by FirstBase Software.
[ Index of Contents] [ FirstBase RDBMS Overview]