Network content: Maintain a reverse dependency map

Fixes performance issues with dependency lookup

See: https://github.com/OpenTTD/OpenTTD/issues/9535
pull/306/head
Jonathan G Rennison 3 years ago
parent 5d351a14d2
commit ebab945838

@ -68,7 +68,10 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_INFO(Packet *p)
ci->dependency_count = p->Recv_uint8();
ci->dependencies = MallocT<ContentID>(ci->dependency_count);
for (uint i = 0; i < ci->dependency_count; i++) ci->dependencies[i] = (ContentID)p->Recv_uint32();
for (uint i = 0; i < ci->dependency_count; i++) {
ci->dependencies[i] = (ContentID)p->Recv_uint32();
this->reverse_dependency_map.insert({ ci->dependencies[i], ci->id });
}
ci->tag_count = p->Recv_uint8();
ci->tags = MallocT<char[32]>(ci->tag_count);
@ -169,8 +172,10 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_INFO(Packet *p)
this->infos.push_back(ci);
/* Incoming data means that we might need to reconsider dependencies */
for (ContentInfo *ici : this->infos) {
this->CheckDependencyState(ici);
ConstContentVector parents;
this->ReverseLookupTreeDependency(parents, ci);
for (const ContentInfo *ici : parents) {
this->CheckDependencyState(const_cast<ContentInfo *>(ici));
}
this->OnReceiveContentInfo(ci);
@ -928,15 +933,10 @@ void ClientNetworkContentSocketHandler::ToggleSelectedState(const ContentInfo *c
*/
void ClientNetworkContentSocketHandler::ReverseLookupDependency(ConstContentVector &parents, const ContentInfo *child) const
{
for (const ContentInfo *ci : this->infos) {
if (ci == child) continue;
auto range = this->reverse_dependency_map.equal_range(child->id);
for (uint i = 0; i < ci->dependency_count; i++) {
if (ci->dependencies[i] == child->id) {
parents.push_back(ci);
break;
}
}
for (auto iter = range.first; iter != range.second; ++iter) {
parents.push_back(GetContent(iter->second));
}
}
@ -1061,6 +1061,7 @@ void ClientNetworkContentSocketHandler::Clear()
this->infos.clear();
this->requested.clear();
this->reverse_dependency_map.clear();
}
/*** CALLBACK ***/

@ -12,6 +12,7 @@
#include "core/tcp_content.h"
#include "core/tcp_http.h"
#include "../3rdparty/cpp-btree/btree_map.h"
/** Vector with content info */
typedef std::vector<ContentInfo *> ContentVector;
@ -68,6 +69,7 @@ protected:
std::vector<ContentCallback *> callbacks; ///< Callbacks to notify "the world"
ContentIDList requested; ///< ContentIDs we already requested (so we don't do it again)
ContentVector infos; ///< All content info we received
btree::btree_multimap<ContentID, ContentID> reverse_dependency_map; ///< Content reverse dependency map
std::vector<char> http_response; ///< The HTTP response to the requests we've been doing
int http_response_index; ///< Where we are, in the response, with handling it
@ -82,6 +84,7 @@ protected:
bool Receive_SERVER_CONTENT(Packet *p) override;
ContentInfo *GetContent(ContentID cid);
const ContentInfo *GetContent(ContentID cid) const { return const_cast<ClientNetworkContentSocketHandler *>(this)->GetContent(cid); }
void DownloadContentInfo(ContentID cid);
void OnConnect(bool success) override;

Loading…
Cancel
Save