From a893ecebf80bd85c4654249406b278e856a805f7 Mon Sep 17 00:00:00 2001 From: ariel- Date: Wed, 17 Aug 2016 16:32:47 -0300 Subject: * Core/ObjectAccessor: optimize FindPlayerByName by saving a map of player names to Player* (#17797) --- src/server/game/Globals/ObjectAccessor.cpp | 74 ++++++++++++++++++------------ src/server/game/Globals/ObjectAccessor.h | 6 +++ 2 files changed, 51 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp index 247c4943113..270b2f77f45 100644 --- a/src/server/game/Globals/ObjectAccessor.cpp +++ b/src/server/game/Globals/ObjectAccessor.cpp @@ -81,6 +81,32 @@ HashMapHolder::MapType const& ObjectAccessor::GetPlayers() template class TC_GAME_API HashMapHolder; template class TC_GAME_API HashMapHolder; +namespace PlayerNameMapHolder +{ +typedef std::unordered_map MapType; +static MapType PlayerNameMap; + +void Insert(Player* p) +{ + PlayerNameMap[p->GetName()] = p; +} + +void Remove(Player* p) +{ + PlayerNameMap.erase(p->GetName()); +} + +Player* Find(std::string const& name) +{ + std::string charName(name); + if (!normalizePlayerName(charName)) + return nullptr; + + auto itr = PlayerNameMap.find(charName); + return (itr != PlayerNameMap.end()) ? itr->second : nullptr; +} +} // namespace PlayerNameMapHolder + WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, ObjectGuid const& guid) { switch (guid.GetHigh()) @@ -217,40 +243,16 @@ Player* ObjectAccessor::FindConnectedPlayer(ObjectGuid const& guid) Player* ObjectAccessor::FindPlayerByName(std::string const& name) { - boost::shared_lock lock(*HashMapHolder::GetLock()); + Player* player = PlayerNameMapHolder::Find(name); + if (!player || !player->IsInWorld()) + return nullptr; - std::string nameStr = name; - std::transform(nameStr.begin(), nameStr.end(), nameStr.begin(), ::tolower); - HashMapHolder::MapType const& m = GetPlayers(); - for (HashMapHolder::MapType::const_iterator iter = m.begin(); iter != m.end(); ++iter) - { - if (!iter->second->IsInWorld()) - continue; - std::string currentName = iter->second->GetName(); - std::transform(currentName.begin(), currentName.end(), currentName.begin(), ::tolower); - if (nameStr.compare(currentName) == 0) - return iter->second; - } - - return NULL; + return player; } Player* ObjectAccessor::FindConnectedPlayerByName(std::string const& name) { - boost::shared_lock lock(*HashMapHolder::GetLock()); - - std::string nameStr = name; - std::transform(nameStr.begin(), nameStr.end(), nameStr.begin(), ::tolower); - HashMapHolder::MapType const& m = GetPlayers(); - for (HashMapHolder::MapType::const_iterator iter = m.begin(); iter != m.end(); ++iter) - { - std::string currentName = iter->second->GetName(); - std::transform(currentName.begin(), currentName.end(), currentName.begin(), ::tolower); - if (nameStr.compare(currentName) == 0) - return iter->second; - } - - return NULL; + return PlayerNameMapHolder::Find(name); } void ObjectAccessor::SaveAllPlayers() @@ -261,3 +263,17 @@ void ObjectAccessor::SaveAllPlayers() for (HashMapHolder::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr) itr->second->SaveToDB(); } + +template<> +void ObjectAccessor::AddObject(Player* player) +{ + HashMapHolder::Insert(player); + PlayerNameMapHolder::Insert(player); +} + +template<> +void ObjectAccessor::RemoveObject(Player* player) +{ + HashMapHolder::Remove(player); + PlayerNameMapHolder::Remove(player); +} diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h index be7066c84a9..fba2b5da9ac 100644 --- a/src/server/game/Globals/ObjectAccessor.h +++ b/src/server/game/Globals/ObjectAccessor.h @@ -105,6 +105,12 @@ namespace ObjectAccessor HashMapHolder::Remove(object); } + template<> + void AddObject(Player* player); + + template<> + void RemoveObject(Player* player); + TC_GAME_API void SaveAllPlayers(); }; -- cgit v1.2.3