home *** CD-ROM | disk | FTP | other *** search
- /* Database handling subroutines for benchmark interface
- **
- ** BYTE Magazine, Spring 1990
- **
- ** init_db: reads in db records, if file exists.
- ** lin_search_db: returns index with matching criteria
- ** sort_db: sorts on one field
- ** update_db: updates one field in one record
- ** add_entry_db: adds an entry, marks it current.
- ** dump_db: writes db out to a file
- ** free_db: frees up memory allocated by init_db
- */
-
- #include <stdio.h>
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <stdlib.h>
- #include <io.h>
- #include <string.h>
-
- #include "db.h"
-
- char init_db(char num_records_limit, db_rec** listptr, char * dbfilename)
- /* looks for dbfilename. If it exists, reads in records */
- /* returns number of records in database */
-
- {
- int i;
- char num_records=0;
- int dbfh;
-
- dbfh=open(dbfilename, O_BINARY|O_RDONLY);
-
- if(dbfh==-1)
- return 0;
- if( read(dbfh, &num_records, 1) <= 0){
- close(dbfh);
- return 0;
- }
-
- num_records=(num_records>num_records_limit-1)? \
- num_records_limit-1:num_records;
-
- /* allocate the memory */
-
- for(i=0; i<(int)num_records; i++){
- if ((*(listptr+i)=(db_rec*)malloc(sizeof(db_rec)))==NULL){
- num_records=(char)i;
- break;
- }
- }
-
- /* read-em in*/
- for(i=0; i<(int)num_records; i++){
- read(dbfh, (char*)(*(listptr+i)), sizeof(db_rec));
- }
-
- close(dbfh);
- return num_records;
- }
-
- int dump_db(char num_records, db_rec** listptr, char * dbfilename)
- /* dumps records to file */
- {
- int i;
- int dbfh;
-
- /* open file */
-
- dbfh=open(dbfilename, O_TRUNC|O_WRONLY|O_BINARY|O_CREAT);
-
- if (dbfh==-1)
- return 0;
- if( write(dbfh, &num_records, 1) <= 0){
- close(dbfh);
- return 0;
- }
-
- /* write-em */
-
- for(i=0; i<(int)num_records; i++){
- write(dbfh, (char*)(*(listptr+i)), sizeof(db_rec));
- }
-
- close(dbfh);
- return 1;
- }
-
- void free_db(char num_records, db_rec** listptr)
- /* frees all memory allocated to records */
- {
- int i;
-
- for(i=0; i<(int)num_records; i++){
- free(*(listptr+i));
- }
- }
-
- int lin_search_db(char startpos, char endpos, void** listptr, \
- int struct_offset, char crit_type_code, double crit)
- /* unsorted linear search. Return index of first match found, -1 on no match.
- ** crit=value to match. struct_offset=location of field to match.
- */
- {
- int i;
- int temp;
-
- switch(crit_type_code){
- case CHARCODE:
- for(i=(int)startpos;i<=(int)endpos;i++){
- if(*((char*)
- ((char *)(*(listptr+i))+struct_offset)) \
- ==(char)crit)
- return i;
- }
- return -1;
- case INTCODE:
- for(i=(int)startpos;i<=(int)endpos;i++){
- if(*((unsigned int*) \
- ((char *)(*(listptr+i))+struct_offset)) \
- ==(unsigned int)crit)
- return i;
- }
- return -1;
- case FLOATCODE:
- for(i=(int)startpos;i<=(int)endpos;i++){
- if(*((double *) \
- ((char *)(*(listptr+i))+struct_offset)) \
- ==(double)crit)
- return i;
- }
- return -1;
- case CHARPTRCODE:
- temp=(int) crit;
- for(i=(int)startpos;i<=(int)endpos;i++){
- if(strcmp( \
- ((char *)(*(listptr+i))+struct_offset),
- (char*)temp)==0)
- return i;
- }
- return -1;
- default:
- return -1;
- }
- }
-
-
- void sort_db( char num_records, void** listptr, \
- int struct_offset, char ft_code)
- /*
- ** quicksort for these structures
- ** adapted from Esakov-Weiss, _Data_Structures_
- **
- */
- {
-
- void** left;
- void** right;
- void** el;
- char num_remaining;
-
- void swap(void**, void**);
- int comp_fld_ptr(void**, void**, int, char);
-
- if (num_records<=1) return;
- left=listptr;
- right=listptr+(num_records-1);
- el=left;
-
- swap (el, right);
- el=right;
-
- while(left<right){
- while((comp_fld_ptr(left,el,struct_offset, ft_code)<0)&&(left<right))
- left++;
- while((comp_fld_ptr(right,el,struct_offset,ft_code)>=0)&&(left<right))
- right--;;
- if(left<right){
- swap(left,right);
- left++;
- }
- }
- if(right==listptr){
- swap(right, el);
- right++;
- }
-
- num_remaining=(right-listptr);
- sort_db(num_remaining, listptr, struct_offset, ft_code);
- sort_db(num_records-num_remaining, right, struct_offset, ft_code);
-
- }
-
- void swap(void** a, void** b)
- {
- void* temp;
- temp=*a;
- *a=*b;
- *b=temp;
- }
-
- int comp_fld_ptr(void** a, void** b, int s_off, char f_code)
- {
-
- switch(f_code){
- case CHARCODE:
- if( *((char*) ((char *)(*a)+s_off)) <
- *((char*) ((char *)(*b)+s_off)))
- return 1;
- if( *((char*) ((char *)(*a)+s_off)) >
- *((char*) ((char *)(*b)+s_off)))
- return -1;
- return 0;
-
- case INTCODE:
- if( *((unsigned int*) ((char *)(*a)+s_off)) <
- *((unsigned int*) ((char *)(*b)+s_off)))
- return 1;
- if( *((unsigned int*) ((char *)(*a)+s_off)) >
- *((unsigned int*) ((char *)(*b)+s_off)))
- return -1;
- return 0;
-
- case FLOATCODE:
- if( *((double*) ((char *)(*a)+s_off)) <
- *((double*) ((char *)(*b)+s_off)))
- return 1;
- if( *((double*) ((char *)(*a)+s_off)) >
- *((double*) ((char *)(*b)+s_off)))
- return -1;
- return 0;
-
- case CHARPTRCODE:
- return strcmp(((char *)(*b)+s_off), \
- ((char *)(*a)+s_off));
- }
- return 0;
- }
-
-
- void update_db(int index, void** listptr, int struct_offset, \
- char ft_code, double newvalue)
- /*
- ** updates a db entry.
- */
-
- {
-
- int temp;
-
- switch(ft_code){
- case CHARCODE:
- *((char*) \
- ((char*)(*(listptr+index))+struct_offset))= \
- (char) newvalue;
- break;
-
- case INTCODE:
- *((unsigned int*) \
- ((char*)(*(listptr+index))+struct_offset))= \
- (unsigned int) newvalue;
- break;
-
- case FLOATCODE:
- *((double *) \
- ((char*)(*(listptr+index))+struct_offset))= \
- (double) newvalue;
- break;
-
- case CHARPTRCODE:
- temp=(int) newvalue;
- strcpy(
- ((char*)(*(listptr+index))+struct_offset), \
- (char*) temp);
- }
- }
-
- char add_entry_db( char num_records_limit, char num_records, \
- db_rec** listptr, char* entryname)
- /* adds a db entry. Returns number of records in new db. If records in
- ** equals records out, you're out of room.
- */
-
- {
- int i;
- int curroff;
-
- if(num_records==num_records_limit) return num_records;
-
- /* allocate the memory */
- if((*(listptr+num_records)=(db_rec*)malloc(sizeof(db_rec)))==NULL)
- return num_records;
-
- /* clear current entry */
- if(num_records!=0){
- curroff=lin_search_db(0, num_records-1, (void**) listptr, \
- offset_in_struc(db_rec,currflag), INTCODE, 1);
- if(curroff>(-1)){
- update_db(curroff,(void**) listptr,
- offset_in_struc(db_rec,currflag), INTCODE, 0);
- }
- }
-
- /* zero out new entry */
- for(i=0; i<sizeof(db_rec); i++)
- *(*((char**)listptr+num_records)+i)=0;
-
- /* make new entry current */
- update_db((int)num_records,(void**) listptr,
- offset_in_struc(db_rec,currflag), INTCODE, 1);
-
- /* give it a name */
- update_db((int)num_records,(void**) listptr,
- offset_in_struc(db_rec,name), CHARPTRCODE, (int)entryname);
-
- return num_records+1;
- }
-
- void dup_rec( void** listptr, int destoff, int sourceoff)
- /*
- ** duplicates records.
- */
-
- {
- int i;
-
- for(i=0; i<sizeof(db_rec); i++){
- *(*((char**)listptr+destoff)+i)= \
- *(*((char**)listptr+sourceoff)+i);
- }
-
- }
-