home *** CD-ROM | disk | FTP | other *** search
- /*
- * INXRTNS.C - index file support routines
- *
- * Copyright (c) 1987, Jim Mischel
- * Modifications:
- *
- * 08/13/87 - jim - original coding
- * 08/21/87 - jim - flush the buffer after every write (iwrite_dat and iwrite_inx)
- */
-
- #include "inxdefs.h"
-
-
- /************************************************************************/
- /* */
- /* Internal support routines */
- /* */
- /************************************************************************/
-
- /*
- * iget_next() - read the next index record in sequence.
- * If successful, '*irec' contains the next index record and the function
- * returns 0.
- * If unsuccessful, '*irec' is undefined and the function returns EOF.
- */
- int iget_next(df_rec *db_control, inx_rec *irec)
- {
- /* see if we've already reached the end of the file */
- if (irec->if_flags & ETHRD) {
- db_control->df_flags |= DF_EOF;
- return(EOF);
- }
-
- if (irec->if_flags & RTHRD) { /* Right node is a thread pointer */
- if (iread_inx(db_control,irec->if_right_node))
- return(EOF);
- }
- else { /* Right node is a tree pointer */
-
- /*
- * Read the right node, then follow the left nodes until we come to a leaf.
- * We'll know a leaf when the left node pointer is a thread pointer.
- */
- if (iread_inx(db_control,irec->if_right_node))
- return(EOF);
- while (!(db_control->df_inx_buff.if_flags & LTHRD))
- if (iread_inx(db_control,db_control->df_inx_buff.if_left_node))
- return(EOF);
- } /* else */
-
- return(0);
- } /* iget_next */
-
- /*
- * iget_prev() - read the previous index record in sequence.
- * If successful, '*irec' contains the previous index record and the function
- * returns 0.
- * If unsuccessful, '*irec' is undefined and the function returns EOF.
- */
- int iget_prev(df_rec *db_control, inx_rec *irec)
- {
- if (irec->if_flags & BTHRD) {
- db_control->df_flags |= DF_TOF;
- return(EOF);
- }
-
- if (irec->if_flags & LTHRD) { /* Left node is a thread pointer */
- if (iread_inx(db_control,irec->if_left_node))
- return(EOF);
- }
- else { /* Left node is a tree pointer */
-
- /*
- * Read the left node, then follow the right nodes until we come to a leaf.
- * We'll know a leaf when the right node pointer is a thread pointer.
- */
- if (iread_inx(db_control,irec->if_left_node))
- return(EOF);
- while (!(db_control->df_inx_buff.if_flags & RTHRD))
- if (iread_inx(db_control,db_control->df_inx_buff.if_right_node))
- return(EOF);
- } /* else */
-
- return(0);
- } /* iget_prev */
-
- /*
- * isearch() - searches for key value '*key' in data file using a simple
- * binary tree search.
- * The function returns:
- * -1 : The specified key was not found. '*db_control->df_inx_buff'
- * would be the parent if '*key' was added to the file.
- * '*db_control->df_dat_buff' contains the data record last read.
- * 0 : The specified key was found. '*db_control->df_inx_buff' contains
- * the index record and '*db_control->df_dat_buff' contains the
- * data record.
- * 1 : The specified key was not found. '*db_control->df_inx_buff'
- * would be the parent if '*key' was added to the file.
- * '*db_control->df_dat_buff' contains the data record last read.
- * 2 : An error was encountered reading either the index or the data file.
- * '*db_control->df_inx_buff' and '*db_control->df_dat_buff' are
- * undefined.
- */
- int isearch(df_rec *db_control, char *key)
- {
- if (iget_root(db_control))
- return(ierrno);
-
- /* Binary tree search */
- while (1) {
-
- /* read the data record */
- if (iread_dat(db_control,db_control->df_inx_buff.if_dat_ptr))
- return(2); /* data file read error */
-
- switch ((*db_control->df_cmp)(key,db_control->df_key_ptr)) {
- case -1 : /* key is less than data record key */
- if (db_control->df_inx_buff.if_flags & LTHRD)
- return(-1); /* thread pointer (not found) */
- if (iread_inx(db_control,db_control->df_inx_buff.if_left_node))
- return(2); /* index file read error */
- break;
- case 0 :
- return(0); /* found */
- case 1 : /* key is greater than data record key */
- if (db_control->df_inx_buff.if_flags & RTHRD)
- return(1); /* right thread (not found) */
- if (iread_inx(db_control,db_control->df_inx_buff.if_right_node))
- return(2); /* inx file read error */
- break;
- default :
- puts("invalid return value from comparison routine");
- return(2);
- } /* switch */
- } /* while */
- } /* isearch */
-
- /*
- * iget_root() - reads the root of the binary tree into the index buffer.
- * Returns 0 if successful, error status if unsuccessful. If the file
- * is empty, EOF is returned. If unsuccessful, the contents of the index
- * buffer is undefined.
- */
- int iget_root(df_rec *db_control)
- {
- if (iread_inx(db_control,0L))
- return(ierrno);
- if (db_control->df_inx_buff.if_left_node == 0L)
- return(ierror(EOF)); /* empty file */
- if (iread_inx(db_control,db_control->df_inx_buff.if_left_node))
- return(ierrno);
- return(0);
- } /* iget_root */
-
-
- /************************************************************************/
- /* */
- /* File I/O primitives */
- /* */
- /* These are the only routines that actually access the files. */
- /* */
- /************************************************************************/
-
- /*
- * iread_inx() - reads the index record at seek_pos into the index buffer.
- * Returns 0 if successful, I_INXRD if unsuccessful. If unsuccessful,
- * the contents of the index buffer is undefined.
- */
- int iread_inx(df_rec *db_control, long seek_pos)
- {
- if (fseek(db_control->df_inx_file,seek_pos,SEEK_SET))
- return(ierror(I_INXRD));
- db_control->df_inx_ptr = seek_pos;
- if (fread(&db_control->df_inx_buff,sizeof(inx_rec),1,
- db_control->df_inx_file) != 1)
- return(ierror(I_INXRD));
- return(ierror(0));
- } /* iread_inx */
-
- /*
- * iwrite_inx() - write the record from 'irec' to the index file at position
- * 'seek_pos'. Returns 0 if successful, I_INXWT if unsuccessful.
- */
- int iwrite_inx(df_rec *db_control, inx_rec *irec, long seek_pos)
- {
- if (fseek(db_control->df_inx_file,seek_pos,SEEK_SET))
- return(ierror(I_INXWT));
- db_control->df_inx_ptr = seek_pos;
- if (fwrite(irec,sizeof(inx_rec),1,db_control->df_inx_file) != 1)
- return(ierror(I_INXWT));
- if (fflush(db_control->df_inx_file))
- return(ierror(I_INXWT));
- return(ierror(0));
- } /* iwrite_inx */
-
- /*
- * iread_dat() - reads the data record at seek_pos into the data buffer.
- * Returns 0 if successful, I_DATRD if unsuccessful. If unsuccessful,
- * the contents of the data buffer is undefined.
- */
- int iread_dat(df_rec *db_control, long seek_pos)
- {
- if (fseek(db_control->df_dat_file,seek_pos,SEEK_SET))
- return(ierror(I_DATRD));
- db_control->df_dat_ptr = seek_pos;
- if (fread(db_control->df_dat_buff,db_control->df_rec_size,1,
- db_control->df_dat_file) != 1)
- return(ierror(I_DATRD));
- return(ierror(0));
- } /* iread_dat */
-
- /*
- * iwrite_dat() - write the record from 'datrec' to the data file at position
- * 'seek_pos'. Returns 0 if successful, I_DATWT if unsuccessful.
- */
- int iwrite_dat(df_rec *db_control, void *datrec, long seek_pos)
- {
- if (fseek(db_control->df_dat_file,seek_pos,SEEK_SET))
- return(ierror(I_DATWT));
- db_control->df_dat_ptr = seek_pos;
- if (fwrite(datrec,db_control->df_rec_size,1,db_control->df_dat_file) != 1)
- return(ierror(I_DATWT));
- if (fflush(db_control->df_dat_file))
- return(ierror(I_DATWT));
- return(ierror(0));
- } /* iwrite_dat */
-
- /*
- * ierror() - set the global variable 'ierrno' to the value supplied in 'e'
- * and return the error number.
- */
- int ierror(int e)
- {
- ierrno = e;
- return(ierrno);
- }
-
- /************************************************************************/
- /* */
- /* Comparison routines */
- /* */
- /* These routines all return -1 if *arg1 < *arg2 */
- /* 0 if *arg1 == *arg2 */
- /* 1 if *arg1 > *arg2 */
- /************************************************************************/
-
- int icmp_uchar(void *arg1, void *arg2)
- {
- return ((*(unsigned char *)arg1 < *(unsigned char *)arg2) ? -1 :
- (*(unsigned char *)arg1 > *(unsigned char *)arg2) ? 1 : 0);
- }
-
- int icmp_schar(void *arg1, void *arg2)
- {
- return ((*(signed char *)arg1 < *(signed char *)arg2) ? -1 :
- (*(signed char *)arg1 > *(signed char *)arg2) ? 1 : 0);
- }
-
- int icmp_uint(void *arg1, void *arg2)
- {
- return ((*(unsigned int *)arg1 < *(unsigned int *)arg2) ? -1 :
- (*(unsigned int *)arg1 > *(unsigned int *)arg2) ? 1 : 0);
- }
-
- int icmp_sint(void *arg1, void *arg2)
- {
- return ((*(signed int *)arg1 < *(signed int *)arg2) ? -1 :
- (*(signed int *)arg1 > *(signed int *)arg2) ? 1 : 0);
- }
-
- int icmp_ulong(void *arg1, void *arg2)
- {
- return ((*(unsigned long *)arg1 < *(unsigned long *)arg2) ? -1 :
- (*(unsigned long *)arg1 > *(unsigned long *)arg2) ? 1 : 0);
- }
-
- int icmp_slong(void *arg1, void *arg2)
- {
- return ((*(signed long *)arg1 < *(signed long *)arg2) ? -1 :
- (*(signed long *)arg1 > *(signed long *)arg2) ? 1 : 0);
- }
-
- int icmp_string(void *arg1, void *arg2)
- {
- int r;
-
- return(((r = strcmp((char *)arg1, (char *)arg2)) == 0) ? 0 :
- (r > 0) ? 1 : -1);
- }
-
- #ifdef FLOAT_KEY
-
- int icmp_float(void *arg1, void *arg2)
- {
- return ((*(float *)arg1 < *(float *)arg2) ? -1 :
- (*(float *)arg1 > *(float *)arg2) ? 1 : 0);
- }
-
- int icmp_double(void *arg1, void *arg2)
- {
- return ((*(double *)arg1 < *(double *)arg2) ? -1 :
- (*(double *)arg1 > *(double *)arg2) ? 1 : 0);
- }
- #endif