home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume8 / graph+ / part03 / join.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-03-01  |  3.1 KB  |  143 lines

  1. /*
  2.  * Copyright (C) 1986   Alan Kent
  3.  *
  4.  * Permission is granted to freely distribute part or
  5.  * all of this code as long as it is not for profit
  6.  * and this message is retained in the code.
  7.  *
  8.  * No resposibility is taken for any damage or incorect
  9.  * results this program generates.
  10.  * 
  11.  */
  12.  
  13.  
  14. #include <stdio.h>
  15. #include "graph.h"
  16.  
  17.  
  18. extern char *new ();
  19. extern table_st *new_table ();
  20.  
  21.  
  22. table_st *
  23. join ( tab1 , tab2 , attr1 , attr2 )
  24. table_st *tab1 , *tab2;
  25. int attr1 , attr2;
  26. {
  27.     double floor ();
  28.  
  29.     int i , j , j0 , newsize , ni;
  30.     int free1 , free2;
  31.     double *data1 , *data2;
  32.     table_st *newtab , *pcol , *pcol1 , *pcol2;
  33.  
  34.  
  35.     if ( attr1 == 0 ) {
  36.     
  37.     /* to make life easy, create a dummy array for $0 */
  38.  
  39.     data1 = (double *) new ( sizeof ( double ) * tab1->size );
  40.     for ( i = 0; i < tab1->size; i++ )
  41.         data1[i] = i + 1;
  42.     free1 = 1;
  43.     }
  44.     else {
  45.     
  46.     /* look for column in table */
  47.  
  48.     for ( i = 1, pcol1 = tab1; pcol1 != NULL  &&  i != attr1; pcol1 = pcol1->next, i++ );
  49.     if ( pcol1 == NULL )
  50.         abort ( "Illegal attribute selected for join" );
  51.     data1 = pcol1->data;
  52.     free1 = 0;
  53.     }
  54.  
  55.     if ( attr2 == 0 ) {
  56.     
  57.     /* to make life easy, create a dummy array for $0 */
  58.  
  59.     data2 = (double *) new ( sizeof ( double ) * tab2->size );
  60.     for ( i = 0; i < tab2->size; i++ )
  61.         data2[i] = i + 1;
  62.     free2 = 1;
  63.     }
  64.     else {
  65.     
  66.     /* look for column in table */
  67.  
  68.     for ( i = 1, pcol2 = tab2; pcol2 != NULL  &&  i != attr2; pcol2 = pcol2->next, i++ );
  69.     if ( pcol2 == NULL )
  70.         abort ( "Illegal attribute selected for join" );
  71.     data2 = pcol2->data;
  72.     free2 = 0;
  73.     }
  74.  
  75.     /* check that data has been sorted on join field, and if not, sort it */
  76.  
  77.     for ( i = 0; i < tab1->size - 1; i++ ) {
  78.     if ( data1[i] > data1[i+1] ) {
  79.         sort ( tab1 , attr1 );
  80.         break;
  81.     }
  82.     }
  83.     for ( i = 0; i < tab2->size - 1; i++ ) {
  84.     if ( data2[i] > data2[i+1] ) {
  85.         sort ( tab2 , attr2 );
  86.         break;
  87.     }
  88.     }
  89.  
  90.     /* determine how big the final table will be */
  91.  
  92.     i = 0;
  93.     j0 = 0;
  94.     newsize = 0;
  95.     for ( i = 0; i < tab1->size; i++ ) {
  96.     while ( j0 < tab2->size  &&  data1[i] > data2[j0] )
  97.         j0++;
  98.     for ( j = j0; j < tab2->size  &&  data1[i] == data2[j]; j++ ) {
  99.         newsize++;
  100.     }
  101.     }
  102.  
  103.     /* ok, build the new table */
  104.  
  105.     newtab = new_table ( num_cols ( tab1 ) + num_cols ( tab2 ) , newsize );
  106.  
  107.     /* now do the join */
  108.  
  109.     i = 0;
  110.     j0 = 0;
  111.     ni = 0;
  112.     for ( i = 0; i < tab1->size; i++ ) {
  113.     while ( j0 < tab2->size  &&  data1[i] > data2[j0] ) {
  114.         j0++;
  115.     }
  116.     for ( j = j0; j < tab2->size  &&  data1[i] == data2[j]; j++ ) {
  117.         pcol = newtab;
  118.         for ( pcol1 = tab1; pcol1 != NULL; pcol1 = pcol1->next ) {
  119.         pcol->data[ni] = pcol1->data[i];
  120.         pcol = pcol->next;
  121.         }
  122.         for ( pcol2 = tab2; pcol2 != NULL; pcol2 = pcol2->next ) {
  123.         pcol->data[ni] = pcol2->data[j];
  124.         pcol = pcol->next;
  125.         }
  126.         ni++;
  127.     }
  128.     }
  129.     if ( ni != newsize )
  130.     abort ( "Internal error in JOIN - pass 2 returns different size than pass 1" );
  131.  
  132.     /* free up and return */
  133.  
  134.     free_table ( tab1 );
  135.     free_table ( tab2 );
  136.     if ( free1 )
  137.     release ( data1 );
  138.     if ( free2 )
  139.     release ( data2 );
  140.     return ( newtab );
  141. }
  142.  
  143.