home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 9
/
MEDIASHARE_09.ISO
/
cprog
/
btree.zip
/
EXERCISE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-16
|
8KB
|
355 lines
#include <stdio.h>
#include "dbfiles.hpp"
#include "btree.hpp"
long atol();
void pad(char *, int);
int compound_compare(union Key * , struct KeyGroup * , int );
main(int argc,char **argv)
{
char indxbuff[40];
char buff1[65];
char buff2[65];
int dups,reply,quit,index_exists,tfd,tok,lng,stat,print_key;
struct KeyGroup k,*kp;
union Key bk;
long lk;
double dk;
printf("==========================================================\n");
printf(" Test program to exercise the B+Tree\n");
printf("Copr. 1991 Larry A. Walker & Co. Sterling, Va 22170\n");
printf("==========================================================\n");
//
// Get the name of the index
//
if(argc == 2){
strcpy(indxbuff,*(argv+1));
}else{
printf("\n\nWhat is the name of the index\n");
gets(indxbuff);
}
index_exists = ( (tfd=open(indxbuff,O_RDONLY)) == -1 )?0:1;
if(index_exists){
close(tfd);
dups = 0;
lng = 0;
tok = UNDEF_KEY;
}else{
//
// Duplicates required needed for opening new index
//
printf("1. Duplicates allowed.\n");
printf("2. No duplicates allowed.\n");
printf("\nEnter a number to select an item.\n: ");
gets(buff1);
dups=atoi(buff1);
if( (dups < 1) || (dups > 2) ){
fprintf(stderr,"Must be either 1 or 2\n");
exit(1);
}
dups=(dups == 2)?0:1;
//
// Type of key required for opening new index
//
printf("Please enter the type of key to use.\n");
printf("%d. Variable length keys\n",VAR_LNG_KEY);
printf("%d. Fixed length keys\n",FIX_LNG_KEY);
printf("%d. Long keys\n",LONG_KEY);
printf("%d. Double keys\n",DOUBLE_KEY);
printf("\nEnter a number to select an item.\n: ");
gets(buff1);
tok=atoi(buff1);
switch(tok){
case VAR_LNG_KEY:
lng = -1;
break;
case FIX_LNG_KEY:
printf("Please enter the key length.\n: ");
gets(buff1);
lng = atoi(buff1);
break;
case LONG_KEY:
lng = sizeof(long);
break;
case DOUBLE_KEY:
lng = sizeof(double);
break;
default:
fprintf(stderr,"Invalid response.\n");
exit(1);
break;
}
}
// index_name, create, type of key,
// duplicates, fixed length key size
Btree tree(indxbuff, (index_exists)?0:CREATE, tok, dups, lng);
// If you already know the index exists, you can open it
// with default parameters as "Btree tree(indxbuff)"
// test the install routine
if(tok == UNDEF_KEY){
// then, we opened an index but don't know anything about
// it, we can however get the information
tok = (int)tree.ReportState(TYPE_OF_KEY);
dups = (int)tree.ReportState(DUPLICATES);
lng = (int)tree.ReportState(KEY_LENGTH);
printf("Type of key = ");
switch(tok){
case VAR_LNG_KEY:
printf("VAR_LNG_KEY");
break;
case FIX_LNG_KEY:
printf("FIX_LNG_KEY");
break;
case LONG_KEY:
printf("LONG_KEY");
break;
case DOUBLE_KEY:
printf("DOUBLE_KEY");
break;
}
printf(" duplicates = %s ",(dups)?"YES":"NO");
printf(" key length = %d ",lng);
printf("\n number of keys = %ld, last access %ld\n", tree.ReportState(NUMBER_OF_KEYS),tree.ReportState(LAST_ACCESS) );
}
printf("Turn on print error log? (y/n)\n: ");
gets(buff2);
if((buff2[0] == 'y') || (buff2[0] == 'Y')){
tree.set_display(ON,stderr);
tree.set_log(ON,"mylog",1); // third param 0 would be to truncate
// defaults to 1
}
quit=0;
if(tok == FIX_LNG_KEY){
if(tree.InstallCompare(compound_compare) == SUCCESS)
printf("Installed key compare routine\n");
}
while(!quit) {
printf( "\n===========================================\n");
printf( "|Pick an operation to perform on the index|\n");
printf( "|1. Find a key 2. Insert a key |\n");
printf( "|3. Delete a key 4. Next key |\n");
printf( "|5. Prior key 6. First key |\n");
printf( "|7. Last key 8. Current key |\n");
printf( "|9. Quit |\n");
printf( "===========================================\n");
printf( ": ");
gets(buff2);
reply = atoi(buff2);
print_key = 0;
switch(reply) {
case 1:
printf("Check index for what key?\n: ");
gets(buff2);
printf("finding ->%s<-\n",buff2);
switch(tok){
case VAR_LNG_KEY:
create_index_string(bk.key,buff2);
break;
case FIX_LNG_KEY:
if(strlen(buff2) < lng )
pad(buff2,lng);
memcpy(bk.key,buff2,lng);
break;
case LONG_KEY:
bk.long_key = atol(buff2);
break;
case DOUBLE_KEY:
bk.double_key = atof(buff2);
break;
}
if(tree.Locate(&bk) == FAIL) {
printf("not in index\n");
break;
} else {
if( (kp = tree.CurrentKey()) == NULL) {
printf("No current key\n");
break;
}
}
print_key = 1;
break;
case 3:
printf("What key to delete\n");
gets(buff2);
switch(tok){
case VAR_LNG_KEY:
create_index_string(bk.key,buff2);
break;
case FIX_LNG_KEY:
if(strlen(buff2) < lng )
pad(buff2,lng);
memcpy(bk.key,buff2,lng);
break;
case LONG_KEY:
bk.long_key = atol(buff2);
break;
case DOUBLE_KEY:
bk.double_key = atof(buff2);
break;
}
if( (stat = tree-=(&bk)) == FAIL) {
printf("Key not deleted\n");
}
else printf("Successful delete\n");
break;
case 2:
printf("What key to add\n: ");
gets(buff1);
switch(tok){
case VAR_LNG_KEY:
create_index_string(k.k.key,buff1);
break;
case FIX_LNG_KEY:
if(strlen(buff1) < lng )
pad(buff1,lng);
memcpy(k.k.key,buff1,lng);
break;
case LONG_KEY:
k.k.long_key = atol(buff1);
break;
case DOUBLE_KEY:
k.k.double_key = atof(buff1);
break;
}
printf("What data\n: ");
gets(buff2);
k.address = atol(buff2);
if( (stat = tree+= (&k) ) == FAIL){
printf("Key add failed\n");
}
break;
case 4:
kp = ++tree;
if(kp == NULL){
printf("next key not found\n");
break;
}
print_key = 1;
break;
case 5:
kp = --tree;
if(kp == NULL){
printf("previous key not found\n");
break;
}
print_key = 1;
break;
case 6:
kp=tree.First();
if(kp == NULL){
printf("first key not found\n");
break;
}
print_key = 1;
break;
case 7:
kp=tree.Last();
if(kp == NULL){
printf("last key not found\n");
break;
}
print_key = 1;
break;
case 8:
if((kp=tree.CurrentKey()) == NULL) {
printf("No current key\n");
break;
}
print_key = 1;
break;
case 9:
quit=1;
break;
}
switch(reply) {
// these items display the key in kp
case 1:
case 4:
case 5:
case 6:
case 7:
case 8:
if(print_key){
switch(tok){
case VAR_LNG_KEY:
create_c_string(buff1,kp->k.key);
printf("found ->%s<-\ndata -> %ld\n",buff1, kp->address);
break;
case FIX_LNG_KEY:
// this doesn't take care of
// a fix length key being
// a struct of info
memcpy(buff1,kp->k.key,lng);
buff1[lng] = 0;
printf("found ->%s<-\ndata -> %ld\n",buff1, kp->address);
break;
case LONG_KEY:
printf("found ->%ld<-\ndata -> %ld\n",kp->k.long_key, kp->address);
break;
case DOUBLE_KEY:
printf("found ->%f<-\ndata -> %ld\n",kp->k.double_key, kp->address);
break;
}
}
}
}
tree.Close();
exit(0);
}
//
// pad an area with null values to a length
//
void pad( char *ptr ,int lng)
{
int i;
for(i = strlen(ptr); i < lng; i++ ){
*(ptr+i) = (char)0;
}
}
//
// Function: compound_compare
//
// Discussion: Compare two compound values, returning the result
//
// Returns: -1 LT, 0 EQ, 1 GT
//
//
int compound_compare(union Key * value, struct KeyGroup * active_key, int lng){
char *ptr,*ptr1;
ptr=(char *)value->key;
ptr1=(char *)active_key->k.key;
for(int i = 0; i < lng;i++){
if(*ptr < *ptr1 )
return -1;
if(*ptr > *ptr1 )
return 1;
ptr++;ptr1++;
}
return 0;
}