refactor(Core/LFG): Reduce memory allocations in LFG hot paths (#25064)

Co-authored-by: blinkysc <blinkysc@users.noreply.github.com>
Co-authored-by: sudlud <sudlud@users.noreply.github.com>
This commit is contained in:
blinkysc
2026-07-05 09:52:41 -05:00
committed by GitHub
parent 523bd83ad6
commit fe82e9faf8
3 changed files with 52 additions and 60 deletions
+42 -57
View File
@@ -826,7 +826,6 @@ namespace lfg
return;
}
std::string debugNames = "";
if (grp) // Begin rolecheck
{
// Create new rolecheck
@@ -857,9 +856,6 @@ namespace lfg
if (!isContinue)
SetSelectedDungeons(pguid, dungeons);
roleCheck.roles[pguid] = 0;
if (!debugNames.empty())
debugNames.append(", ");
debugNames.append(plrg->GetName());
}
}
// Update leader role
@@ -886,16 +882,7 @@ namespace lfg
player->GetSession()->SendLfgUpdatePlayer(LfgUpdateData(LFG_UPDATETYPE_JOIN_QUEUE, dungeons, comment));
SetState(guid, LFG_STATE_QUEUED);
SetRoles(guid, roles);
debugNames.append(player->GetName());
}
/*if (sLog->ShouldLog(LOG_FILTER_LFG, LOG_LEVEL_DEBUG))
{
std::ostringstream o;
o << "LFGMgr::Join: [" << guid << "] joined (" << (grp ? "group" : "player") << ") Members: " << debugNames.c_str()
<< ". Dungeons (" << uint32(dungeons.size()) << "): " << ConcatenateDungeons(dungeons);
LOG_DEBUG("lfg", "{}", o.str());
}*/
}
void LFGMgr::ToggleTesting()
@@ -1099,10 +1086,7 @@ namespace lfg
int32 spellDamage, spellHeal;
uint32 dungeonId, encounterMask, maxPower;
uint32 deletedCounter, groupCounter, playerCounter;
ByteBuffer buffer_deleted, buffer_groups, buffer_players;
std::string emptyComment;
GuidSet deletedGroups, deletedGroupsToErase;
RBInternalInfoMap copy;
for (uint8 team = 0; team < 2; ++team)
{
@@ -1207,18 +1191,18 @@ namespace lfg
}
}
copy.clear();
copy = currInternalInfoMap; // will be saved as prev at the end
_rbCopy.clear();
_rbCopy = currInternalInfoMap; // will be saved as prev at the end
// compare prev with curr to build difference packet
deletedCounter = 0;
groupCounter = 0;
playerCounter = 0;
buffer_deleted.clear();
buffer_groups.clear();
buffer_players.clear();
deletedGroups.clear();
deletedGroupsToErase.clear();
_rbBufferDeleted.clear();
_rbBufferGroups.clear();
_rbBufferPlayers.clear();
_rbDeletedGroups.clear();
_rbDeletedGroupsToErase.clear();
RBInternalInfoMap& prevInternalInfoMap = RBInternalInfoStorePrev[team][dungeonId];
RBInternalInfoMap::iterator iter, iterTmp;
@@ -1228,50 +1212,51 @@ namespace lfg
if (iter == currInternalInfoMap.end()) // was -> isn't
{
if (sitr->second.isGroupLeader)
deletedGroups.insert(sitr->second.groupGuid);
_rbDeletedGroups.insert(sitr->second.groupGuid);
++deletedCounter;
buffer_deleted << sitr->second.guid;
_rbBufferDeleted << sitr->second.guid;
}
else // was -> is
{
if (sitr->second.isGroupLeader) // was a leader
{
if (!iter->second.isGroupLeader) // leader -> no longer a leader
deletedGroups.insert(sitr->second.groupGuid);
_rbDeletedGroups.insert(sitr->second.groupGuid);
else if (sitr->second.groupGuid != iter->second.groupGuid) // leader -> leader of another group
{
deletedGroups.insert(sitr->second.groupGuid);
deletedGroupsToErase.insert(iter->second.groupGuid);
_rbDeletedGroups.insert(sitr->second.groupGuid);
_rbDeletedGroupsToErase.insert(iter->second.groupGuid);
++groupCounter;
RBPacketAppendGroup(iter->second, buffer_groups);
RBPacketAppendGroup(iter->second, _rbBufferGroups);
}
else if (sitr->second.comment != iter->second.comment || sitr->second.encounterMask != iter->second.encounterMask || sitr->second.instanceGuid != iter->second.instanceGuid) // leader -> nothing changed
{
++groupCounter;
RBPacketAppendGroup(iter->second, buffer_groups);
RBPacketAppendGroup(iter->second, _rbBufferGroups);
}
}
else if (iter->second.isGroupLeader) // wasn't a leader -> is a leader
{
deletedGroupsToErase.insert(iter->second.groupGuid);
_rbDeletedGroupsToErase.insert(iter->second.groupGuid);
++groupCounter;
RBPacketAppendGroup(iter->second, buffer_groups);
RBPacketAppendGroup(iter->second, _rbBufferGroups);
}
if (!iter->second._online) // if offline, copy previous stats (itemLevel, talents, area, etc.)
{
iterTmp = copy.find(sitr->first); // copied container is for building a full packet, so modify it there (currInternalInfoMap is erased)
iterTmp = _rbCopy.find(sitr->first); // copied container is for building a full packet, so modify it there (currInternalInfoMap is erased)
iterTmp->second.CopyStats(sitr->second);
if (!sitr->second.PlayerSameAs(iterTmp->second)) // player info changed
{
++playerCounter;
RBPacketAppendPlayer(iterTmp->second, buffer_players);
RBPacketAppendPlayer(iterTmp->second, _rbBufferPlayers);
}
}
else if (!sitr->second.PlayerSameAs(iter->second)) // player info changed
{
++playerCounter;
RBPacketAppendPlayer(iter->second, buffer_players);
RBPacketAppendPlayer(iter->second, _rbBufferPlayers);
}
currInternalInfoMap.erase(iter);
}
@@ -1281,38 +1266,38 @@ namespace lfg
{
if (sitr->second.isGroupLeader)
{
deletedGroupsToErase.insert(sitr->second.groupGuid);
_rbDeletedGroupsToErase.insert(sitr->second.groupGuid);
++groupCounter;
RBPacketAppendGroup(sitr->second, buffer_groups);
RBPacketAppendGroup(sitr->second, _rbBufferGroups);
}
++playerCounter;
RBPacketAppendPlayer(sitr->second, buffer_players);
RBPacketAppendPlayer(sitr->second, _rbBufferPlayers);
}
if (!deletedGroupsToErase.empty())
if (!_rbDeletedGroupsToErase.empty())
{
for (ObjectGuid const& toErase : deletedGroupsToErase)
for (ObjectGuid const& toErase : _rbDeletedGroupsToErase)
{
deletedGroups.erase(toErase);
_rbDeletedGroups.erase(toErase);
}
}
if (!deletedGroups.empty())
if (!_rbDeletedGroups.empty())
{
for (ObjectGuid const& deletedGroup : deletedGroups)
for (ObjectGuid const& deletedGroup : _rbDeletedGroups)
{
++deletedCounter;
buffer_deleted << deletedGroup;
_rbBufferDeleted << deletedGroup;
}
}
WorldPacket differencePacket(SMSG_UPDATE_LFG_LIST, 1000);
RBPacketBuildDifference(differencePacket, dungeonId, deletedCounter, buffer_deleted, groupCounter, buffer_groups, playerCounter, buffer_players);
RBPacketBuildDifference(differencePacket, dungeonId, deletedCounter, _rbBufferDeleted, groupCounter, _rbBufferGroups, playerCounter, _rbBufferPlayers);
WorldPacket fullPacket(SMSG_UPDATE_LFG_LIST, 1000);
RBPacketBuildFull(fullPacket, dungeonId, copy);
RBPacketBuildFull(fullPacket, dungeonId, _rbCopy);
RBCacheStore[team][dungeonId] = fullPacket;
prevInternalInfoMap = copy;
prevInternalInfoMap = _rbCopy;
currInternalInfoMap.clear();
if (entryInfoMap.empty())
@@ -1403,44 +1388,44 @@ namespace lfg
buffer << (uint32)info.encounterMask;
}
void LFGMgr::RBPacketBuildDifference(WorldPacket& differencePacket, uint32 dungeonId, uint32 deletedCounter, ByteBuffer& buffer_deleted, uint32 groupCounter, ByteBuffer& buffer_groups, uint32 playerCounter, ByteBuffer& buffer_players)
void LFGMgr::RBPacketBuildDifference(WorldPacket& differencePacket, uint32 dungeonId, uint32 deletedCounter, ByteBuffer const& bufferDeleted, uint32 groupCounter, ByteBuffer const& bufferGroups, uint32 playerCounter, ByteBuffer const& bufferPlayers)
{
differencePacket << (uint32)LFG_TYPE_RAID;
differencePacket << (uint32)dungeonId;
differencePacket << (uint8)1;
differencePacket << (uint32)deletedCounter;
differencePacket.append(buffer_deleted);
differencePacket.append(bufferDeleted);
differencePacket << (uint32)groupCounter;
differencePacket << (uint32)0;
differencePacket.append(buffer_groups);
differencePacket.append(bufferGroups);
differencePacket << (uint32)playerCounter;
differencePacket << (uint32)0;
differencePacket.append(buffer_players);
differencePacket.append(bufferPlayers);
}
void LFGMgr::RBPacketBuildFull(WorldPacket& fullPacket, uint32 dungeonId, RBInternalInfoMap& infoMap)
void LFGMgr::RBPacketBuildFull(WorldPacket& fullPacket, uint32 dungeonId, RBInternalInfoMap const& infoMap)
{
fullPacket << (uint32)LFG_TYPE_RAID;
fullPacket << (uint32)dungeonId;
fullPacket << (uint8)0;
uint32 groupCounter = 0, playerCounter = 0;
ByteBuffer buffer_groups, buffer_players;
ByteBuffer bufferGroups, bufferPlayers;
for (RBInternalInfoMap::const_iterator itr = infoMap.begin(); itr != infoMap.end(); ++itr)
{
if (itr->second.isGroupLeader)
{
++groupCounter;
RBPacketAppendGroup(itr->second, buffer_groups);
RBPacketAppendGroup(itr->second, bufferGroups);
}
++playerCounter;
RBPacketAppendPlayer(itr->second, buffer_players);
RBPacketAppendPlayer(itr->second, bufferPlayers);
}
fullPacket << (uint32)groupCounter;
fullPacket << (uint32)0;
fullPacket.append(buffer_groups);
fullPacket.append(bufferGroups);
fullPacket << (uint32)playerCounter;
fullPacket << (uint32)0;
fullPacket.append(buffer_players);
fullPacket.append(bufferPlayers);
}
// pussywizard:
+9 -2
View File
@@ -20,6 +20,7 @@
#include <utility>
#include "ByteBuffer.h"
#include "DBCStructure.h"
#include "Field.h"
#include "LFG.h"
@@ -562,8 +563,8 @@ namespace lfg
void SendRaidBrowserJoinedPacket(Player* p, LfgDungeonSet& dungeons, std::string comment);
void RBPacketAppendGroup(const RBInternalInfo& info, ByteBuffer& buffer);
void RBPacketAppendPlayer(const RBInternalInfo& info, ByteBuffer& buffer);
void RBPacketBuildDifference(WorldPacket& differencePacket, uint32 dungeonId, uint32 deletedCounter, ByteBuffer& buffer_deleted, uint32 groupCounter, ByteBuffer& buffer_groups, uint32 playerCounter, ByteBuffer& buffer_players);
void RBPacketBuildFull(WorldPacket& fullPacket, uint32 dungeonId, RBInternalInfoMap& infoMap);
void RBPacketBuildDifference(WorldPacket& differencePacket, uint32 dungeonId, uint32 deletedCounter, ByteBuffer const& bufferDeleted, uint32 groupCounter, ByteBuffer const& bufferGroups, uint32 playerCounter, ByteBuffer const& bufferPlayers);
void RBPacketBuildFull(WorldPacket& fullPacket, uint32 dungeonId, RBInternalInfoMap const& infoMap);
// LfgQueue
/// Get last lfg state (NONE, DUNGEON or FINISHED_DUNGEON)
@@ -627,6 +628,12 @@ namespace lfg
uint32 lastProposalId; ///< pussywizard, store it here because of splitting LFGMgr update into tasks
uint32 m_raidBrowserUpdateTimer[2]; ///< pussywizard
uint32 m_raidBrowserLastUpdatedDungeonId[2]; ///< pussywizard: for 2 factions
ByteBuffer _rbBufferDeleted;
ByteBuffer _rbBufferGroups;
ByteBuffer _rbBufferPlayers;
GuidSet _rbDeletedGroups;
GuidSet _rbDeletedGroupsToErase;
RBInternalInfoMap _rbCopy;
LfgQueueContainer QueuesStore; ///< Queues
LfgCachedDungeonContainer CachedDungeonMapStore; ///< Stores all dungeons by groupType
+1 -1
View File
@@ -374,7 +374,7 @@ namespace lfg
LfgDungeonSet temporal;
LfgDungeonSet& dungeons = QueueDataStore[check.guids[i]].dungeons;
std::set_intersection(proposalDungeons.begin(), proposalDungeons.end(), dungeons.begin(), dungeons.end(), std::inserter(temporal, temporal.begin()));
proposalDungeons = temporal;
std::swap(proposalDungeons, temporal);
}
if (proposalDungeons.empty())