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

CdbNTupleAlgorithms.cc

Go to the documentation of this file.
00001 // File and Version Information:
00002 //      $Id: CdbNTupleAlgorithms.cc,v 1.5 2004/08/06 05:54:41 bartoldu Exp $
00003 
00004 /// The implementation of the CdbNTupleAlgorithms class.
00005 /**
00006   * @see CdbNTupleAlgorithms
00007   */
00008 
00009 #include "BaBar/BaBar.hh"
00010 
00011 #include "CdbTable/CdbNTupleAlgorithms.hh"
00012 #include "CdbTable/CdbNTupleFactory.hh"
00013 #include "CdbTable/CdbNTupleIsLessComparator.hh"
00014 
00015 #include <iostream>
00016 using std::cout;
00017 using std::endl;
00018 
00019 /*
00020  * The obsolete interface and implementation of the algorithm
00021  *
00022 template < class T, unsigned int NCOL >
00023 CdbStatus
00024 CdbNTupleMerge(       CdbCPtr<CdbNTuple<T,NCOL> >& theOutputPtr,
00025                 const CdbCPtr<CdbNTuple<T,NCOL> >& thePrototypePtr,
00026                 const CdbCPtr<CdbNTuple<T,NCOL> >& theExtraPtr )
00027 {
00028     const char* errorStr = "CdbNTupleMerge<T,NCOL>(output,prototype,extra) - ERROR";
00029 
00030     if( thePrototypePtr.isNull( )) return CdbStatus::IllegalParameters;
00031     if( theExtraPtr.isNull( ))     return CdbStatus::IllegalParameters;
00032 
00033   // Create a clone of the "prototype" tuple and initialize the resulting
00034   // pointer with this clone. Upon the successfull completion of the algorithm
00035   // the output pointer will be repointed onto this new tuple.
00036   //
00037   // NOTE; This operation will automatically copy all metadata and rows
00038   //       from the "prototype" into the resulting tuple.
00039 
00040     CdbCPtr<CdbNTuple<T,NCOL> > resultPtr = thePrototypePtr->clone( );
00041 
00042   // Copy over rows from the "extra" tuple and append them by the end
00043   // of the "output" one.
00044 
00045     unsigned int nRows = theExtraPtr->rows( );
00046     for( unsigned int i = 0; i < nRows; ++i ) {
00047 
00048         std::vector<T> row;
00049         if( CdbStatus::Success != theExtraPtr->get_row( row, i )) {
00050             cout << errorStr << endl
00051                  << "    Failed to read the row number " << i << " from the \"extra\" tuple." << endl;
00052             return CdbStatus::Error;
00053         }
00054         if( CdbStatus::Success != resultPtr->append_row( row )) {
00055             cout << errorStr << endl
00056                  << "    Failed to append the row number " << i << " read from the \"extra\" tuple" << endl
00057                  << "    by the end of the resulting tuple." << endl;
00058             return CdbStatus::Error;
00059         }
00060     }
00061 
00062   // Repoint the "output" tuple to point onto the newely created
00063   // resulting tuple.
00064 
00065     theOutputPtr = resultPtr;
00066 
00067     return CdbStatus::Success;
00068 }
00069 *
00070 * There is a better implementation below.
00071 */
00072 
00073 template < class NTUPLE >
00074 CdbStatus
00075 CdbNTupleMerge(       CdbCPtr<NTUPLE>& theOutputPtr,
00076                 const CdbCPtr<NTUPLE>& thePrototypePtr,
00077                 const CdbCPtr<NTUPLE>& theExtraPtr )
00078 {
00079     const char* errorStr = "CdbNTupleMerge<NTUPLE>(output,prototype,extra) - ERROR";
00080 
00081     if( thePrototypePtr.isNull( )) return CdbStatus::IllegalParameters;
00082     if( theExtraPtr.isNull( ))     return CdbStatus::IllegalParameters;
00083 
00084   // Create a clone of the "prototype" tuple and initialize the resulting
00085   // pointer with this clone. Upon the successfull completion of the algorithm
00086   // the output pointer will be repointed onto this new tuple.
00087   //
00088   // NOTE; This operation will automatically copy all metadata and rows
00089   //       from the "prototype" into the resulting tuple.
00090 
00091     CdbCPtr<NTUPLE> resultPtr = thePrototypePtr->clone( );
00092 
00093   // Copy over rows from the "extra" tuple and append them by the end
00094   // of the "output" one.
00095 
00096     unsigned int nRows = theExtraPtr->rows( );
00097     for( unsigned int i = 0; i < nRows; ++i ) {
00098 
00099         std::vector<typename NTUPLE::element_type> row;
00100         if( CdbStatus::Success != theExtraPtr->get_row( row, i )) {
00101             cout << errorStr << endl
00102                  << "    Failed to read the row number " << i << " from the \"extra\" tuple." << endl;
00103             return CdbStatus::Error;
00104         }
00105         if( CdbStatus::Success != resultPtr->append_row( row )) {
00106             cout << errorStr << endl
00107                  << "    Failed to append the row number " << i << " read from the \"extra\" tuple" << endl
00108                  << "    by the end of the resulting tuple." << endl;
00109             return CdbStatus::Error;
00110         }
00111     }
00112 
00113   // Repoint the "output" tuple to point onto the newely created
00114   // resulting tuple.
00115 
00116     theOutputPtr = resultPtr;
00117 
00118     return CdbStatus::Success;
00119 }
00120 
00121 /*
00122  * The obsolete interface and implementation of the algorithm
00123  *
00124 template < class T, unsigned int NCOL >
00125 CdbStatus
00126 CdbNTupleAppend(       CdbCPtr<CdbNTuple<T,NCOL> >& theOutputPtr,
00127                  const CdbCPtr<CdbNTuple<T,NCOL> >& theInputPtr )
00128 {
00129     const char* errorStr = "CdbNTupleAppend<T,NCOL>(output,input) - ERROR";
00130 
00131     if( theOutputPtr.isNull( )) return CdbStatus::IllegalParameters;
00132     if( theInputPtr.isNull( ))  return CdbStatus::IllegalParameters;
00133 
00134   // Copy over rows from the "input" tuple and append them by the end
00135   // of the "output" one.
00136 
00137     unsigned int nRows = theInputPtr->rows( );
00138     for( unsigned int i =0; i < nRows; ++i ) {
00139         std::vector<T> row;
00140         if( CdbStatus::Success != theInputPtr->get_row( row, i )) {
00141             cout << errorStr << endl
00142                  << "    Failed to read the row number " << i << " from the \"input\" tuple." << endl;
00143             return CdbStatus::Error;
00144         }
00145         if( CdbStatus::Success != theOutputPtr->append_row( row )) {
00146             cout << errorStr << endl
00147                  << "    Failed to append the row number " << i << " read from the \"input\" tuple" << endl
00148                  << "    by the end of the \"output\" tuple." << endl;
00149             return CdbStatus::Error;
00150         }
00151     }
00152 
00153     return CdbStatus::Success;
00154 }
00155 *
00156 * There is a better implementation below.
00157 */
00158 
00159 template < class NTUPLE >
00160 CdbStatus
00161 CdbNTupleAppend(       CdbCPtr<NTUPLE >& theOutputPtr,
00162                  const CdbCPtr<NTUPLE >& theInputPtr )
00163 {
00164     const char* errorStr = "CdbNTupleAppend<NTUPLE>(output,input) - ERROR";
00165 
00166     if( theOutputPtr.isNull( )) return CdbStatus::IllegalParameters;
00167     if( theInputPtr.isNull( ))  return CdbStatus::IllegalParameters;
00168 
00169   // Copy over rows from the "input" tuple and append them by the end
00170   // of the "output" one.
00171 
00172     unsigned int nRows = theInputPtr->rows( );
00173     for( unsigned int i =0; i < nRows; ++i ) {
00174         std::vector<typename NTUPLE::element_type> row;
00175         if( CdbStatus::Success != theInputPtr->get_row( row, i )) {
00176             cout << errorStr << endl
00177                  << "    Failed to read the row number " << i << " from the \"input\" tuple." << endl;
00178             return CdbStatus::Error;
00179         }
00180         if( CdbStatus::Success != theOutputPtr->append_row( row )) {
00181             cout << errorStr << endl
00182                  << "    Failed to append the row number " << i << " read from the \"input\" tuple" << endl
00183                  << "    by the end of the \"output\" tuple." << endl;
00184             return CdbStatus::Error;
00185         }
00186     }
00187 
00188     return CdbStatus::Success;
00189 }
00190 
00191 /*
00192  * The obsolete interface and implementation of the algorithm
00193  *
00194 template < class T, unsigned int NCOL >
00195 CdbStatus
00196 CdbNTupleCopy(       CdbCPtr<CdbNTuple<T,NCOL> >& theOutputTuple,
00197                const CdbCPtr<CdbNTuple<T,NCOL> >& theInputTuple )
00198 {
00199     if( theInputTuple.isNull( )) return CdbStatus::IllegalParameters;
00200 
00201   // Create a clone of the "input" tuple and repoint the "output" pointer
00202   // onto the clone.
00203   //
00204   // NOTE; This operation will automatically copy all metadata and rows
00205   //       from the "input" into the "output" tuple.
00206 
00207     theOutputTuple = theInputTuple->clone( );
00208 
00209     return CdbStatus::Success;
00210 }
00211 *
00212 * There is a better implementation below.
00213 */
00214 
00215 template < class NTUPLE >
00216 CdbStatus
00217 CdbNTupleCopy(       CdbCPtr<NTUPLE>& theOutputTuple,
00218                const CdbCPtr<NTUPLE>& theInputTuple )
00219 {
00220     if( theInputTuple.isNull( )) return CdbStatus::IllegalParameters;
00221 
00222   // Create a clone of the "input" tuple and repoint the "output" pointer
00223   // onto the clone.
00224   //
00225   // NOTE; This operation will automatically copy all metadata and rows
00226   //       from the "input" into the "output" tuple.
00227 
00228     theOutputTuple = theInputTuple->clone( );
00229 
00230     return CdbStatus::Success;
00231 }
00232 
00233 /*
00234  * The obsolete interface and implementation of the algorithm
00235  *
00236 template < class T,
00237            unsigned int NCOL_OUT,
00238            unsigned int NCOL_LEFT,
00239            unsigned int NCOL_RIGHT >
00240 CdbStatus
00241 CdbNTupleGlue_utility<T,NCOL_OUT,NCOL_LEFT,NCOL_RIGHT>::glue(       CdbCPtr<CdbNTuple<T,NCOL_OUT> >&   theOutputPtr,
00242                                                               const CdbCPtr<CdbNTuple<T,NCOL_LEFT> >&  theLeftPtr,
00243                                                               const CdbCPtr<CdbNTuple<T,NCOL_RIGHT> >& theRightPtr,
00244                                                               const bool                               allowRenamingOfColumnsFlag )
00245 {
00246     const char* errorStr = "CdbNTupleGlue_utility<T,NCOL_OUT,NCOL_LEFT,NCOL_RIGHT>::glue(output,left,right) - ERROR";
00247     const char* fatalStr = "CdbNTupleGlue_utility<T,NCOL_OUT,NCOL_LEFT,NCOL_RIGHT>::glue(output,left,right) - FATAL ERROR";
00248 
00249     if( NCOL_OUT != NCOL_LEFT + NCOL_RIGHT ) return CdbStatus::ConflictOfParameters;
00250 
00251     if( theLeftPtr.isNull( ))  return CdbStatus::IllegalParameters;
00252     if( theRightPtr.isNull( )) return CdbStatus::IllegalParameters;
00253 
00254   // Check for the column names (in-)compatibility.
00255 
00256     std::vector<std::string> outputColumnNames;
00257     {
00258         std::vector<std::string> leftColumnNames;
00259         theLeftPtr->column_names( leftColumnNames );
00260 
00261         std::vector<std::string> rightColumnNames;
00262         theRightPtr->column_names( rightColumnNames );
00263 
00264         outputColumnNames = leftColumnNames;
00265 
00266         for( unsigned int right = 0; right < NCOL_RIGHT; ++right ) {
00267 
00268             std::string rightName = rightColumnNames[right];
00269 
00270             if( CdbNTupleBase::is_system_name( rightName )) {
00271 
00272               // That's a defaul t"system" name. Then we need to force its replacement
00273               // with the right default name regardeless of the mode the algorithm
00274               // is used. This is because "system" names of columns from the right tuple
00275               // would be unsuitable when these columns will "shifted" right.
00276 
00277                 rightName = CdbNTupleBase::default_column_name( NCOL_LEFT + right );
00278 
00279             } else {
00280 
00281               // For regular names we should check for the duplicates.
00282 
00283                 for( unsigned int left = 0; left < NCOL_LEFT; ++left ) {
00284 
00285                     if( rightName == leftColumnNames[left] ) {
00286 
00287                       // Replace column names at a right column with the corresponding default
00288                       // value for that position if a conflict with the naming of left columns
00289                       // is found, and if the algorithm is allowed so.
00290 
00291                         if( allowRenamingOfColumnsFlag ) {
00292                             rightName = CdbNTupleBase::default_column_name( NCOL_LEFT + right );
00293                             break;
00294                         } else {
00295                             return CdbStatus::ConflictOfParameters;
00296                         }
00297                     }
00298                 }
00299             }
00300             outputColumnNames.push_back( rightName );
00301         }
00302     }
00303 
00304   // Create a resulting tuple, which will be returned back to a caller
00305   // upon the successfull completion of the algorithm.
00306   //
00307   // NOTE: We've commited not to modify the value of the "output" pointer
00308   //       in case of any problems.
00309 
00310     CdbCPtr< CdbNTuple< T, NCOL_OUT > > resultPtr =
00311         CdbNTupleFactory< T, NCOL_OUT >::createSimple( outputColumnNames,
00312                                                        theLeftPtr->name( ),
00313                                                        theLeftPtr->description( ));
00314     if( resultPtr.isNull( )) {
00315 
00316         cout << fatalStr << endl
00317              << "    Failed to create an output tuple using the \"simple\" factory method." << endl
00318              << "    It can be either a memory management problem of the current application" << endl
00319              << "    or improperly implemented hierarchy of N-Tupe classes." << endl;
00320 
00321         assert( 0 );
00322 
00323         return CdbStatus::Error;
00324     }
00325 
00326   // Copy over rows from the both input tuples and merge them into the output
00327   // one. Fill elements with default values (using default constructor of the
00328   // current element type) for shortest tuple.
00329 
00330     unsigned int nLeftRows   = theLeftPtr->rows( );
00331     unsigned int nRightRows  = theRightPtr->rows( );
00332     unsigned int nOutputRows = ( nLeftRows > nRightRows ? nLeftRows : nRightRows );
00333 
00334     for( unsigned int i = 0; i < nOutputRows; ++ i ) {
00335 
00336         std::vector<T> leftRow;
00337         {
00338 
00339             if( i < nLeftRows ) {
00340 
00341               // Get and check the width of a row from the left tuple
00342 
00343                 if( CdbStatus::Success != theLeftPtr->get_row( leftRow, i )) {
00344                     cout << errorStr << endl
00345                          << "    Failed to read the row number " << i << " from the \"left\" tuple." << endl;
00346                     return CdbStatus::Error;
00347                 }
00348                 if( NCOL_LEFT != leftRow.size( )) {
00349 
00350                     cout << fatalStr << endl
00351                          << "    The number of elements " << leftRow.size( ) << " in a vector returned" << endl
00352                          << "    from the \"left\" tuple when reading the row number " << i << " does not match" << endl
00353                          << "    the width of the tuple. The tuple is supposed to be " << NCOL_LEFT << " in width." << endl
00354                          << "    This can be a problem with the actual implementation of the tuple class." << endl;
00355 
00356                     assert( 0 );
00357 
00358                     return CdbStatus::Error;
00359                 }
00360 
00361             } else {
00362 
00363               // Fill that row with default values by resizing the vector
00364               //
00365               // NOTE: See the specifications for the std::vector class for details.
00366 
00367                 leftRow.resize( NCOL_LEFT );
00368             }
00369         }
00370         
00371       // Get and check the width of a row from the right tuple
00372 
00373         std::vector<T> rightRow;
00374         {
00375             if( i < nRightRows ) {
00376 
00377               // Get and check the width of a row from the right tuple
00378 
00379                 if( CdbStatus::Success != theRightPtr->get_row( rightRow, i )) {
00380                     cout << errorStr << endl
00381                          << "    Failed to read the row number " << i << " from the \"right\" tuple." << endl;
00382                     return CdbStatus::Error;
00383                 }
00384                 if( NCOL_RIGHT != rightRow.size( )) {
00385 
00386                     cout << fatalStr << endl
00387                          << "    The number of elements " << rightRow.size( ) << " in a vector returned" << endl
00388                          << "    from the \"right\" tuple when reading the row number " << i << " does not match" << endl
00389                          << "    the width of the tuple. The tuple is supposed to be " << NCOL_RIGHT << " in width." << endl
00390                          << "    This can be a problem with the actual implementation of the tuple class." << endl;
00391 
00392                     assert( 0 );
00393 
00394                     return CdbStatus::Error;
00395                 }
00396 
00397             } else {
00398 
00399               // Fill that row with default values by resizing the vector.
00400               //
00401               // NOTE: See the specifications for the std::vector class for details.
00402 
00403                 rightRow.resize( NCOL_RIGHT );
00404             }
00405         }
00406 
00407       // Write the merged row into the resulting tuple
00408 
00409         std::vector<T> resultRow = leftRow;
00410 
00411         resultRow.insert( resultRow.end( ),
00412                           rightRow.begin( ),
00413                           rightRow.end( ));
00414 
00415         if( CdbStatus::Success != resultPtr->append_row( resultRow )) {
00416             cout << errorStr << endl
00417                  << "    Failed to append the row number " << i << " merged from both input tuples" << endl
00418                  << "    by the end of the \"output\" tuple." << endl;
00419             return CdbStatus::Error;
00420         }
00421     }
00422 
00423   // Substitute the original "output" pointer with the above created resulting one.
00424 
00425     theOutputPtr = resultPtr;
00426 
00427     return CdbStatus::Success;
00428 }
00429 *
00430 * There is a better implementation below.
00431 */
00432 
00433 template < class NTUPLE_OUT,
00434            class NTUPLE_LEFT,
00435            class NTUPLE_RIGHT >
00436 CdbStatus
00437 CdbNTupleGlue(       CdbCPtr<NTUPLE_OUT>&   theOutputPtr,
00438                const CdbCPtr<NTUPLE_LEFT>&  theLeftPtr,
00439                const CdbCPtr<NTUPLE_RIGHT>& theRightPtr,
00440                const bool                   allowRenamingOfColumnsFlag )
00441 {
00442     const char* errorStr = "CdbNTupleGlue<NTUPLE_OUT,NTUPLE_LEFT,NTUPLE_RIGHT>(output,left,right) - ERROR";
00443     const char* fatalStr = "CdbNTupleGlue<NTUPLE_OUT,NTUPLE_LEFT,NTUPLE_RIGHT>(output,left,right) - FATAL ERROR";
00444 
00445     if( NTUPLE_OUT::ncol != NTUPLE_LEFT::ncol + NTUPLE_RIGHT::ncol ) return CdbStatus::ConflictOfParameters;
00446 
00447     if( theLeftPtr.isNull( ))  return CdbStatus::IllegalParameters;
00448     if( theRightPtr.isNull( )) return CdbStatus::IllegalParameters;
00449 
00450   // Check for the column names (in-)compatibility.
00451 
00452     std::vector<std::string> outputColumnNames;
00453     {
00454         std::vector<std::string> leftColumnNames;
00455         theLeftPtr->column_names( leftColumnNames );
00456 
00457         std::vector<std::string> rightColumnNames;
00458         theRightPtr->column_names( rightColumnNames );
00459 
00460         outputColumnNames = leftColumnNames;
00461 
00462         for( unsigned int right = 0; right < NTUPLE_RIGHT::ncol; ++right ) {
00463 
00464             std::string rightName = rightColumnNames[right];
00465 
00466             if( CdbNTupleBase::is_system_name( rightName )) {
00467 
00468               // That's a defaul t"system" name. Then we need to force its replacement
00469               // with the right default name regardeless of the mode the algorithm
00470               // is used. This is because "system" names of columns from the right tuple
00471               // would be unsuitable when these columns will "shifted" right.
00472 
00473                 rightName = CdbNTupleBase::default_column_name( NTUPLE_LEFT::ncol + right );
00474 
00475             } else {
00476 
00477               // For regular names we should check for the duplicates.
00478 
00479                 for( unsigned int left = 0; left < NTUPLE_LEFT::ncol; ++left ) {
00480 
00481                     if( rightName == leftColumnNames[left] ) {
00482 
00483                       // Replace column names at a right column with the corresponding default
00484                       // value for that position if a conflict with the naming of left columns
00485                       // is found, and if the algorithm is allowed so.
00486 
00487                         if( allowRenamingOfColumnsFlag ) {
00488                             rightName = CdbNTupleBase::default_column_name( NTUPLE_LEFT::ncol + right );
00489                             break;
00490                         } else {
00491                             return CdbStatus::ConflictOfParameters;
00492                         }
00493                     }
00494                 }
00495             }
00496             outputColumnNames.push_back( rightName );
00497         }
00498     }
00499 
00500   // Create a resulting tuple, which will be returned back to a caller
00501   // upon the successfull completion of the algorithm.
00502   //
00503   // NOTE: We've commited not to modify the value of the "output" pointer
00504   //       in case of any problems.
00505 
00506     CdbCPtr< NTUPLE_OUT > resultPtr =
00507         CdbNTupleFactory< typename NTUPLE_OUT::element_type, NTUPLE_OUT::ncol >::createSimple( outputColumnNames,
00508                                                                                                theLeftPtr->name( ),
00509                                                                                                theLeftPtr->description( ));
00510     if( resultPtr.isNull( )) {
00511 
00512         cout << fatalStr << endl
00513              << "    Failed to create an output tuple using the \"simple\" factory method." << endl
00514              << "    It can be either a memory management problem of the current application" << endl
00515              << "    or improperly implemented hierarchy of N-Tupe classes." << endl;
00516 
00517         assert( 0 );
00518 
00519         return CdbStatus::Error;
00520     }
00521 
00522   // Copy over rows from the both input tuples and merge them into the output
00523   // one. Fill elements with default values (using default constructor of the
00524   // current element type) for shortest tuple.
00525 
00526     unsigned int nLeftRows   = theLeftPtr->rows( );
00527     unsigned int nRightRows  = theRightPtr->rows( );
00528     unsigned int nOutputRows = ( nLeftRows > nRightRows ? nLeftRows : nRightRows );
00529 
00530     for( unsigned int i = 0; i < nOutputRows; ++ i ) {
00531 
00532         std::vector<typename NTUPLE_LEFT::element_type> leftRow;
00533         {
00534 
00535             if( i < nLeftRows ) {
00536 
00537               // Get and check the width of a row from the left tuple
00538 
00539                 if( CdbStatus::Success != theLeftPtr->get_row( leftRow, i )) {
00540                     cout << errorStr << endl
00541                          << "    Failed to read the row number " << i << " from the \"left\" tuple." << endl;
00542                     return CdbStatus::Error;
00543                 }
00544                 if( NTUPLE_LEFT::ncol != leftRow.size( )) {
00545 
00546                     cout << fatalStr << endl
00547                          << "    The number of elements " << leftRow.size( ) << " in a vector returned" << endl
00548                          << "    from the \"left\" tuple when reading the row number " << i << " does not match" << endl
00549                          << "    the width of the tuple. The tuple is supposed to be " << NTUPLE_LEFT::ncol << " in width." << endl
00550                          << "    This can be a problem with the actual implementation of the tuple class." << endl;
00551 
00552                     assert( 0 );
00553 
00554                     return CdbStatus::Error;
00555                 }
00556 
00557             } else {
00558 
00559               // Fill that row with default values by resizing the vector
00560               //
00561               // NOTE: See the specifications for the std::vector class for details.
00562 
00563                 leftRow.resize( NTUPLE_LEFT::ncol );
00564             }
00565         }
00566         
00567       // Get and check the width of a row from the right tuple
00568 
00569         std::vector<typename NTUPLE_RIGHT::element_type> rightRow;
00570         {
00571             if( i < nRightRows ) {
00572 
00573               // Get and check the width of a row from the right tuple
00574 
00575                 if( CdbStatus::Success != theRightPtr->get_row( rightRow, i )) {
00576                     cout << errorStr << endl
00577                          << "    Failed to read the row number " << i << " from the \"right\" tuple." << endl;
00578                     return CdbStatus::Error;
00579                 }
00580                 if( NTUPLE_RIGHT::ncol != rightRow.size( )) {
00581 
00582                     cout << fatalStr << endl
00583                          << "    The number of elements " << rightRow.size( ) << " in a vector returned" << endl
00584                          << "    from the \"right\" tuple when reading the row number " << i << " does not match" << endl
00585                          << "    the width of the tuple. The tuple is supposed to be " << NTUPLE_RIGHT::ncol << " in width." << endl
00586                          << "    This can be a problem with the actual implementation of the tuple class." << endl;
00587 
00588                     assert( 0 );
00589 
00590                     return CdbStatus::Error;
00591                 }
00592 
00593             } else {
00594 
00595               // Fill that row with default values by resizing the vector.
00596               //
00597               // NOTE: See the specifications for the std::vector class for details.
00598 
00599                 rightRow.resize( NTUPLE_RIGHT::ncol );
00600             }
00601         }
00602 
00603       // Write the merged row into the resulting tuple
00604 
00605         std::vector<typename NTUPLE_OUT::element_type> resultRow = leftRow;
00606 
00607         resultRow.insert( resultRow.end( ),
00608                           rightRow.begin( ),
00609                           rightRow.end( ));
00610 
00611         if( CdbStatus::Success != resultPtr->append_row( resultRow )) {
00612             cout << errorStr << endl
00613                  << "    Failed to append the row number " << i << " merged from both input tuples" << endl
00614                  << "    by the end of the \"output\" tuple." << endl;
00615             return CdbStatus::Error;
00616         }
00617     }
00618 
00619   // Substitute the original "output" pointer with the above created resulting one.
00620 
00621     theOutputPtr = resultPtr;
00622 
00623     return CdbStatus::Success;
00624 }
00625 
00626 /////////////////
00627 // End Of File //
00628 /////////////////

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