#include "gb-include.h" void doit ( int32_t n ) ; void printLine ( char *bits , int32_t n , char *lastBits , int32_t removeNegs ) ; void setBits ( char *bits , int32_t n , int32_t i ) ; main ( int argc , char *argv[] ) { if ( argc > 2 ) { fprintf(stderr,"Usage: gen <# lists to merge>\n"); exit(-1); } // merge code for how many lists? //int32_t n = atoi ( argv[1] ); for ( int32_t i = 3 ; i <= 5 ; i++ ) doit(i); return 0; } void doit ( int32_t n ) { printf ("// This code was auto generated by " "generateSuperMergeCode.cpp\n"); // print header printf ( "void RdbList::superMerge%"INT32" ( RdbList *list0 ,\n" , n ); for ( int32_t i = 1 ; i < n ; i++ ) printf ("\tRdbList *list%"INT32" ,\n", i ); // then key parms printf ( "\tkey_t startKey ,\n\tkey_t endKey ) {\n"); // set up printf ( "\tint32_t newMax = (m_mergeMinListSize / sizeof(key_t)) * " "\tsizeof(key_t);\n" "\tkey_t *k = (key_t *) m_listPtr;\n" "\tkey_t *keysEnd = (key_t *) (m_listPtr + newMax);\n" "\tkey_t *kstart = (key_t *) m_listPtr;\n" ); // then quick vars for ( int32_t i = 0 ; i < n ; i++ ) printf("\tkey_t *k%"INT32" = (key_t *) list%"INT32"->m_listPtr;\n",i,i); for ( int32_t i = 0 ; i < n ; i++ ) printf ("\tkey_t *end%"INT32" = (key_t *) list%"INT32"->m_listEnd;\n",i,i); // go forwards for ( int32_t i = 0 ; i < n ; i++ ) printf ("\twhile ( k%"INT32" < end%"INT32" && *k%"INT32" < startKey ) " "k%"INT32"++;\n",i,i,i,i); // pedal backwards for ( int32_t i = 0 ; i < n ; i++ ) printf ("\twhile ( end%"INT32" > k%"INT32" && *(end%"INT32"-1) > endKey ) " "end%"INT32"--;\n",i,i,i,i); // . begin tree stuff // . OUTTER COMPARES // . it's a trinary tree // . 1st row is (for 5 lists is) // . there's ESSENTIALLY 3^(5-1) comparison lines // . (k0 < k1, k0 < k2, k0 < k3, k0 < k4) k0,k0,k0,k0 // . (k0 < k1, k0 < k2, k0 < k3, k0 > k4) k0,k0,k0,k0/k4 // . (k0 < k1, k0 < k2, k0 < k3, k0 = k4) k0,k0,k0,k4 // . (k0 < k1, k0 < k2, k0 > k3, k3 < k4) k0,k0,k3,k3 // . (k0 < k1, k0 < k2, k0 > k3, k3 > k4) k0,k0,k3,k4 // . (k0 < k1, k0 < k2, k0 > k3, k3 = k4) k0,k0,k3,k3/k4 // . (k0 < k1, k0 > k2, k2 < k3, k2 < k4) k0,k2,k2,k2 // . (k0 < k1, k0 > k2, k2 < k3, k2 > k4) k0,k2,k2,k4 // . (k0 < k1, k0 > k2, k2 < k3, k2 = k4) k0,k2,k2,k2/k4 // . (k0 < k1, k0 > k2, k2 > k3, k3 < k4) k0,k2,k3,k3 // . (k0 < k1, k0 > k2, k2 > k3, k3 > k4) k0,k2,k3,k4 // . (k0 < k1, k0 > k2, k2 > k3, k3 = k4) k0,k2,k3,k3/k4 // . so into binary, 1 means leadership is taken away, 2 means shared // . # of 0's after first bit on determines nested depth // . 0 0 0 0 if(k0 m_list ) goto top;\n"); printf ("padding:\n"); // padding start for ( int32_t i = 0 ; i < n ; i++ ) printf ("\tif ( k%"INT32" >= end%"INT32" ) goto done;\n",i,i); // init lastBits char lastBits[32]; for ( int32_t i = 0 ; i < 32 ; i++ ) lastBits[i] = -2; // now start counting in trinary for ( int32_t i = 0 ; i < count ; i++ ) { // set bits for this trinary setBits ( bits , numCmps , i ); // print out a statement printLine ( bits , numCmps , lastBits , 0 ); // copy lastBits for ( int32_t i = 0 ; i < 32 ; i++ ) lastBits[i] = bits[i]; } // the real part printf ("top:\n"); printf("\tif ( k >= keysEnd ) goto done;\n"); // init lastBits again for ( int32_t i = 0 ; i < 32 ; i++ ) lastBits[i] = -2; // print all again for ( int32_t i = 0 ; i < count ; i++ ) { // set bits for this trinary setBits ( bits , numCmps , i ); // print out a statement printLine ( bits , numCmps , lastBits, 1 ); // copy lastBits for ( int32_t i = 0 ; i < 32 ; i++ ) lastBits[i] = bits[i]; } // loop command printf ( "\tgoto top;\n" ); printf ( "\tdone:\n"); // update list ptrs for ( int32_t i = 0 ; i < n ; i++ ) printf("\tlist%"INT32"->m_listPtr = (char *)k%"INT32";\n",i,i); printf ("\tm_mergeMinListSize -= ((char *)k-(char *)kstart);\n"); // set our stuff printf ("\tm_listSize = (char *)k - m_list;\n" "\tm_listPtr = (char *)k;\n" "\tm_listEnd = m_list + m_listSize;\n"); // then re-calls for ( int32_t i = 0 ; i < n ; i++ ) { printf("\tif ( k%"INT32" >= end%"INT32" ) {\n",i,i); printf ("\t\tsuperMerge%"INT32" ( ",n-1); // arguments for ( int32_t j = 0 ; j < n ; j++ ) { if ( j == i ) continue; printf("list%"INT32" , ",j); } // rest of args //if ( n-1 == 2 ) printf("startKey , endKey , false );\n"); //else printf("startKey , endKey );\n"); printf("startKey , endKey );\n"); printf ("\t\treturn;\n\t}\n"); } // return if no keys set printf ("\tif ( k == (key_t *)m_list ) return;\n"); printf ("\tkey_t lastKey = *(k - 1);\n"); printf ("\tif ( k < keysEnd ) return ;\n"); // set endKey of each list if we ran out of room for ( int32_t i = 0 ; i < n ; i++ ) printf ("\tif ( k%"INT32" < end%"INT32" && *k%"INT32" < m_endKey ) " "m_endKey = lastKey;\n",i,i,i); printf ("}\n"); } void printLine ( char *bits , int32_t n , char *lastBits , int32_t removeNegs ) { // how many trailing zeroes? int32_t nz = 0; for ( int32_t i = n - 1 ; i >= 0 ; i-- ) { if ( bits[i] == 0 ) nz++; } // complement to get the ultimate winner int32_t winners [ 10 ]; int32_t numWinners = 1; winners[0] = 0; // n tabs char tabs[32]; for ( int32_t i = 0 ; i < n ; i++ ) { tabs[i] = '\t'; tabs[i+1]='\0'; } // call signal //printf("CALLED "); // print bits out for debug //for ( int32_t i = 0 ; i < n ; i++ ) // printf("%"INT32"(%"INT32") ",bits[i],lastBits[i]); //printf("\n"); for ( int32_t i = 0 ; i < n ; i++ ) { // print i tabs if ( bits[i] != lastBits[i] ) for ( int32_t j = 0 ; j < i ; j++ ) printf("\t"); if ( bits[i] == 0 ) { if ( bits[i] != lastBits[i] ) printf("\tif ( *k%"INT32" <= *k%"INT32" ) {\n", winners[0],i+1); //winners[0] = i; //numWinners = 1; } else if ( bits[i] == 1 ) { if ( bits[i] != lastBits[i] ) //printf("\telse if ( *k%"INT32" > *k%"INT32" ) {\n", printf("\telse {\n", winners[0],i+1); winners[0] = i+1; numWinners = 1; } //else { // if ( bits[i] != lastBits[i] ) // printf("\telse {\n"); // winners [ numWinners++ ] = i+1; //} } // if removing negs... if ( removeNegs ) { printf ("%s\tif ((k-1)->n1==k%"INT32"->n1 && " "((k-1)->n0|0x01LL)==k%"INT32"->n0)" "{\n" "%s\t\tk%"INT32"++; " "if ( --k == kstart ) goto padding; }\n" "%s\telse { ", tabs,winners[0],winners[0], tabs,winners[0], tabs); // then the storage instructions printf ("*k++ = *k%"INT32"++; }\n",winners[0]); // advance 1st winner only //printf ("%s\t\tk%"INT32"++;\n",tabs,winners[0]); // if anything we advanced finished printf ("%s\tif ( k%"INT32" >= end%"INT32" ) goto done;", tabs,winners[0],winners[0]); } else { // then the storage instructions printf ("%s\t*k++ = *k%"INT32"++; \n",tabs,winners[0]); // advance 1st winner only //printf ("%s\tk%"INT32"++;\n",tabs,winners[0]); // if anything we advanced finished printf ("%s\tif ( k%"INT32" >= end%"INT32" ) goto done;", tabs,winners[0],winners[0]); } printf ("\n"); // wrap up printf ("%s}",tabs); // count consecutive trailing 2's for ( int32_t i = n-1 ; i >= 1 ; i-- ) { if ( bits[i] == 1 ) printf ("}"); else break; } printf ("\n"); } void setBits ( char *bits , int32_t n , int32_t i ) { for ( int32_t j = n - 1 ; j >= 0 ; j-- ) { bits[j] = i % 2 ; i /= 2; } }