// ------------------------------------------------------------------------------------------------ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bool is_src, const ConnectionMap& conns, const char* const* classnames, size_t count) const { ai_assert(classnames); ai_assert(count != 0 && count <= MAX_CLASSNAMES); size_t lenghts[MAX_CLASSNAMES]; const size_t c = count; for (size_t i = 0; i < c; ++i) { lenghts[i] = strlen(classnames[i]); } std::vector<const Connection*> temp; const std::pair<ConnectionMap::const_iterator,ConnectionMap::const_iterator> range = conns.equal_range(id); temp.reserve(std::distance(range.first,range.second)); for (ConnectionMap::const_iterator it = range.first; it != range.second; ++it) { const Token& key = (is_src ? (*it).second->LazyDestinationObject() : (*it).second->LazySourceObject() ).GetElement().KeyToken(); const char* obtype = key.begin(); for (size_t i = 0; i < c; ++i) { ai_assert(classnames[i]); if(static_cast<size_t>(std::distance(key.begin(),key.end())) == lenghts[i] && !strncmp(classnames[i],obtype,lenghts[i])) { obtype = NULL; break; } } if(obtype) { continue; } temp.push_back((*it).second); } std::sort(temp.begin(), temp.end(), std::mem_fun(&Connection::Compare)); return temp; // NRVO should handle this }
// ------------------------------------------------------------------------------------------------ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, const ConnectionMap& conns) const { std::vector<const Connection*> temp; const std::pair<ConnectionMap::const_iterator,ConnectionMap::const_iterator> range = conns.equal_range(id); temp.reserve(std::distance(range.first,range.second)); for (ConnectionMap::const_iterator it = range.first; it != range.second; ++it) { temp.push_back((*it).second); } std::sort(temp.begin(), temp.end(), std::mem_fun(&Connection::Compare)); return temp; // NRVO should handle this }
IDatabase* DatabaseFactory::getDatabase(EDataTypes dataType, EDataActions dataAction) { FUNCTION_ENTRY("getDatabase"); // Set up a local variable to point to the database that is either created or found IDatabase* theDatabase = NULL; ThreadGuard guard( m_getDatabaseLock ); // get the connection string for this datatype/action std::string dbConnection; // forever loop will exit by exception or when a good db is found while(1) { // If this call fails it will throw something. try { DbConnection::getInstance().getConnectionString(dataType, dataAction, dbConnection); } catch(DbConnectionFailed&) { // we exit the forever loop with this throw TA_THROW(DatabaseException("Unable to find a working database")); } // Get the ID of this thread - we want one database connection per thread int threadId = Thread::getCurrentThreadId(); // Look to see if there is already a database connection for this thread //<ThreadID: Map<ConnectionString, SimpleDBDatabase>> ThreadMap::iterator threadIter ( m_databaseMap.find( threadId )); if ( threadIter == m_databaseMap.end() ) { // add new ConnectionMap. Set db* to null untill it's defined ConnectionMap cmap; cmap.insert( ConnectionMap::value_type( dbConnection, 0 ) ); threadIter = m_databaseMap.insert(ThreadMap::value_type(threadId, cmap) ).first; } ConnectionMap::iterator connIter ( threadIter->second.find( dbConnection ) ); if (connIter == threadIter->second.end()) { connIter = threadIter->second.insert(ConnectionMap::value_type( dbConnection, 0 )).first; } if (connIter->second != 0 ) { // Then the connection already exists. theDatabase = connIter->second; //TODO: need to set dataType and DataAction theDatabase->setDataTypeAction(dataType, dataAction); } else // Database doesn't exist for this thread, so need to create it. { LOG(SourceInfo, DebugUtil::GenericLog, DebugUtil::DebugInfo, "New SimpleDbDatabase object created for thread %lu", threadId); theDatabase = new TA_Base_Core::SimpleDbDatabase(dataType, dataAction); // add to map connIter->second = theDatabase; } // Now that we have a database object, we need to connect it - do this everytime // 'cause if the database is alerady connected, nothing will happen, but if it has // been inadvertandtly disconnected, then it will be reconnected try // The connect line can generate a DatabaseException { theDatabase->connect( dbConnection ); // we can also exit the forever loop this (preferred) way FUNCTION_EXIT; return theDatabase; } catch (DatabaseException&) { // A DatabaseException was generated. Need to delete the database object for now. delete theDatabase; threadIter->second.erase(connIter); TA_Base_Core::Thread::sleep(100); // do not rethrow, just sleep for a while // there may be another database we can talk to. } } // end forever loop }