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

CompiledExpressionManager.cpp

Go to the documentation of this file.
00001 #include "CompiledExpressionManager.h"
00002 #include "SymbolManager.h"
00003 #include "ExpressionParser.h"
00004 
00005 #ifdef OLDSTREAMS
00006 # include <strstream>
00007 # define ostringstream ostrstream
00008 #else
00009 # include <sstream>
00010 #endif
00011 
00012 #include <fstream>
00013 #include <set>
00014 
00015 #include <cstdlib>
00016 
00017 static const std::string filterSymbolPrefix = "anaphe_tuple_filter_";
00018 static const std::string evaluatorSymbolPrefix = "anaphe_tuple_evaluator_";
00019 
00020 
00021 Anaphe::AIDA_Tuple_native::CompiledExpressionManager::CompiledExpressionManager():
00022   m_cacheSizeForFilterObjects( Anaphe::AIDA_Tuple_native::CompiledExpressionManager::defaultCacheSizeForFilterObjects ),
00023   m_cacheSizeForEvaluatorObjects( Anaphe::AIDA_Tuple_native::CompiledExpressionManager::defaultCacheSizeForEvaluatorObjects ),
00024   m_symbolManager( new Anaphe::AIDA_Tuple_native::SymbolManager ),
00025   m_expressionParser( new Anaphe::AIDA_Tuple_native::ExpressionParser )
00026 {
00027   std::set<std::string> includePaths;
00028   char* aidadir = std::getenv( "AIDA_DIR" );
00029   if ( aidadir != 0 ) {
00030     includePaths.insert( std::string( aidadir ) );
00031   }
00032   char* anaphereldir = std::getenv( "ANAPHE_REL_DIR" );
00033   if ( anaphereldir != 0 ) {
00034     includePaths.insert( std::string( anaphereldir ) + "/include" );
00035   }
00036 
00037   std::set<std::string> headerFiles;
00038   headerFiles.insert("<cmath>");
00039   headerFiles.insert("\"AIDA_Dev/IDevTuple.h\"");
00040 
00041   std::set<std::string> namespaces;
00042   namespaces.insert("std");
00043 
00044   m_expressionParser->useHeaderFiles( headerFiles );
00045   m_expressionParser->useNamespaces( namespaces );
00046   m_symbolManager->setIncludePaths( includePaths );
00047 }
00048 
00049 
00050 Anaphe::AIDA_Tuple_native::CompiledExpressionManager::~CompiledExpressionManager()
00051 {
00052   if ( m_expressionParser ) delete m_expressionParser;
00053   if ( m_symbolManager ) {
00054     for ( std::map<std::string, Anaphe::AIDA_Tuple_native::IFilterExpressionBaseFactory*>::iterator i = m_filterFactories.begin();
00055           i != m_filterFactories.end(); ++i ) {
00056       m_symbolManager->destroyAndUnload( i->second );
00057     }
00058     for ( std::map<std::string, Anaphe::AIDA_Tuple_native::IEvaluatorExpressionBaseFactory*>::iterator i = m_evaluatorFactories.begin();
00059           i != m_evaluatorFactories.end(); ++i ) {
00060       m_symbolManager->destroyAndUnload( i->second );
00061     }
00062   }
00063 }
00064 
00065 
00066 std::auto_ptr<Anaphe::AIDA_Tuple_native::IFilterExpressionBase>
00067 Anaphe::AIDA_Tuple_native::CompiledExpressionManager::createFilterExpression( const std::string& expression,
00068                                                                               const std::map<std::string, std::string>& variableTypes,
00069                                                                               std::set<std::string>& variablesUsed )
00070 {
00071   // Determine the most used expression
00072   int nMax = 0;
00073   for ( std::map<std::string, int>::const_iterator i = m_filterFactoryUsage.begin(); i != m_filterFactoryUsage.end(); ++i ) {
00074     const int n = i->second;
00075     if ( n > nMax ) nMax = n;
00076   }
00077 
00078   // Check whether the expression already exists
00079   std::map<std::string, Anaphe::AIDA_Tuple_native::IFilterExpressionBaseFactory*>::iterator iFilterFactory = m_filterFactories.find( expression );
00080   if ( iFilterFactory != m_filterFactories.end() ) {
00081     if ( m_filterFactoryUsage[expression] < nMax ) {
00082       m_filterFactoryUsage[expression] = nMax + 1;
00083       for ( std::map<std::string, int>::iterator i = m_filterFactoryUsage.begin(); i != m_filterFactoryUsage.end(); ++i ) {
00084         i->second -= 1;
00085       }
00086     }
00087     variablesUsed = m_filterFactoryVariables.find( expression )->second;
00088     return std::auto_ptr<Anaphe::AIDA_Tuple_native::IFilterExpressionBase>( iFilterFactory->second->create() );
00089   }
00090 
00091   std::string symbolName = "";
00092   if ( m_filterFactoryUsage.size() > 0 ) { // check if the maximum number of expressions is already reached.
00093     if ( static_cast<int>(m_filterFactoryUsage.size()) < m_cacheSizeForFilterObjects ) {
00094       nMax = m_filterFactoryUsage.size();
00095     }
00096     else { // find the one with the lowest usage
00097       for ( std::map<std::string, int>::const_iterator i = m_filterFactoryUsage.begin(); i != m_filterFactoryUsage.end(); ++i ) {
00098         if ( i->second == 0 ) {
00099           symbolName = i->first;
00100           break;
00101         }
00102       }
00103     }
00104   }
00105 
00106   // remove an old symbol if needed
00107   if ( symbolName.size() > 0 ) {
00108     m_symbolManager->destroyAndUnload( m_filterFactories[ symbolName ] );
00109     m_filterFactories.erase( symbolName );
00110     m_filterFactoryUsage.erase( symbolName );
00111     m_filterFactoryVariables.erase( symbolName );
00112   }
00113   else { // Form the symbol name
00114     std::ostringstream osSymbol;
00115     osSymbol << filterSymbolPrefix << nMax;
00116 #ifndef BADENDS
00117     osSymbol << std::ends;
00118 #endif
00119     symbolName = osSymbol.str();
00120   }
00121 
00122   const std::string symbolFile = symbolName + ".cpp";
00123 
00124   // create a new symbol
00125   std::ofstream fout( symbolFile.c_str() );
00126   variablesUsed = m_expressionParser->logicalEvaluation( expression, variableTypes, symbolName, fout );
00127   Anaphe::AIDA_Tuple_native::IFilterExpressionBaseFactory* factoryPointer = m_symbolManager->makeAndLoadFilter( symbolFile, symbolName );
00128 
00129   // return the actual object
00130   Anaphe::AIDA_Tuple_native::IFilterExpressionBase* p = 0;
00131   if ( factoryPointer ) {
00132     p = factoryPointer->create();
00133     m_filterFactories.insert( std::make_pair( expression, factoryPointer ) );
00134     m_filterFactoryUsage.insert( std::make_pair( expression, static_cast<int>(m_filterFactories.size()) ) );
00135     m_filterFactoryVariables.insert( std::make_pair( expression, variablesUsed ) );
00136   }
00137   return std::auto_ptr<Anaphe::AIDA_Tuple_native::IFilterExpressionBase>( p );
00138 }
00139 
00140 
00141 std::auto_ptr<Anaphe::AIDA_Tuple_native::IEvaluatorExpressionBase>
00142 Anaphe::AIDA_Tuple_native::CompiledExpressionManager::createEvaluatorExpression( const std::string& expression,
00143                                                                                  const std::map<std::string, std::string>& variableTypes,
00144                                                                                  std::set<std::string>& variablesUsed )
00145 {
00146   // Determine the most used expression
00147   int nMax = 0;
00148   for ( std::map<std::string, int>::const_iterator i = m_evaluatorFactoryUsage.begin(); i != m_evaluatorFactoryUsage.end(); ++i ) {
00149     const int n = i->second;
00150     if ( n > nMax ) nMax = n;
00151   }
00152 
00153   // Check whether the expression already exists
00154   std::map<std::string, Anaphe::AIDA_Tuple_native::IEvaluatorExpressionBaseFactory*>::iterator iEvaluatorFactory = m_evaluatorFactories.find( expression );
00155   if ( iEvaluatorFactory != m_evaluatorFactories.end() ) {
00156     if ( m_evaluatorFactoryUsage[expression] < nMax ) {
00157       m_evaluatorFactoryUsage[expression] = nMax + 1;
00158       for ( std::map<std::string, int>::iterator i = m_evaluatorFactoryUsage.begin(); i != m_evaluatorFactoryUsage.end(); ++i ) {
00159         i->second -= 1;
00160       }
00161     }
00162     variablesUsed = m_evaluatorFactoryVariables.find( expression )->second;
00163     return std::auto_ptr<Anaphe::AIDA_Tuple_native::IEvaluatorExpressionBase>( iEvaluatorFactory->second->create() );
00164   }
00165 
00166   std::string symbolName = "";
00167   if ( m_evaluatorFactoryUsage.size() > 0 ) { // check if the maximum number of expressions is already reached.
00168     if ( static_cast<int>(m_evaluatorFactoryUsage.size()) < m_cacheSizeForEvaluatorObjects ) {
00169       nMax = m_evaluatorFactoryUsage.size();
00170     }
00171     else { // find the one with the lowest usage
00172       for ( std::map<std::string, int>::const_iterator i = m_evaluatorFactoryUsage.begin(); i != m_evaluatorFactoryUsage.end(); ++i ) {
00173         if ( i->second == 0 ) {
00174           symbolName = i->first;
00175           break;
00176         }
00177       }
00178     }
00179   }
00180 
00181   // remove an old symbol if needed
00182   if ( symbolName.size() > 0 ) {
00183     m_symbolManager->destroyAndUnload( m_evaluatorFactories[ symbolName ] );
00184     m_evaluatorFactories.erase( symbolName );
00185     m_evaluatorFactoryUsage.erase( symbolName );
00186     m_evaluatorFactoryVariables.erase( symbolName );
00187   }
00188   else { // Form the symbol name
00189     std::ostringstream osSymbol;
00190     osSymbol << evaluatorSymbolPrefix << nMax;
00191 #ifndef BADENDS
00192     osSymbol << std::ends;
00193 #endif
00194     symbolName = osSymbol.str();
00195   }
00196 
00197   const std::string symbolFile = symbolName + ".cpp";
00198 
00199   // create a new symbol
00200   std::ofstream fout( symbolFile.c_str() );
00201   variablesUsed = m_expressionParser->mathematicalEvaluation( expression, variableTypes, symbolName, fout );
00202   Anaphe::AIDA_Tuple_native::IEvaluatorExpressionBaseFactory* factoryPointer = m_symbolManager->makeAndLoadEvaluator( symbolFile, symbolName );
00203 
00204   // return the actual object
00205   Anaphe::AIDA_Tuple_native::IEvaluatorExpressionBase* p = 0;
00206   if ( factoryPointer ) {
00207     p = factoryPointer->create();
00208     m_evaluatorFactories.insert( std::make_pair( expression, factoryPointer ) );
00209     m_evaluatorFactoryUsage.insert( std::make_pair( expression, static_cast<int>(m_evaluatorFactories.size()) ) );
00210     m_evaluatorFactoryVariables.insert( std::make_pair( expression, variablesUsed ) );
00211   }
00212   return std::auto_ptr<Anaphe::AIDA_Tuple_native::IEvaluatorExpressionBase>( p );
00213 }
00214 
00215 
00216 int
00217 Anaphe::AIDA_Tuple_native::CompiledExpressionManager::cacheSizeForFilterObjects()
00218 {
00219   return m_cacheSizeForFilterObjects;
00220 }
00221 
00222 
00223 int
00224 Anaphe::AIDA_Tuple_native::CompiledExpressionManager::cacheSizeForEvaluatorObjects()
00225 {
00226   return m_cacheSizeForEvaluatorObjects;
00227 }
00228 
00229 
00230 void
00231 Anaphe::AIDA_Tuple_native::CompiledExpressionManager::setCacheSizeForFilterObjects( int cacheSize )
00232 {
00233   m_cacheSizeForFilterObjects = cacheSize;
00234 }
00235 
00236 
00237 void
00238 Anaphe::AIDA_Tuple_native::CompiledExpressionManager::setCacheSizeForEvaluatorObjects( int cacheSize )
00239 {
00240   m_cacheSizeForEvaluatorObjects = cacheSize;
00241 }

Generated on Tue Feb 18 17:51:19 2003 for AIDA_Tuple_native by doxygen1.2.16