try optimizing user fetch

This commit is contained in:
ouwou 2022-12-18 19:59:48 -05:00
parent 6926b12a50
commit 190118bb58
5 changed files with 64 additions and 21 deletions

View File

@ -70,12 +70,12 @@ void MemberList::UpdateMemberList() {
return;
}
std::set<Snowflake> ids;
std::vector<UserData> 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<int, RoleData> pos_to_role;
@ -83,23 +83,22 @@ void MemberList::UpdateMemberList() {
// std::unordered_map<Snowflake, int> user_to_color;
std::vector<Snowflake> 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;
}

View File

@ -262,6 +262,12 @@ std::set<Snowflake> DiscordClient::GetUsersInGuild(Snowflake id) const {
return {};
}
std::vector<UserData> DiscordClient::GetUserDataInGuildBulk(Snowflake id) {
const auto ids = GetUsersInGuild(id);
std::vector<Snowflake> test;
return m_store.GetUserDataBulk(ids.begin(), ids.end());
}
std::set<Snowflake> DiscordClient::GetChannelsInGuild(Snowflake id) const {
auto it = m_guild_to_channels.find(id);
if (it != m_guild_to_channels.end())

View File

@ -76,6 +76,7 @@ public:
Snowflake GetMemberHoistedRole(Snowflake guild_id, Snowflake user_id, bool with_color = false) const;
std::optional<RoleData> GetMemberHighestRole(Snowflake guild_id, Snowflake user_id) const;
std::set<Snowflake> GetUsersInGuild(Snowflake id) const;
std::vector<UserData> GetUserDataInGuildBulk(Snowflake id);
std::set<Snowflake> GetChannelsInGuild(Snowflake id) const;
std::vector<Snowflake> GetUsersInThread(Snowflake id) const;
std::vector<ChannelData> GetActiveThreads(Snowflake channel_id) const;

View File

@ -1033,6 +1033,22 @@ RoleData Store::GetRoleBound(std::unique_ptr<Statement> &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<UserData> Store::GetUser(Snowflake id) const {
auto &s = m_stmt_get_user;
s->Bind(1, id);
@ -1043,17 +1059,7 @@ std::optional<UserData> 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();

View File

@ -39,6 +39,36 @@ public:
std::optional<BanData> GetBan(Snowflake guild_id, Snowflake user_id) const;
std::vector<BanData> GetBans(Snowflake guild_id) const;
template<typename Iter>
std::vector<UserData> 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<UserData> r;
while (stmt.FetchOne()) {
r.push_back(GetUserBound(&stmt));
}
return r;
}
std::vector<Message> GetLastMessages(Snowflake id, size_t num) const;
std::vector<Message> GetMessagesBefore(Snowflake channel_id, Snowflake message_id, size_t limit) const;
std::vector<Message> GetPinnedMessages(Snowflake channel_id) const;
@ -240,6 +270,7 @@ private:
Message GetMessageBound(std::unique_ptr<Statement> &stmt) const;
static RoleData GetRoleBound(std::unique_ptr<Statement> &stmt);
UserData GetUserBound(Statement *stmt) const;
void SetMessageInteractionPair(Snowflake message_id, const MessageInteractionData &interaction);