[Performance] Pre-Compute CLE Server Lists (#4838)

* [Performance] Pre-Compute CLE Server Lists

* Remove debug
This commit is contained in:
Chris Miles
2025-04-09 21:11:52 -05:00
committed by GitHub
parent c2989e019a
commit ac1469bac2
3 changed files with 104 additions and 54 deletions
+89 -52
View File
@@ -42,11 +42,16 @@ extern ZSList zoneserver_list;
uint32 numplayers = 0; //this really wants to be a member variable of ClientList...
ClientList::ClientList()
: CLStale_timer(10000)
: CLStale_timer(10000),
m_poll_cache_timer(6000)
{
NextCLEID = 1;
m_tick = std::make_unique<EQ::Timer>(5000, true, std::bind(&ClientList::OnTick, this, std::placeholders::_1));
// pre-allocate / pin memory for the zone server caches
m_gm_zone_server_ids.reserve(512);
m_guild_zone_server_ids.reserve(1024);
}
ClientList::~ClientList() {
@@ -57,6 +62,10 @@ void ClientList::Process() {
if (CLStale_timer.Check())
CLCheckStale();
if (m_poll_cache_timer.Check()) {
RebuildZoneServerCaches();
}
LinkedListIterator<Client*> iterator(list);
iterator.Reset();
@@ -384,6 +393,7 @@ void ClientList::ClientUpdate(ZoneServer *zoneserver, ServerClientList_Struct *s
}
else {
cle->Update(zoneserver, scl);
AddToZoneServerCaches(cle);
}
return;
}
@@ -458,6 +468,7 @@ void ClientList::ClientUpdate(ZoneServer *zoneserver, ServerClientList_Struct *s
);
clientlist.Insert(cle);
AddToZoneServerCaches(cle);
zoneserver->ChangeWID(scl->charid, cle->GetID());
}
@@ -1857,71 +1868,97 @@ std::map<uint32, ClientListEntry *> ClientList::GetGuildClientsWithTributeOptIn(
return guild_members;
}
#include <unordered_set>
void ClientList::RebuildZoneServerCaches()
{
// Clear without freeing memory (buckets stay allocated)
m_gm_zone_server_ids.clear();
m_guild_zone_server_ids.clear();
LinkedListIterator<ClientListEntry*> iterator(clientlist);
iterator.Reset();
while (iterator.MoreElements()) {
ClientListEntry* cle = iterator.GetData();
if (cle->Online() != CLE_Status::InZone || !cle->Server()) {
iterator.Advance();
continue;
}
uint32_t server_id = cle->Server()->GetID();
// Track GM zone server
if (cle->GetGM()) {
m_gm_zone_server_ids.insert(server_id);
}
// Track guild zone servers
if (cle->GuildID() > 0) {
auto& guild_set = m_guild_zone_server_ids[cle->GuildID()];
guild_set.insert(server_id);
}
iterator.Advance();
}
}
std::vector<uint32_t> ClientList::GetGuildZoneServers(uint32 guild_id)
{
std::vector<uint32_t> zone_server_ids;
std::unordered_set<uint32_t> seen_ids;
if (RuleB(World, RealTimeCalculateGuilds)) {
std::vector<uint32_t> zone_server_ids;
std::unordered_set<uint32_t> seen_ids;
LinkedListIterator<ClientListEntry *> iterator(clientlist);
LinkedListIterator<ClientListEntry *> iterator(clientlist);
iterator.Reset();
while (iterator.MoreElements()) {
ClientListEntry *cle = iterator.GetData();
iterator.Reset();
while (iterator.MoreElements()) {
ClientListEntry *cle = iterator.GetData();
if (cle->Online() != CLE_Status::InZone) {
iterator.Advance();
continue;
}
if (!cle->Server()) {
iterator.Advance();
continue;
}
if (cle->GuildID() == guild_id) {
uint32_t id = cle->Server()->GetID();
if (seen_ids.insert(id).second) {
zone_server_ids.emplace_back(id);
if (cle->Online() != CLE_Status::InZone) {
iterator.Advance();
continue;
}
if (!cle->Server()) {
iterator.Advance();
continue;
}
if (cle->GuildID() == guild_id) {
uint32_t id = cle->Server()->GetID();
if (seen_ids.insert(id).second) {
zone_server_ids.emplace_back(id);
}
}
iterator.Advance();
}
iterator.Advance();
return zone_server_ids;
}
return zone_server_ids;
auto it = m_guild_zone_server_ids.find(guild_id);
if (it == m_guild_zone_server_ids.end()) {
return {};
}
return {it->second.begin(), it->second.end()};
}
std::vector<uint32_t> ClientList::GetZoneServersWithGMs()
void ClientList::AddToZoneServerCaches(ClientListEntry* cle)
{
std::vector<uint32_t> zone_server_ids;
std::unordered_set<uint32_t> seen_ids;
LinkedListIterator<ClientListEntry *> iterator(clientlist);
iterator.Reset();
while (iterator.MoreElements()) {
ClientListEntry *cle = iterator.GetData();
if (cle->Online() != CLE_Status::InZone) {
iterator.Advance();
continue;
}
if (!cle->Server()) {
iterator.Advance();
continue;
}
if (cle->Admin() > 0) {
uint32_t id = cle->Server()->GetID();
if (seen_ids.insert(id).second) {
zone_server_ids.emplace_back(id);
}
}
iterator.Advance();
if (!cle || cle->Online() != CLE_Status::InZone || !cle->Server()) {
return;
}
return zone_server_ids;
uint32_t server_id = cle->Server()->GetID();
// Add GM zone server if applicable
if (cle->GetGM()) {
m_gm_zone_server_ids.insert(server_id);
}
// Add guild zone server if applicable
if (cle->GuildID() > 0) {
m_guild_zone_server_ids[cle->GuildID()].insert(server_id);
}
}