home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Education Master 1994 (4th Edition)
/
EDUCATIONS_MASTER_4TH_EDITION.bin
/
files
/
progng_c
/
smallc
/
srt.cs
< prev
next >
Wrap
Text File
|
1994-01-01
|
9KB
|
334 lines
/* SDB - sort routines */
#include "stdio.h"
#include "sdbio.h"
extern int dbv_token;
extern char dbv_tstring[];
extern int dbv_tvalue;
/* get_skeys - get sort key list */
static struct skey *get_skeys(sptr)
struct scan *sptr;
{
struct skey *skeys,*newskey,*lastskey;
/* parse a list of attribute names */
skeys = lastskey = NULL;
while (TRUE) {
/* get attribute name */
if (db_ntoken() != ID)
return (db_nerror(SYNTAX));
/* allocate a sort key structure */
if ((newskey = malloc(sizeof(struct skey))) == NULL)
return (db_nerror(INSMEM));
/* initialize the sort key structure */
newskey->sk_next = NULL;
/* lookup the attribute name */
if (!find_attr(sptr,newskey,dbv_tstring)) {
free(newskey);
return (NULL);
}
/* check for ascending or descending */
if (db_token() == ASCENDING || dbv_token == DESCENDING) {
newskey->sk_type = dbv_token;
db_ntoken();
}
else
newskey->sk_type = ASCENDING;
/* link the sort key structure into the list */
if (lastskey == NULL)
skeys = newskey;
else
lastskey->sk_next = newskey;
lastskey = newskey;
/* check for more attributes */
if (db_token() != ',')
break;
db_ntoken();
}
/* return successfully */
return (skeys);
}
/* db_sort - sort tuples in a relation */
int *db_sort(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9)
char *fmt;
{
struct scan *sptr1,*sptr2,*sptr3; /*dns*/
struct skey *skeys;
int result;
/* check for a command line */
if (fmt != NULL)
db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9);
/* checks for relation name */
if (db_token() == ID)
db_ntoken();
else
strcpy(dbv_tstring,"sdbcur");
/* open the relation */
if ((sptr1 = db_ropen(dbv_tstring)) == NULL)
return (FALSE);
if ((sptr2 = db_ropen(dbv_tstring)) == NULL) {
db_rclose(sptr1);
return (FALSE);
}
if ((sptr3 = db_ropen(dbv_tstring)) == NULL) { /*dns*/
db_rclose(sptr1); /*dns*/
db_rclose(sptr2); /*dns*/
return (FALSE); /*dns*/
}
/* checks for "<relation-name> by <sort-list>" */
if (db_ntoken() != BY)
return (db_ferror(SYNTAX));
if ((skeys = get_skeys(sptr1)) == NULL) {
db_rclose(sptr1);
db_rclose(sptr2);
db_rclose(sptr3); /*dns*/
return (FALSE);
}
/* do the sort */
result = sort(skeys,sptr1,sptr2,sptr3); /*dns*/
/* close the relation */
db_rclose(sptr1);
db_rclose(sptr2);
db_rclose(sptr3); /*dns*/
/* free the sort keys */
free_skeys(skeys);
return (result);
}
/* free_skeys - free a list of sort keys */
static free_skeys(skeys)
struct skey *skeys;
{
struct skey *thisskey;
for (thisskey = skeys; skeys != NULL; thisskey = skeys) {
skeys = skeys->sk_next;
free(thisskey);
}
}
/* find_attr - find an attribute */
static int find_attr(sptr,newskey,aname)
struct scan *sptr; struct skey *newskey; char *aname;
{
struct attribute *aptr;
int i,astart;
/* loop through each attribute within the relation */
astart = 1;
for (i = 0; i < NATTRS; i++) {
/* get a pointer to the current attribute */
aptr = &sptr->sc_relation->rl_header.hd_attrs[i];
/* check for last attribute */
if (aptr->at_name[0] == 0)
break;
/* check for attribute name match */
if (db_sncmp(aname,aptr->at_name,ANSIZE) == 0) {
newskey->sk_start = astart;
newskey->sk_aptr = aptr;
return (TRUE);
}
/* update the attribute start */
astart += aptr->at_size;
}
/* attribute name not found */
return (db_ferror(ATUNDF));
}
/* sort - sort the relation */
static int sort(skeys,sptr1,sptr2,sptr3)
struct skey *skeys; struct scan *sptr1,*sptr2,*sptr3;
{
/* unsigned int j,k,l,r; dns */
long int passes,swaps; /*dns*/
int i, j, m, n; /*dns*/
int rec1 = 0; /*dns*/
int rec2 = 0; /*dns*/
int rec3 = 0; /*dns*/
int dns = 0; /*dns*/
FILE *test; /*dns*/
passes = 0L;
swaps = 0L;
/*dns ---> */
test = fopen("sort.dat", "w");
n = sptr1->sc_relation->rl_tcnt;
m = n;
while( m>1 ) {
passes++;
if ((m/=3.14159) < 1) m = 1;
for ( j=1; j<=n-m; j++ ) {
if( rec1 != j+m ) {
if(dns) fprintf(test,"Read1: %d\n", j+m);
if (!db_rget(sptr1, rec1=j+m)) return (FALSE);
}
for ( i=j; i>=1; i-=m ) {
if( rec2 != i ) {
if(dns) fprintf(test,"Read2: %d\n", i);
if (!db_rget(sptr2, rec2=i)) return (FALSE);
}
if (compare(skeys,sptr1,sptr2) > 0)
break;
if(rec3 != i+m) {
if(dns) fprintf(test,"Read3: %d\n", i+m);
if (!db_rget(sptr3, rec3=i+m)) return (FALSE);
}
if(dns) fprintf(test,"Write 3,2: %d from %d\n", i+m, i);
assign( sptr3, sptr2 );
swaps++;
}
if(rec1 != i+m) {
if(rec3 != i+m) {
if(dns) fprintf(test,"Read 3: %d\n", i+m);
if (!db_rget(sptr3, rec3=i+m)) return (FALSE);
}
if(dns) fprintf(test,"Write 3,1: %d from %d\n", i+m, j+m);
assign( sptr3, sptr1 );
swaps++;
}
}
}
fclose(test);
/*
l = 2;
r = sptr1->sc_relation->rl_tcnt;
k = r;
do {
for (j = r; j >= l; j--) {
if (!db_rget(sptr1,j-1))
return (FALSE);
if (!db_rget(sptr2,j))
return (FALSE);
if (compare(skeys,sptr1,sptr2) > 0) {
swap(sptr1,sptr2);
k = j;
swaps++;
}
}
l = k + 1;
for (j = l; j <= r; j++) {
if (!db_rget(sptr1,j-1))
return (FALSE);
if (!db_rget(sptr2,j))
return (FALSE);
if (compare(skeys,sptr1,sptr2) > 0) {
swap(sptr1,sptr2);
k = j;
swaps++;
}
}
r = k - 1;
passes++;
} while (l <= r);
*/
printf("[ Passes: %ld Swaps: %ld ]\n",passes,swaps);
return (TRUE);
}
/* compare - compare two tuples */
static int compare(skeys,sptr1,sptr2)
struct skey *skeys; struct scan *sptr1,*sptr2;
{
struct skey *cskey;
int result;
for (cskey = skeys; cskey != NULL; cskey = cskey->sk_next)
if ((result = cattr(cskey,sptr1,sptr2)) != 0)
break;
return (result);
}
/* cattr - compare two attributes */
static int cattr(cskey,sptr1,sptr2)
struct skey *cskey; struct scan *sptr1,*sptr2;
{
int astart,aend,i;
astart = cskey->sk_start;
aend = astart + cskey->sk_aptr->at_size;
for (i = astart; i < aend; i++)
if (sptr1->sc_tuple[i] != sptr2->sc_tuple[i])
break;
if (i == aend)
return (0);
if (sptr1->sc_tuple[i] < sptr2->sc_tuple[i])
if (cskey->sk_type == ASCENDING)
return (-1);
else
return (1);
else
if (cskey->sk_type == ASCENDING)
return (1);
else
return (-1);
}
/* swap - swap two tuples */
/* dns
static int swap(sptr1,sptr2)
struct scan *sptr1,*sptr2;
{
unsigned int tnum1,tnum2;
tnum1 = sptr1->sc_atnum;
tnum2 = sptr2->sc_atnum;
if (!db_rput(sptr1,tnum2))
return (FALSE);
if (!db_rput(sptr2,tnum1))
return (FALSE);
return (TRUE);
}
dns */
/* assign - assign one tupple to another */
static int assign(sptr1,sptr2)
struct scan *sptr1,*sptr2;
{
unsigned int tnum1,tnum2;
tnum1 = sptr1->sc_atnum;
if (!db_rput(sptr2,tnum1))
return (FALSE);
return (TRUE);
}