mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-13 02:38:45 +00:00
[Performance] Pre-Compute CLE Server Lists (#4838)
* [Performance] Pre-Compute CLE Server Lists * Remove debug
This commit is contained in:
+89
-52
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user