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