Commit d919f8d5 authored by Max Kellermann's avatar Max Kellermann

ClientInternal: use std::set for subscriptions

parent d67aa7c1
......@@ -24,6 +24,9 @@
#include "ClientMessage.hxx"
#include "command.h"
#include <set>
#include <string>
#include <glib.h>
#undef G_LOG_DOMAIN
......@@ -82,7 +85,7 @@ public:
/**
* 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
......@@ -100,6 +103,11 @@ public:
* The number of messages in #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;
......
......@@ -120,7 +120,6 @@ client_new(struct player_control *player_control,
client->send_buf_used = 0;
client->subscriptions = NULL;
client->messages = NULL;
client->num_messages = 0;
......
......@@ -27,17 +27,6 @@ extern "C" {
#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
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))
return CLIENT_SUBSCRIBE_INVALID;
if (client_find_subscription(client, channel) != NULL)
return CLIENT_SUBSCRIBE_ALREADY;
if (client->num_subscriptions >= CLIENT_MAX_SUBSCRIPTIONS)
return CLIENT_SUBSCRIBE_FULL;
client->subscriptions = g_slist_prepend(client->subscriptions,
g_strdup(channel));
auto r = client->subscriptions.insert(channel);
if (!r.second)
return CLIENT_SUBSCRIBE_ALREADY;
++client->num_subscriptions;
idle_add(IDLE_SUBSCRIPTION);
......@@ -65,19 +53,19 @@ client_subscribe(Client *client, const char *channel)
bool
client_unsubscribe(Client *client, const char *channel)
{
GSList *i = client_find_subscription(client, channel);
if (i == NULL)
const auto i = client->subscriptions.find(channel);
if (i == client->subscriptions.end())
return false;
assert(client->num_subscriptions > 0);
client->subscriptions = g_slist_remove(client->subscriptions, i->data);
client->subscriptions.erase(i);
--client->num_subscriptions;
idle_add(IDLE_SUBSCRIPTION);
assert((client->num_subscriptions == 0) ==
(client->subscriptions == NULL));
client->subscriptions.empty());
return true;
}
......@@ -85,11 +73,7 @@ client_unsubscribe(Client *client, const char *channel)
void
client_unsubscribe_all(Client *client)
{
for (GSList *i = client->subscriptions; i != NULL; i = g_slist_next(i))
g_free(i->data);
g_slist_free(client->subscriptions);
client->subscriptions = NULL;
client->subscriptions.clear();
client->num_subscriptions = 0;
}
......@@ -101,7 +85,7 @@ client_push_message(Client *client, const struct client_message *msg)
assert(client_message_defined(msg));
if (client->num_messages >= CLIENT_MAX_MESSAGES ||
client_find_subscription(client, msg->channel) == NULL)
!client->IsSubscribed(msg->channel))
return false;
if (client->messages == NULL)
......
......@@ -83,12 +83,8 @@ collect_channels(gpointer data, gpointer user_data)
(struct channels_context *)user_data;
const Client *client = (const Client *)data;
for (GSList *i = client->subscriptions; i != NULL;
i = g_slist_next(i)) {
const char *channel = (const char *)i->data;
context->channels.insert(channel);
}
context->channels.insert(client->subscriptions.begin(),
client->subscriptions.end());
}
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