|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T j
Length: 3126 (0xc36)
Types: TextFile
Names: »join.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/euug-87hel/sec1/graph/join.c«
/*
* Copyright (C) 1986 Alan Kent
*
* Permission is granted to freely distribute part or
* all of this code as long as it is not for profit
* and this message is retained in the code.
*
* No resposibility is taken for any damage or incorect
* results this program generates.
*
*/
#include <stdio.h>
#include "graph.h"
extern char *new ();
extern table_st *new_table ();
table_st *
join ( tab1 , tab2 , attr1 , attr2 )
table_st *tab1 , *tab2;
int attr1 , attr2;
{
double floor ();
int i , j , j0 , newsize , ni;
int free1 , free2;
double *data1 , *data2;
table_st *newtab , *pcol , *pcol1 , *pcol2;
if ( attr1 == 0 ) {
/* to make life easy, create a dummy array for $0 */
data1 = (double *) new ( sizeof ( double ) * tab1->size );
for ( i = 0; i < tab1->size; i++ )
data1[i] = i + 1;
free1 = 1;
}
else {
/* look for column in table */
for ( i = 1, pcol1 = tab1; pcol1 != NULL && i != attr1; pcol1 = pcol1->next, i++ );
if ( pcol1 == NULL )
abort ( "Illegal attribute selected for join" );
data1 = pcol1->data;
free1 = 0;
}
if ( attr2 == 0 ) {
/* to make life easy, create a dummy array for $0 */
data2 = (double *) new ( sizeof ( double ) * tab2->size );
for ( i = 0; i < tab2->size; i++ )
data2[i] = i + 1;
free2 = 1;
}
else {
/* look for column in table */
for ( i = 1, pcol2 = tab2; pcol2 != NULL && i != attr2; pcol2 = pcol2->next, i++ );
if ( pcol2 == NULL )
abort ( "Illegal attribute selected for join" );
data2 = pcol2->data;
free2 = 0;
}
/* check that data has been sorted on join field, and if not, sort it */
for ( i = 0; i < tab1->size - 1; i++ ) {
if ( data1[i] > data1[i+1] ) {
sort ( tab1 , attr1 );
break;
}
}
for ( i = 0; i < tab2->size - 1; i++ ) {
if ( data2[i] > data2[i+1] ) {
sort ( tab2 , attr2 );
break;
}
}
/* determine how big the final table will be */
i = 0;
j0 = 0;
newsize = 0;
for ( i = 0; i < tab1->size; i++ ) {
while ( j0 < tab2->size && data1[i] > data2[j0] )
j0++;
for ( j = j0; j < tab2->size && data1[i] == data2[j]; j++ ) {
newsize++;
}
}
/* ok, build the new table */
newtab = new_table ( num_cols ( tab1 ) + num_cols ( tab2 ) , newsize );
/* now do the join */
i = 0;
j0 = 0;
ni = 0;
for ( i = 0; i < tab1->size; i++ ) {
while ( j0 < tab2->size && data1[i] > data2[j0] ) {
j0++;
}
for ( j = j0; j < tab2->size && data1[i] == data2[j]; j++ ) {
pcol = newtab;
for ( pcol1 = tab1; pcol1 != NULL; pcol1 = pcol1->next ) {
pcol->data[ni] = pcol1->data[i];
pcol = pcol->next;
}
for ( pcol2 = tab2; pcol2 != NULL; pcol2 = pcol2->next ) {
pcol->data[ni] = pcol2->data[j];
pcol = pcol->next;
}
ni++;
}
}
if ( ni != newsize )
abort ( "Internal error in JOIN - pass 2 returns different size than pass 1" );
/* free up and return */
free_table ( tab1 );
free_table ( tab2 );
if ( free1 )
release ( data1 );
if ( free2 )
release ( data2 );
return ( newtab );
}