Commit d919f8d5 authored by Max Kellermann's avatar Max Kellermann

ClientInternal: use std::set for subscriptions

parent d67aa7c1
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
#include "ClientMessage.hxx" #include "ClientMessage.hxx"
#include "command.h" #include "command.h"
#include <set>
#include <string>
#include <glib.h> #include <glib.h>
#undef G_LOG_DOMAIN #undef G_LOG_DOMAIN
...@@ -82,7 +85,7 @@ public: ...@@ -82,7 +85,7 @@ public:
/** /**
* A list of channel names this client is subscribed to. * A list of channel names this client is subscribed to.
*/ */
GSList *subscriptions; std::set<std::string> subscriptions;
/** /**
* The number of subscriptions in #subscriptions. Used to * The number of subscriptions in #subscriptions. Used to
...@@ -100,6 +103,11 @@ public: ...@@ -100,6 +103,11 @@ public:
* The number of messages in #messages. * The number of messages in #messages.
*/ */
unsigned num_messages; unsigned num_messages;
gcc_pure
bool IsSubscribed(const char *channel_name) const {
return subscriptions.find(channel_name) != subscriptions.end();
}
}; };
extern unsigned int client_max_connections; extern unsigned int client_max_connections;
......
...@@ -120,7 +120,6 @@ client_new(struct player_control *player_control, ...@@ -120,7 +120,6 @@ client_new(struct player_control *player_control,
client->send_buf_used = 0; client->send_buf_used = 0;
client->subscriptions = NULL;
client->messages = NULL; client->messages = NULL;
client->num_messages = 0; client->num_messages = 0;
......
...@@ -27,17 +27,6 @@ extern "C" { ...@@ -27,17 +27,6 @@ extern "C" {
#include <string.h> #include <string.h>
G_GNUC_PURE
static GSList *
client_find_subscription(const Client *client, const char *channel)
{
for (GSList *i = client->subscriptions; i != NULL; i = g_slist_next(i))
if (strcmp((const char *)i->data, channel) == 0)
return i;
return NULL;
}
enum client_subscribe_result enum client_subscribe_result
client_subscribe(Client *client, const char *channel) client_subscribe(Client *client, const char *channel)
{ {
...@@ -47,14 +36,13 @@ client_subscribe(Client *client, const char *channel) ...@@ -47,14 +36,13 @@ client_subscribe(Client *client, const char *channel)
if (!client_message_valid_channel_name(channel)) if (!client_message_valid_channel_name(channel))
return CLIENT_SUBSCRIBE_INVALID; return CLIENT_SUBSCRIBE_INVALID;
if (client_find_subscription(client, channel) != NULL)
return CLIENT_SUBSCRIBE_ALREADY;
if (client->num_subscriptions >= CLIENT_MAX_SUBSCRIPTIONS) if (client->num_subscriptions >= CLIENT_MAX_SUBSCRIPTIONS)
return CLIENT_SUBSCRIBE_FULL; return CLIENT_SUBSCRIBE_FULL;
client->subscriptions = g_slist_prepend(client->subscriptions, auto r = client->subscriptions.insert(channel);
g_strdup(channel)); if (!r.second)
return CLIENT_SUBSCRIBE_ALREADY;
++client->num_subscriptions; ++client->num_subscriptions;
idle_add(IDLE_SUBSCRIPTION); idle_add(IDLE_SUBSCRIPTION);
...@@ -65,19 +53,19 @@ client_subscribe(Client *client, const char *channel) ...@@ -65,19 +53,19 @@ client_subscribe(Client *client, const char *channel)
bool bool
client_unsubscribe(Client *client, const char *channel) client_unsubscribe(Client *client, const char *channel)
{ {
GSList *i = client_find_subscription(client, channel); const auto i = client->subscriptions.find(channel);
if (i == NULL) if (i == client->subscriptions.end())
return false; return false;
assert(client->num_subscriptions > 0); assert(client->num_subscriptions > 0);
client->subscriptions = g_slist_remove(client->subscriptions, i->data); client->subscriptions.erase(i);
--client->num_subscriptions; --client->num_subscriptions;
idle_add(IDLE_SUBSCRIPTION); idle_add(IDLE_SUBSCRIPTION);
assert((client->num_subscriptions == 0) == assert((client->num_subscriptions == 0) ==
(client->subscriptions == NULL)); client->subscriptions.empty());
return true; return true;
} }
...@@ -85,11 +73,7 @@ client_unsubscribe(Client *client, const char *channel) ...@@ -85,11 +73,7 @@ client_unsubscribe(Client *client, const char *channel)
void void
client_unsubscribe_all(Client *client) client_unsubscribe_all(Client *client)
{ {
for (GSList *i = client->subscriptions; i != NULL; i = g_slist_next(i)) client->subscriptions.clear();
g_free(i->data);
g_slist_free(client->subscriptions);
client->subscriptions = NULL;
client->num_subscriptions = 0; client->num_subscriptions = 0;
} }
...@@ -101,7 +85,7 @@ client_push_message(Client *client, const struct client_message *msg) ...@@ -101,7 +85,7 @@ client_push_message(Client *client, const struct client_message *msg)
assert(client_message_defined(msg)); assert(client_message_defined(msg));
if (client->num_messages >= CLIENT_MAX_MESSAGES || if (client->num_messages >= CLIENT_MAX_MESSAGES ||
client_find_subscription(client, msg->channel) == NULL) !client->IsSubscribed(msg->channel))
return false; return false;
if (client->messages == NULL) if (client->messages == NULL)
......
...@@ -83,12 +83,8 @@ collect_channels(gpointer data, gpointer user_data) ...@@ -83,12 +83,8 @@ collect_channels(gpointer data, gpointer user_data)
(struct channels_context *)user_data; (struct channels_context *)user_data;
const Client *client = (const Client *)data; const Client *client = (const Client *)data;
for (GSList *i = client->subscriptions; i != NULL; context->channels.insert(client->subscriptions.begin(),
i = g_slist_next(i)) { client->subscriptions.end());
const char *channel = (const char *)i->data;
context->channels.insert(channel);
}
} }
enum command_return enum command_return
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment