mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 08:24:18 +00:00
1 line
8.5 KiB
C
1 line
8.5 KiB
C
/* SDB - sort routines */
|
||
|
||
|
||
|
||
#include <stdio.h>
|
||
|
||
#include "sdbio.h"
|
||
|
||
|
||
|
||
extern int dbv_token;
|
||
|
||
extern char dbv_tstring[];
|
||
|
||
extern int dbv_tvalue;
|
||
|
||
|
||
|
||
#ifdef CPM68K
|
||
|
||
struct scan *db_ropen();
|
||
|
||
#endif
|
||
|
||
|
||
|
||
/* get_skeys - get sort key list */
|
||
|
||
static struct skey *get_skeys(sptr)
|
||
|
||
struct scan *sptr;
|
||
|
||
{
|
||
|
||
struct skey *skeys,*newskey,*lastskey;
|
||
|
||
struct skey *db_nerror();
|
||
|
||
|
||
|
||
/* 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);
|
||
|
||
}
|
||
|
||
|