IOLoop::m_mapTimerIDExist,CheckpointReceiver::m_mapHasInitDir,CheckpointSender::m_mapAlreadySendedFile的数据类型应该由std::map改为std::unordered_set。
原因如下:
- 以上几个map在对应的代码里并没有读取second的逻辑。second的值浪费内存空间。
- 以上几个map在对应的代码里并没有顺序相关的逻辑。不需要用红黑树来维护树的平衡和键的有序性(std::map的底层是红黑树插入和查找的时间复杂度为O(log(n)),n为节点个数)。std::unordered_set不需要维护键的有序性(std::unordered的底层是开链法实现的哈希表,理想的插入和查找时间复杂度为O(1))。
修改后的代码路径:
src/algorithm/ioloop.h
class IOLoop : public Thread
{
// ...
// std::map<uint32_t, bool> m_mapTimerIDExist;
std::unordered_set<uint32_t> m_TimerID;
// ...
};
src/algorithm/ioloop.cpp
bool IOLoop :: AddTimer(const int iTimeout, const int iType, uint32_t & iTimerID)
{
if (iTimeout == -1)
{
return true;
}
uint64_t llAbsTime = Time::GetSteadyClockMS() + iTimeout;
m_oTimer.AddTimerWithType(llAbsTime, iType, iTimerID);
// m_mapTimerIDExist[iTimerID] = true;
m_TimerID.insert(iTimerID);
return true;
}
void IOLoop :: RemoveTimer(uint32_t & iTimerID)
{
/*
auto it = m_mapTimerIDExist.find(iTimerID);
if (it != end(m_mapTimerIDExist))
{
m_mapTimerIDExist.erase(it);
}
*/
auto it = m_TimerID.find(iTimerID);
if (it != end(m_TimerID))
{
m_TimerID.erase(it);
}
iTimerID = 0;
}
void IOLoop :: DealwithTimeoutOne(const uint32_t iTimerID, const int iType)
{
/*
auto it = m_mapTimerIDExist.find(iTimerID);
if (it == end(m_mapTimerIDExist))
{
//PLGErr("Timeout aready remove!, timerid %u iType %d", iTimerID, iType);
return;
}
m_mapTimerIDExist.erase(it);
*/
auto it = m_TimerID.find(iTimerID);
if (it == end(m_TimerID))
{
//PLGErr("Timeout aready remove!, timerid %u iType %d", iTimerID, iType);
return;
}
m_TimerID.erase(it);
m_poInstance->OnTimeout(iTimerID, iType);
}
src/algorithm/checkpoint_receiver.h
class CheckpointReceiver
{
// ...
// std::map<std::string, bool> m_mapHasInitDir;
std::unordered_set<std::string> m_HasInitDir;
// ...
};
src/algorithm/checkpoint_receiver.cpp
void CheckpointReceiver :: Reset()
{
// m_mapHasInitDir.clear();
m_HasInitDir.clear();
m_iSenderNodeID = nullnode;
m_llUUID = 0;
m_llSequence = 0;
}
int CheckpointReceiver :: NewReceiver(const nodeid_t iSenderNodeID, const uint64_t llUUID)
{
int ret = ClearCheckpointTmp();
if (ret != 0)
{
return ret;
}
ret = m_poLogStorage->ClearAllLog(m_poConfig->GetMyGroupIdx());
if (ret != 0)
{
PLGErr("ClearAllLog fail, groupidx %d ret %d",
m_poConfig->GetMyGroupIdx(), ret);
return ret;
}
// m_mapHasInitDir.clear();
m_HasInitDir.clear();
m_iSenderNodeID = iSenderNodeID;
m_llUUID = llUUID;
m_llSequence = 0;
return 0;
}
int CheckpointReceiver :: InitFilePath(const std::string & sFilePath, std::string & sFormatFilePath)
{
// ...
// if (m_mapHasInitDir.find(sFormatFilePath) == end(m_mapHasInitDir))
if (m_HasInitDir.find(sFormatFilePath) == end(m_HasInitDir))
{
int ret = CreateDir(sFormatFilePath);
if (ret != 0)
{
return ret;
}
// m_mapHasInitDir[sFormatFilePath] = true;
m_HasInitDir.insert(sFormatFilePath);
}
// ...
}
src/algorithm/checkpoint_sender.h
class CheckpointSender : public Thread
{
// ...
// std::map<std::string, bool> m_mapAlreadySendedFile;
std::unordered_set<std::string> m_AlreadySendedFile;
// ...
};
src/algorithm/checkpoint_sender.cpp
int CheckpointSender :: SendFile(const StateMachine * poSM, const std::string & sDirPath, const std::string & sFilePath)
{
// ...
// if (m_mapAlreadySendedFile.find(sPath) != end(m_mapAlreadySendedFile))
if (m_AlreadySendedFile.find(sPath) != end(m_AlreadySendedFile))
{
PLGErr("file already send, filepath %s", sPath.c_str());
return 0;
}
// ...
// m_mapAlreadySendedFile[sPath] = true;
m_AlreadySendedFile.insert(sPath);
// ...
}
IOLoop::m_mapTimerIDExist,CheckpointReceiver::m_mapHasInitDir,CheckpointSender::m_mapAlreadySendedFile的数据类型应该由std::map改为std::unordered_set。
原因如下:
修改后的代码路径:
src/algorithm/ioloop.h
src/algorithm/ioloop.cpp
src/algorithm/checkpoint_receiver.h
src/algorithm/checkpoint_receiver.cpp
src/algorithm/checkpoint_sender.h
src/algorithm/checkpoint_sender.cpp