00001 #include "MemoryPersistentTuple.h"
00002 #include "MemoryTupleData.h"
00003 #include "IMemoryBackingStore.h"
00004 #include "AIDA_Dev/ITupleVariableDescription.h"
00005 #include "AIDA_Dev/IDevTuple.h"
00006 #include "AIDA_Dev/ITupleHeader.h"
00007 #include "AIDA_Dev/IDevTupleFactory.h"
00008
00009 static const std::string subTuplePrefix = "st";
00010
00011 Anaphe::AIDA_MemoryStore::MemoryPersistentTuple::MemoryPersistentTuple( IMemoryBackingStore* store,
00012 AIDA::Dev::IDevTupleFactory& factory,
00013 Anaphe::AIDA_MemoryStore::MemoryTupleData* data,
00014 const std::string& pathInStore ):
00015 m_store( store ),
00016 m_factory( factory ),
00017 m_tupleData( data ),
00018 m_pathInStore( pathInStore ),
00019 m_currentRow( -1 ),
00020 m_cache( data->variables().size(), 0 )
00021 {}
00022
00023 Anaphe::AIDA_MemoryStore::MemoryPersistentTuple::~MemoryPersistentTuple()
00024 {
00025 for ( unsigned int i = 0; i < m_cache.size(); ++i ) {
00026 void* p = m_cache[i];
00027 if ( !p ) continue;
00028 const std::string& variableType = m_tupleData->variables()[i]->variableType();
00029 if ( variableType == "double" ) delete reinterpret_cast< double * >( p );
00030 else if ( variableType == "float" ) delete reinterpret_cast< float * >( p );
00031 else if ( variableType == "long" ) delete reinterpret_cast< long * >( p );
00032 else if ( variableType == "int" ) delete reinterpret_cast< int * >( p );
00033 else if ( variableType == "short" ) delete reinterpret_cast< short * >( p );
00034 else if ( variableType == "char" ) delete reinterpret_cast< char * >( p );
00035 else if ( variableType == "bool" ) delete reinterpret_cast< bool * >( p );
00036 else if ( variableType == "std::string" ) delete reinterpret_cast< std::string * >( p );
00037 }
00038 }
00039
00040 bool
00041 Anaphe::AIDA_MemoryStore::MemoryPersistentTuple::setTupleData( Anaphe::AIDA_MemoryStore::MemoryTupleData* data )
00042 {
00043 if ( data == 0 ) return false;
00044 else {
00045 m_tupleData = data;
00046 return true;
00047 }
00048 }
00049
00050 Anaphe::AIDA_MemoryStore::MemoryTupleData*
00051 Anaphe::AIDA_MemoryStore::MemoryPersistentTuple::tupleData() const
00052 {
00053 return m_tupleData;
00054 }
00055
00056 bool
00057 Anaphe::AIDA_MemoryStore::MemoryPersistentTuple::bindVariable( int variableIndex )
00058 {
00059 void* & p = m_cache[variableIndex];
00060 if ( !p ) {
00061 AIDA::Dev::ITupleVariableDescription& description = *( m_tupleData->variables()[variableIndex] );
00062 const std::string& variableType = description.variableType();
00063 if ( variableType == "double" ) p = new double;
00064 else if ( variableType == "float" ) p = new float;
00065 else if ( variableType == "long" ) p = new long;
00066 else if ( variableType == "int" ) p = new int;
00067 else if ( variableType == "short" ) p = new short;
00068 else if ( variableType == "char" ) p = new char;
00069 else if ( variableType == "bool" ) p = new bool;
00070 else if ( variableType == "std::string" ) p = new std::string;
00071 else if ( variableType == "AIDA::ITuple" ) {
00072 AIDA::Dev::IDevTuple* tuple = m_factory.create( m_store, m_tupleData->title() );
00073
00074 std::string path = subTuplePrefix;
00075 for ( int i = 0; i < variableIndex; ++i ) path += "_";
00076 path += m_pathInStore;
00077 tuple->header().setPathInStore( path );
00078
00079 for ( int i = 0; i < description.numberOfVariables(); ++i ) {
00080 if ( ! tuple->header().setVariableDescription( m_factory.createDescription( *( description.variableDescription(i) ) ),
00081 true ) ) return false;
00082 }
00083
00084 if ( ! m_store->writeTupleHeader( tuple->header() ) ) return false;
00085 p = tuple;
00086 }
00087 }
00088 return true;
00089 }
00090
00091 bool
00092 Anaphe::AIDA_MemoryStore::MemoryPersistentTuple::clearBindings()
00093 {
00094 for ( unsigned int i = 0; i < m_cache.size(); ++i ) {
00095 void* & p = m_cache[i];
00096 if ( !p ) continue;
00097 const std::string& variableType = m_tupleData->variables()[i]->variableType();
00098 if ( variableType == "double" ) delete reinterpret_cast< double * >( p );
00099 else if ( variableType == "float" ) delete reinterpret_cast< float * >( p );
00100 else if ( variableType == "long" ) delete reinterpret_cast< long * >( p );
00101 else if ( variableType == "int" ) delete reinterpret_cast< int * >( p );
00102 else if ( variableType == "short" ) delete reinterpret_cast< short * >( p );
00103 else if ( variableType == "char" ) delete reinterpret_cast< char * >( p );
00104 else if ( variableType == "bool" ) delete reinterpret_cast< bool * >( p );
00105 else if ( variableType == "std::string" ) delete reinterpret_cast< std::string * >( p );
00106 else if ( variableType == "AIDA::ITuple" ) {
00107 AIDA::Dev::IDevTuple* tuple = reinterpret_cast< AIDA::Dev::IDevTuple * >( p );
00108 m_store->removePersistentTuple( tuple->header().pathInStore() );
00109 delete tuple;
00110 }
00111 p = 0;
00112 }
00113 return true;
00114 }
00115
00116 bool
00117 Anaphe::AIDA_MemoryStore::MemoryPersistentTuple::writeTupleRow( int rowNumber )
00118 {
00119 if ( rowNumber < 0 ) return false;
00120 for ( unsigned int i = 0; i < m_cache.size(); ++i ) {
00121 void* p = m_cache[i];
00122 const std::string& variableType = m_tupleData->variables()[i]->variableType();
00123 if ( variableType == "double" ) {
00124 std::vector< double >& vec = m_tupleData->doubleVariableData().find(i)->second;
00125 while ( static_cast<unsigned int>( rowNumber ) >= vec.size() ) vec.push_back( 0 );
00126 if ( p ) vec[rowNumber] = *( reinterpret_cast< double * >( p ) );
00127 }
00128 else if ( variableType == "float" ) {
00129 std::vector< float >& vec = m_tupleData->floatVariableData().find(i)->second;
00130 while ( static_cast<unsigned int>( rowNumber ) >= vec.size() ) vec.push_back( 0 );
00131 if ( p ) vec[rowNumber] = *( reinterpret_cast< float * >( p ) );
00132 }
00133 else if ( variableType == "long" ) {
00134 std::vector< long >& vec = m_tupleData->longVariableData().find(i)->second;
00135 while ( static_cast<unsigned int>( rowNumber ) >= vec.size() ) vec.push_back( 0 );
00136 if ( p ) vec[rowNumber] = *( reinterpret_cast< long * >( p ) );
00137 }
00138 else if ( variableType == "int" ) {
00139 std::vector< int >& vec = m_tupleData->intVariableData().find(i)->second;
00140 while ( static_cast<unsigned int>( rowNumber ) >= vec.size() ) vec.push_back( 0 );
00141 if ( p ) vec[rowNumber] = *( reinterpret_cast< int * >( p ) );
00142 }
00143 else if ( variableType == "short" ) {
00144 std::vector< short >& vec = m_tupleData->shortVariableData().find(i)->second;
00145 while ( static_cast<unsigned int>( rowNumber ) >= vec.size() ) vec.push_back( 0 );
00146 if ( p ) vec[rowNumber] = *( reinterpret_cast< short * >( p ) );
00147 }
00148 else if ( variableType == "char" ) {
00149 std::vector< char >& vec = m_tupleData->charVariableData().find(i)->second;
00150 while ( static_cast<unsigned int>( rowNumber ) >= vec.size() ) vec.push_back( 0 );
00151 if ( p ) vec[rowNumber] = *( reinterpret_cast< char * >( p ) );
00152 }
00153 else if ( variableType == "bool" ) {
00154 std::vector< bool >& vec = m_tupleData->boolVariableData().find(i)->second;
00155 while ( static_cast<unsigned int>( rowNumber ) >= vec.size() ) vec.push_back( false );
00156 if ( p ) vec[rowNumber] = *( reinterpret_cast< bool * >( p ) );
00157 }
00158 else if ( variableType == "std::string" ) {
00159 std::vector< std::string >& vec = m_tupleData->stringVariableData().find(i)->second;
00160 while ( static_cast<unsigned int>( rowNumber ) >= vec.size() ) vec.push_back( "" );
00161 if ( p ) vec[rowNumber] = *( reinterpret_cast< std::string * >( p ) );
00162 }
00163 else if ( variableType == "AIDA::ITuple" ) {
00164 std::vector< Anaphe::AIDA_MemoryStore::MemoryTupleData* >& vec = m_tupleData->tupleVariableData().find(i)->second;
00165 while ( static_cast<unsigned int>( rowNumber ) >= vec.size() ) vec.push_back( 0 );
00166 if ( p ) {
00167 AIDA::Dev::IDevTuple* tuple = reinterpret_cast< AIDA::Dev::IDevTuple * >( p );
00168 const std::string& pathInStore = tuple->header().pathInStore();
00169 Anaphe::AIDA_MemoryStore::IMemoryPersistentTuple* ptuple = m_store->findPersistentTuple( pathInStore );
00170 if ( ! ptuple ) return false;
00171 vec[rowNumber] = ptuple->tupleData();
00172 Anaphe::AIDA_MemoryStore::MemoryTupleData* data = new MemoryTupleData;
00173
00174 for ( int i = 0; i < tuple->header().numberOfVariables(); ++i ) {
00175 AIDA::Dev::ITupleVariableDescription* description = tuple->header().variableDescription( i );
00176 data->variables().push_back( m_factory.createDescription( *description ) );
00177 description->resetStatistics();
00178 const std::string& type = description->variableType();
00179 if ( type == "double" ) data->doubleVariableData().insert( std::make_pair( i, std::vector< double >() ) );
00180 else if ( type == "float" ) data->floatVariableData().insert( std::make_pair( i, std::vector< float >() ) );
00181 else if ( type == "long" ) data->longVariableData().insert( std::make_pair( i, std::vector< long >() ) );
00182 else if ( type == "int" ) data->intVariableData().insert( std::make_pair( i, std::vector< int >() ) );
00183 else if ( type == "short" ) data->shortVariableData().insert( std::make_pair( i, std::vector< short >() ) );
00184 else if ( type == "char" ) data->charVariableData().insert( std::make_pair( i, std::vector< char >() ) );
00185 else if ( type == "bool" ) data->boolVariableData().insert( std::make_pair( i, std::vector< bool >() ) );
00186 else if ( type == "std::string" ) data->stringVariableData().insert( std::make_pair( i, std::vector< std::string >() ) );
00187 else if ( type == "AIDA::ITuple" ) data->tupleVariableData().insert( std::make_pair( i, std::vector< Anaphe::AIDA_MemoryStore::MemoryTupleData * >() ) );
00188 }
00189 ptuple->setTupleData( data );
00190 m_store->setTupleData( pathInStore, data );
00191
00192 tuple->header().setNumberOfRows( 0 );
00193 tuple->header().setCurrentRowNumber( -1 );
00194 }
00195 }
00196 }
00197 return true;
00198 }
00199
00200 bool
00201 Anaphe::AIDA_MemoryStore::MemoryPersistentTuple::readTupleRow( int rowNumber )
00202 {
00203 if ( rowNumber < 0 ) return false;
00204 for ( unsigned int i = 0; i < m_cache.size(); ++i ) {
00205 void* & p = m_cache[i];
00206 if ( !p ) continue;
00207 const std::string& variableType = m_tupleData->variables()[i]->variableType();
00208 if ( variableType == "double" ) {
00209 const std::vector< double >& vec = m_tupleData->doubleVariableData().find(i)->second;
00210 if ( static_cast<unsigned int>( rowNumber ) < vec.size() ) *( reinterpret_cast< double * >( p ) ) = vec[rowNumber];
00211 else return false;
00212 }
00213 else if ( variableType == "float" ) {
00214 const std::vector< float >& vec = m_tupleData->floatVariableData().find(i)->second;
00215 if ( static_cast<unsigned int>( rowNumber ) < vec.size() ) *( reinterpret_cast< float * >( p ) ) = vec[rowNumber];
00216 else return false;
00217 }
00218 else if ( variableType == "long" ) {
00219 const std::vector< long >& vec = m_tupleData->longVariableData().find(i)->second;
00220 if ( static_cast<unsigned int>( rowNumber ) < vec.size() ) *( reinterpret_cast< long * >( p ) ) = vec[rowNumber];
00221 else return false;
00222 }
00223 else if ( variableType == "int" ) {
00224 const std::vector< int >& vec = m_tupleData->intVariableData().find(i)->second;
00225 if ( static_cast<unsigned int>( rowNumber ) < vec.size() ) *( reinterpret_cast< int * >( p ) ) = vec[rowNumber];
00226 else return false;
00227 }
00228 else if ( variableType == "short" ) {
00229 const std::vector< short >& vec = m_tupleData->shortVariableData().find(i)->second;
00230 if ( static_cast<unsigned int>( rowNumber ) < vec.size() ) *( reinterpret_cast< short * >( p ) ) = vec[rowNumber];
00231 else return false;
00232 }
00233 else if ( variableType == "char" ) {
00234 const std::vector< char >& vec = m_tupleData->charVariableData().find(i)->second;
00235 if ( static_cast<unsigned int>( rowNumber ) < vec.size() ) *( reinterpret_cast< char * >( p ) ) = vec[rowNumber];
00236 else return false;
00237 }
00238 else if ( variableType == "bool" ) {
00239 const std::vector< bool >& vec = m_tupleData->boolVariableData().find(i)->second;
00240 if ( static_cast<unsigned int>( rowNumber ) < vec.size() ) *( reinterpret_cast< bool * >( p ) ) = vec[rowNumber];
00241 else return false;
00242 }
00243 else if ( variableType == "std::string" ) {
00244 const std::vector< std::string >& vec = m_tupleData->stringVariableData().find(i)->second;
00245 if ( static_cast<unsigned int>( rowNumber ) < vec.size() ) *( reinterpret_cast< std::string * >( p ) ) = vec[rowNumber];
00246 else return false;
00247 }
00248 else if ( variableType == "AIDA::ITuple" ) {
00249 const std::vector< Anaphe::AIDA_MemoryStore::MemoryTupleData* >& vec = m_tupleData->tupleVariableData().find(i)->second;
00250 if ( static_cast<unsigned int>( rowNumber ) < vec.size() ) {
00251 Anaphe::AIDA_MemoryStore::MemoryTupleData* data = vec[rowNumber];
00252 AIDA::Dev::ITupleHeader& tupleHeader = ( reinterpret_cast< AIDA::Dev::IDevTuple * >( p ) )->header();
00253 m_store->findPersistentTuple( tupleHeader.pathInStore() )->setTupleData( data );
00254 for ( unsigned int i = 0; i < data->variables().size(); ++i ) {
00255 tupleHeader.setVariableDescription( data->variables()[i], false );
00256 }
00257 unsigned int nRows = 0;
00258 if ( data->doubleVariableData().size() > 0 ) nRows = data->doubleVariableData().begin()->second.size();
00259 else if ( data->floatVariableData().size() > 0 ) nRows = data->floatVariableData().begin()->second.size();
00260 else if ( data->longVariableData().size() > 0 ) nRows = data->longVariableData().begin()->second.size();
00261 else if ( data->intVariableData().size() > 0 ) nRows = data->intVariableData().begin()->second.size();
00262 else if ( data->shortVariableData().size() > 0 ) nRows = data->shortVariableData().begin()->second.size();
00263 else if ( data->charVariableData().size() > 0 ) nRows = data->charVariableData().begin()->second.size();
00264 else if ( data->boolVariableData().size() > 0 ) nRows = data->boolVariableData().begin()->second.size();
00265 else if ( data->stringVariableData().size() > 0 ) nRows = data->stringVariableData().begin()->second.size();
00266 else if ( data->tupleVariableData().size() > 0 ) nRows = data->tupleVariableData().begin()->second.size();
00267 tupleHeader.setNumberOfRows( static_cast< int >( nRows ) );
00268 tupleHeader.setCurrentRowNumber( -1 );
00269 }
00270 else return false;
00271 }
00272 }
00273 return true;
00274 }
00275
00276 void*
00277 Anaphe::AIDA_MemoryStore::MemoryPersistentTuple::variableAddress( int variableIndex )
00278 {
00279 bindVariable( variableIndex );
00280 return m_cache[variableIndex];
00281 }
00282
00283 const void*
00284 Anaphe::AIDA_MemoryStore::MemoryPersistentTuple::variableAddress( int variableIndex ) const
00285 {
00286 const_cast<Anaphe::AIDA_MemoryStore::MemoryPersistentTuple*>(this)->bindVariable( variableIndex );
00287 return m_cache[variableIndex];
00288 }