#include "originconnection.h" #include "filesorigin.h" #include "util.h" #include namespace MOShared { using namespace MOBase; OriginConnection::OriginConnection() : m_NextID(0) { } std::pair OriginConnection::getOrCreate( const std::wstring &originName, const std::wstring &directory, int priority, const boost::shared_ptr& fileRegister, const boost::shared_ptr& originConnection, DirectoryStats& stats) { std::unique_lock lock(m_Mutex); auto itor = m_OriginsNameMap.find(originName); if (itor == m_OriginsNameMap.end()) { FilesOrigin& origin = createOriginNoLock( originName, directory, priority, fileRegister, originConnection); return {origin, true}; } else { FilesOrigin& origin = m_Origins[itor->second]; lock.unlock(); origin.enable(true, stats); return {origin, false}; } } FilesOrigin& OriginConnection::createOrigin( const std::wstring &originName, const std::wstring &directory, int priority, boost::shared_ptr fileRegister, boost::shared_ptr originConnection) { std::scoped_lock lock(m_Mutex); return createOriginNoLock( originName, directory, priority, fileRegister, originConnection); } bool OriginConnection::exists(const std::wstring &name) { std::scoped_lock lock(m_Mutex); return m_OriginsNameMap.find(name) != m_OriginsNameMap.end(); } FilesOrigin& OriginConnection::getByID(OriginID ID) { std::scoped_lock lock(m_Mutex); return m_Origins[ID]; } const FilesOrigin* OriginConnection::findByID(OriginID ID) const { std::scoped_lock lock(m_Mutex); auto itor = m_Origins.find(ID); if (itor == m_Origins.end()) { return nullptr; } else { return &itor->second; } } FilesOrigin& OriginConnection::getByName(const std::wstring &name) { std::scoped_lock lock(m_Mutex); auto iter = m_OriginsNameMap.find(name); if (iter != m_OriginsNameMap.end()) { return m_Origins[iter->second]; } else { std::ostringstream stream; stream << QObject::tr("invalid origin name: ").toStdString() << ToString(name, true); throw std::runtime_error(stream.str()); } } void OriginConnection::changePriorityLookup(int oldPriority, int newPriority) { std::scoped_lock lock(m_Mutex); auto iter = m_OriginsPriorityMap.find(oldPriority); if (iter != m_OriginsPriorityMap.end()) { OriginID idx = iter->second; m_OriginsPriorityMap.erase(iter); m_OriginsPriorityMap[newPriority] = idx; } } void OriginConnection::changeNameLookup(const std::wstring &oldName, const std::wstring &newName) { std::scoped_lock lock(m_Mutex); auto iter = m_OriginsNameMap.find(oldName); if (iter != m_OriginsNameMap.end()) { OriginID idx = iter->second; m_OriginsNameMap.erase(iter); m_OriginsNameMap[newName] = idx; } else { log::error(QObject::tr("failed to change name lookup from {} to {}").toStdString(), oldName, newName); } } OriginID OriginConnection::createID() { return m_NextID++; } FilesOrigin& OriginConnection::createOriginNoLock( const std::wstring &originName, const std::wstring &directory, int priority, boost::shared_ptr fileRegister, boost::shared_ptr originConnection) { OriginID newID = createID(); auto itor = m_Origins.emplace( std::piecewise_construct, std::forward_as_tuple(newID), std::forward_as_tuple( newID, originName, directory, priority, fileRegister, originConnection)) .first; m_OriginsNameMap.insert({originName, newID}); m_OriginsPriorityMap.insert({priority, newID}); return itor->second; } } // namespace