From 190118bb5867f75abc8a98305123748886e91622 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sun, 18 Dec 2022 19:59:48 -0500 Subject: [PATCH] try optimizing user fetch --- src/components/memberlist.cpp | 19 +++++++++---------- src/discord/discord.cpp | 6 ++++++ src/discord/discord.hpp | 1 + src/discord/store.cpp | 28 +++++++++++++++++----------- src/discord/store.hpp | 31 +++++++++++++++++++++++++++++++ 5 files changed, 64 insertions(+), 21 deletions(-) diff --git a/src/components/memberlist.cpp b/src/components/memberlist.cpp index 5e809cf..8ac64a5 100644 --- a/src/components/memberlist.cpp +++ b/src/components/memberlist.cpp @@ -70,12 +70,12 @@ void MemberList::UpdateMemberList() { return; } - std::set ids; + std::vector users; if (channel->IsThread()) { - auto x = discord.GetUsersInThread(m_chan_id); - ids = { x.begin(), x.end() }; + // auto x = discord.GetUsersInThread(m_chan_id); + // ids = { x.begin(), x.end() }; } else { - ids = discord.GetUsersInGuild(m_guild_id); + users = discord.GetUserDataInGuildBulk(m_guild_id); } std::map pos_to_role; @@ -83,23 +83,22 @@ void MemberList::UpdateMemberList() { // std::unordered_map user_to_color; std::vector roleless_users; - for (const auto &id : ids) { - auto user = discord.GetUser(id); - if (!user.has_value() || user->IsDeleted()) + for (const auto &user : users) { + if (user.IsDeleted()) continue; - auto pos_role_id = discord.GetMemberHoistedRole(m_guild_id, id); // role for positioning + auto pos_role_id = discord.GetMemberHoistedRole(m_guild_id, user.ID); // role for positioning // auto col_role_id = discord.GetMemberHoistedRole(m_guild_id, id, true); // role for color auto pos_role = discord.GetRole(pos_role_id); // auto col_role = discord.GetRole(col_role_id); if (!pos_role.has_value()) { - roleless_users.push_back(id); + roleless_users.push_back(user.ID); continue; } pos_to_role[pos_role->Position] = *pos_role; - pos_to_users[pos_role->Position].push_back(std::move(*user)); + pos_to_users[pos_role->Position].push_back(user); // if (col_role.has_value()) // user_to_color[id] = col_role->Color; } diff --git a/src/discord/discord.cpp b/src/discord/discord.cpp index 2808e17..07cedb5 100644 --- a/src/discord/discord.cpp +++ b/src/discord/discord.cpp @@ -262,6 +262,12 @@ std::set DiscordClient::GetUsersInGuild(Snowflake id) const { return {}; } +std::vector DiscordClient::GetUserDataInGuildBulk(Snowflake id) { + const auto ids = GetUsersInGuild(id); + std::vector test; + return m_store.GetUserDataBulk(ids.begin(), ids.end()); +} + std::set DiscordClient::GetChannelsInGuild(Snowflake id) const { auto it = m_guild_to_channels.find(id); if (it != m_guild_to_channels.end()) diff --git a/src/discord/discord.hpp b/src/discord/discord.hpp index c2bea7d..0601928 100644 --- a/src/discord/discord.hpp +++ b/src/discord/discord.hpp @@ -76,6 +76,7 @@ public: Snowflake GetMemberHoistedRole(Snowflake guild_id, Snowflake user_id, bool with_color = false) const; std::optional GetMemberHighestRole(Snowflake guild_id, Snowflake user_id) const; std::set GetUsersInGuild(Snowflake id) const; + std::vector GetUserDataInGuildBulk(Snowflake id); std::set GetChannelsInGuild(Snowflake id) const; std::vector GetUsersInThread(Snowflake id) const; std::vector GetActiveThreads(Snowflake channel_id) const; diff --git a/src/discord/store.cpp b/src/discord/store.cpp index 892f4aa..a1ed78d 100644 --- a/src/discord/store.cpp +++ b/src/discord/store.cpp @@ -1033,6 +1033,22 @@ RoleData Store::GetRoleBound(std::unique_ptr &s) { return r; } +UserData Store::GetUserBound(Statement *s) const { + UserData r; + + s->Get(0, r.ID); + s->Get(1, r.Username); + s->Get(2, r.Discriminator); + s->Get(3, r.Avatar); + s->Get(4, r.IsBot); + s->Get(5, r.IsSystem); + s->Get(6, r.IsMFAEnabled); + s->Get(7, r.PremiumType); + s->Get(8, r.PublicFlags); + + return r; +} + std::optional Store::GetUser(Snowflake id) const { auto &s = m_stmt_get_user; s->Bind(1, id); @@ -1043,17 +1059,7 @@ std::optional Store::GetUser(Snowflake id) const { return {}; } - UserData r; - - r.ID = id; - s->Get(1, r.Username); - s->Get(2, r.Discriminator); - s->Get(3, r.Avatar); - s->Get(4, r.IsBot); - s->Get(5, r.IsSystem); - s->Get(6, r.IsMFAEnabled); - s->Get(7, r.PremiumType); - s->Get(8, r.PublicFlags); + auto r = GetUserBound(s.get()); s->Reset(); diff --git a/src/discord/store.hpp b/src/discord/store.hpp index da97dd5..7b97ec0 100644 --- a/src/discord/store.hpp +++ b/src/discord/store.hpp @@ -39,6 +39,36 @@ public: std::optional GetBan(Snowflake guild_id, Snowflake user_id) const; std::vector GetBans(Snowflake guild_id) const; + template + std::vector GetUserDataBulk(Iter start, Iter end) { + std::string query = "SELECT * FROM users WHERE id IN ("; + for (Iter it = start; it != end; it++) { + query += "?,"; + } + query.pop_back(); + query += ")"; + + Statement stmt(m_db, query.c_str()); + if (!stmt.OK()) { + printf("failed to prepare GetUserDataBulk: %s\n", m_db.ErrStr()); + } + + int i = 0; + for (Iter it = start; it != end; it++) { + i++; + if (stmt.Bind(i, *it) != SQLITE_OK) { + printf("failed to bind GetUserDataBulk: %s\n", m_db.ErrStr()); + } + } + + std::vector r; + while (stmt.FetchOne()) { + r.push_back(GetUserBound(&stmt)); + } + + return r; + } + std::vector GetLastMessages(Snowflake id, size_t num) const; std::vector GetMessagesBefore(Snowflake channel_id, Snowflake message_id, size_t limit) const; std::vector GetPinnedMessages(Snowflake channel_id) const; @@ -240,6 +270,7 @@ private: Message GetMessageBound(std::unique_ptr &stmt) const; static RoleData GetRoleBound(std::unique_ptr &stmt); + UserData GetUserBound(Statement *stmt) const; void SetMessageInteractionPair(Snowflake message_id, const MessageInteractionData &interaction);