DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T j

⟦382c80619⟧ TextFile

    Length: 3126 (0xc36)
    Types: TextFile
    Names: »join.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/graph/join.c« 

TextFile

/*
 * 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 );
}