Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

CdbNTupleTestApp.cc

Go to the documentation of this file.
00001 // File and Version Information:
00002 //      $Id: CdbNTupleTestApp.cc,v 1.7 2004/08/06 05:54:41 bartoldu Exp $
00003 #include "BaBar/BaBar.hh"
00004 
00005 /// This is a test application for the collection of n-tuple classes
00006 /**
00007   * This application would test instantiation, destruction and use of
00008   * the transient n-tuple-s.
00009   *
00010   * The tests do not do any operations involving any kind of persistentcy.
00011   */
00012 
00013 #include "CdbTable/CdbNTupleFactory.hh"
00014 #include "CdbTable/CdbNTupleAlgorithms.hh"
00015 #include "CdbTable/CdbNTuplePrint.hh"
00016 #include "CdbTable/CdbNTupleIsLessComparatorDefaultImpl.hh"
00017 
00018 #include "BdbTime/BdbTime.hh"
00019 
00020 #include <iostream>
00021 #include <fstream>
00022 
00023 #include <stdio.h>
00024 #include <assert.h>
00025 
00026 #include <string>
00027 #include <vector>
00028 using std::cout;
00029 using std::endl;
00030 using std::fstream;
00031 using std::ofstream;
00032 
00033 //////////////////////////
00034 // Forward declarations //
00035 //////////////////////////
00036 
00037 namespace {
00038 
00039   // Test gor n-tuple-s of the float type of various width
00040 
00041     void test_tuple_of_float( );
00042 
00043   // Test for n-tuples of the std::string type 
00044 
00045     void test_tuple_of_string( );
00046 };
00047 
00048 //////////
00049 // main //
00050 //////////
00051 
00052 int main( int    argc,
00053           char** argv )
00054 {
00055     ::test_tuple_of_float( );
00056     ::test_tuple_of_string( );
00057 
00058     return 0;
00059 }
00060 
00061 /////////////////////
00062 // Implementations //
00063 /////////////////////
00064 
00065 namespace {
00066 
00067   /// fill_unique facility
00068   /**
00069     * A utility function to fill an n-tuple with unique values
00070     * of its element's type using the specified generator supplied for
00071     * the elements type.
00072     */
00073 
00074     template < class T >
00075     struct Generator {
00076         static T value( const unsigned int theRow,
00077                         const unsigned int theColumn );
00078     };
00079 
00080     template < >
00081     struct Generator<float> {
00082         static float value( const unsigned int theRow,
00083                             const unsigned int theColumn )
00084         {
00085             float result = 0.0 + theRow;
00086             if( theColumn < 10 ) {
00087                 result += 0.1 * theColumn;
00088             } else {
00089                 result += value( 0, theColumn / 10 ) + 0.1 * value( 0, theColumn % 10 );
00090             }
00091             return result;
00092         }
00093     };
00094 
00095     template < >
00096     struct Generator<std::string> {
00097         static std::string value( const unsigned int theRow,
00098                                   const unsigned int theColumn )
00099         {
00100             char buf[12];
00101             sprintf( buf, "r:%u c:%u", theRow, theColumn );
00102             return std::string( buf );
00103         }
00104     };
00105 
00106     template < class T, unsigned int NCOL >
00107     void
00108     fill_unique( CdbCPtr< CdbNTuple< T,NCOL > >& thePtr,
00109                  const unsigned int              theNumberOfRows )
00110     {
00111         const unsigned int nColumns = thePtr->columns( );
00112 
00113         for( unsigned int row = 0; row < theNumberOfRows; ++row ) {
00114 
00115             std::vector<T> elements;
00116 
00117             for( unsigned int col = 0; col < nColumns; ++col ) {
00118 //                elements.push_back( ::Generator<T>::value( row, col ));
00119                 elements.push_back( ::Generator<T>::value( row % ( 1 + col ), col / 3 ));
00120             }
00121             CdbStatus status = thePtr->append_row( elements );
00122             assert( CdbStatus::Success == status );
00123         }
00124     }
00125 
00126   /////////////////////////////////////////////
00127   // Custom comparator for sorting algorithm //
00128   /////////////////////////////////////////////
00129 
00130     template < class T, unsigned int NCOL >
00131     class IsLessComparator : public CdbNTupleIsLessComparator<T,NCOL> {
00132     public:
00133         virtual bool isLess( const std::vector<T>& theLeftRow,
00134                              const std::vector<T>& theRightRow ) const
00135         {
00136             assert( NCOL == theLeftRow.size( ));
00137             assert( NCOL == theRightRow.size( ));
00138 
00139 //          cout << "theLeftRow[1] = " << theLeftRow[1] << endl;
00140 
00141             for( unsigned int i = 0; i < NCOL; ++i ) {
00142 
00143                 if( theLeftRow[i] < theRightRow[i] ) {
00144                     return true;
00145                 } else if( theRightRow[i] < theLeftRow[i] ) {
00146                     return false;
00147                 } else {
00148 
00149                   // They're equal - keep checking
00150 
00151                     ;
00152                 }
00153             }
00154 
00155           // If they're equal then it's up to the sorting algorithm
00156           // how to treat this result.
00157           //
00158           // IMPLEMENTATION NOTE: Returning "true" would cause a crash in
00159           //                      the current implementation of std::sort()
00160           //                      algorithm on Linux gcc 2.95.x.
00161 
00162             return false;
00163         }
00164     };
00165 
00166   /////////////////////////
00167   // test_tuple_of_float //
00168   /////////////////////////
00169 
00170     void test_tuple_of_float( )
00171     {
00172 
00173       // Local types
00174 
00175         typedef CdbNTuple< float, 10 > MyTuple;
00176         typedef CdbCPtr< MyTuple > MyTuplePtr;
00177         typedef CdbNTupleFactory< MyTuple::element_type, MyTuple::ncol > MyTupleFactory;
00178 //        typedef IsLessComparator< MyTuple::element_type, MyTuple::ncol > MyIsLessComparator;
00179         typedef CdbNTupleIsLessComparatorDefaultImpl< MyTuple::element_type, MyTuple::ncol > MyIsLessComparator;
00180 
00181       // Create and fill tuples
00182 
00183         MyTuplePtr t1Ptr =
00184             MyTupleFactory::createSimple( );
00185 
00186         MyTuplePtr t2Ptr =
00187             MyTupleFactory::createSimple( "Table #2",
00188                                           "Default names for columns.");
00189 
00190         std::vector<std::string> columnNames;
00191         columnNames.push_back( "First" );
00192         columnNames.push_back( "Second" );
00193         columnNames.push_back( "Third" );
00194 
00195         MyTuplePtr t3Ptr =
00196             MyTupleFactory::createSimple( columnNames,
00197                                           "Table #3",
00198                                           "Just a test table with custom column names." );
00199 
00200         ::fill_unique( t3Ptr, 3000 );
00201 
00202       // Dump tuples
00203 
00204         cout << endl;
00205 
00206         CdbNTuplePrint<>::print1( t1Ptr );
00207 
00208         cout << endl;
00209 
00210         CdbNTuplePrint<>::print1( t2Ptr );
00211 
00212         cout << endl;
00213 
00214         CdbNTuplePrint<>::print2( t3Ptr );
00215 
00216         cout << endl;
00217 
00218       // Sort rows in a table using custom algorithm
00219 
00220         cout << "Begin sorting t3Ptr : " << BdbTime::now( ) << endl;
00221 
00222         MyIsLessComparator isLessComparator;
00223         if( CdbStatus::Success != t3Ptr->sort( &isLessComparator )) {
00224             cout << "test_tuple_of_float() - failed to sort rows a tuple t3Ptr" << endl;
00225             return;
00226         }
00227 
00228         cout << "End   sorting t3Ptr : " << BdbTime::now( ) << endl;
00229 
00230       // Print results
00231 
00232         CdbNTuplePrint<>::print2( t3Ptr );
00233 
00234         cout << endl;
00235 
00236       // Also try printing into a file
00237 
00238         ofstream myFile( "/tmp/CdbNTupleTestApp.output" );
00239 
00240         CdbNTuplePrint<>::print2( myFile, t3Ptr );
00241     }
00242 
00243   /////////////////////////
00244   // test_tuple_of_float //
00245   /////////////////////////
00246 
00247     void test_tuple_of_string( )
00248     {
00249       // Local types
00250 
00251         typedef CdbNTuple< std::string, 4 > MyTuple;
00252         typedef CdbCPtr< MyTuple > MyTuplePtr;
00253         typedef CdbNTupleFactory< MyTuple::element_type, MyTuple::ncol > MyTupleFactory;
00254 
00255         struct Fill {
00256             static void row( MyTuplePtr& ptr,
00257                              const char* s1,
00258                              const char* s2,
00259                              const char* s3,
00260                              const char* s4 )
00261             {
00262                 std::vector<std::string> row;
00263                 {
00264                     row.push_back( std::string( s1 ));
00265                     row.push_back( std::string( s2 ));
00266                     row.push_back( std::string( s3 ));
00267                     row.push_back( std::string( s4 ));        
00268                 }
00269                 ptr->append_row( row );
00270             }
00271         };
00272 
00273       // Create and fill tuples
00274 
00275         std::vector<std::string> columnNames;
00276         columnNames.push_back( "First" );
00277         columnNames.push_back( "Middle" );
00278         columnNames.push_back( "Last" );
00279         columnNames.push_back( "Address" );
00280 
00281         MyTuplePtr t1Ptr =
00282             MyTupleFactory::createSimple( columnNames,
00283                                           "t1Ptr",
00284                                           "This table contains the information about my friends" );
00285 
00286         Fill::row( t1Ptr, "Billy", "M",     "Jill",     "123 Deadend, Nowhereland, CA" );
00287         Fill::row( t1Ptr, "Peter", "B",     "Krouzen",  "5676 Sky Ave, Boston, MA" );
00288         Fill::row( t1Ptr, "Pierre","Marie", "Delaneuf", "1246 Rue De La Prulay 72, Meyrin, GE, Switzerland" );
00289         Fill::row( t1Ptr, "Igor",  "A",     "Gaponenko","012345678901234567890123" );
00290 
00291         MyTuplePtr t2Ptr =
00292             MyTupleFactory::createSimple( "t2Ptr" );
00293 
00294         ::fill_unique( t2Ptr, 5 );
00295 
00296       // Test algorithms
00297 
00298         MyTuplePtr t1CopyPtr;
00299         if( CdbStatus::Success != CdbNTupleCopy( t1CopyPtr, t1Ptr )) {
00300             cout << "test_tuple_of_string() - failed to copy a tuple t1Ptr into t1CopyPtr" << endl;
00301             return;
00302         }
00303 
00304         MyTuplePtr t3Ptr;
00305         if( CdbStatus::Success != CdbNTupleMerge( t3Ptr, t1Ptr, t2Ptr )) {
00306             cout << "test_tuple_of_string() - failed to merge t1Ptr and t2Ptr injto t3Ptr" << endl;
00307             return;
00308         }
00309 
00310         MyTuplePtr t4Ptr;
00311         if( CdbStatus::Success != CdbNTupleCopy( t4Ptr, t1Ptr )) {
00312             cout << "test_tuple_of_string() - failed to copy a tuple t1Ptr into t4Ptr" << endl;
00313             return;
00314         }
00315         if( CdbStatus::Success != CdbNTupleAppend( t4Ptr, t4Ptr )) {
00316             cout << "test_tuple_of_string() - failed to append t4Ptr by t4Ptr" << endl;
00317             return;
00318         }
00319 
00320       // Create a tuple of double width to test "columns-glue" algorithm
00321 
00322         CdbCPtr< CdbNTuple< MyTuple::element_type, 2 * MyTuple::ncol > > t5Ptr;
00323         if( CdbStatus::Success != CdbNTupleGlue( t5Ptr, t1Ptr, t2Ptr )) {
00324             cout << "test_tuple_of_string() - failed to columns-glue t1Ptr and t2Ptr into t5Ptr" << endl;
00325             return;
00326         }
00327         {
00328           // Test the robustness of an implementation of this algorithm. It should not
00329           // have any problems to detect (at run time) and reject templates of incompatible width.
00330 
00331             CdbCPtr< CdbNTuple< MyTuple::element_type, 2 * MyTuple::ncol + 1 > > t6Ptr;
00332 
00333             CdbStatus s = CdbNTupleGlue( t6Ptr, t1Ptr, t2Ptr );
00334             if( CdbStatus::Success != s ) {
00335                 cout << "test_tuple_of_string() - failed to columns-glue t1Ptr and t2Ptr into t6Ptr" << endl
00336                      << "                         A value of CdbStatus returned is: " << s << endl
00337                      << "                         Note, that this is an expected result to test the robustness" << endl
00338                      << "                         of the algorithm." << endl
00339                      << endl;
00340             }
00341         }
00342 
00343       // Dump tuples
00344 
00345         cout << endl;
00346 
00347         CdbNTuplePrint<>::print( t1Ptr,
00348                                  24,
00349                                  "  ",
00350                                  CdbNTuplePrintTypes::ClosedFrame,
00351                                  CdbNTuplePrintTypes::DoubleHashes );
00352 
00353         cout << endl;
00354 
00355         CdbNTuplePrint<>::print( t1Ptr,
00356                                  24,
00357                                  "  ",
00358                                  CdbNTuplePrintTypes::OpenFrame,
00359                                  CdbNTuplePrintTypes::SingleXes );
00360 
00361         cout << endl;
00362 
00363         CdbNTuplePrint<>::print1( t2Ptr );
00364 
00365         cout << endl
00366              << "Copy of t1Ptr:" << endl
00367              << endl;
00368 
00369         CdbNTuplePrint<>::print1( t1CopyPtr, 24 );
00370 
00371         cout << endl
00372              << "Row-merge of t1Ptr and t2Ptr:" << endl
00373              << endl;
00374 
00375         CdbNTuplePrint<>::print2( t3Ptr, 24 );
00376 
00377         cout << endl
00378              << "Append of t4Ptr and t4Ptr (originally copied from t1Pr):" << endl
00379              << endl;
00380 
00381         CdbNTuplePrint<>::print1( t4Ptr, 24 );
00382 
00383         cout << endl
00384              << "Column-merge of t1Ptr and t2Ptr:" << endl
00385              << endl;
00386 
00387         CdbNTuplePrint<>::print2( t5Ptr, 10 );
00388 
00389       // Use an explicitly specified convertor, although the default one
00390 
00391         cout << endl
00392              << "Print using an explicitly specified convertor:" << endl
00393              << endl;
00394 
00395         CdbNTuplePrint< CdbNTuplePrintDefaultConverter< MyTuple::element_type > >::print2( t5Ptr, 10 );
00396 
00397         cout << endl;
00398     }
00399 };
00400 
00401 /////////////////
00402 // End Of File //
00403 /////////////////

Generated on Mon Dec 5 18:22:07 2005 for CDB by doxygen1.3-rc3