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
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
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 ) {
00093 if ( static_cast<int>(m_filterFactoryUsage.size()) < m_cacheSizeForFilterObjects ) {
00094 nMax = m_filterFactoryUsage.size();
00095 }
00096 else {
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
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 {
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
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
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
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
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 ) {
00168 if ( static_cast<int>(m_evaluatorFactoryUsage.size()) < m_cacheSizeForEvaluatorObjects ) {
00169 nMax = m_evaluatorFactoryUsage.size();
00170 }
00171 else {
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
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 {
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
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
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 }