ClientList: use class boost::intrusive::list

Eliminate extra allocations for the std::list node instances.
This commit is contained in:
Max Kellermann 2014-06-10 18:57:30 +02:00
parent 0801b3f495
commit 3364c1b893
4 changed files with 25 additions and 29 deletions

View File

@ -27,6 +27,8 @@
#include "event/TimeoutMonitor.hxx"
#include "Compiler.h"
#include <boost/intrusive/list.hpp>
#include <set>
#include <string>
#include <list>
@ -41,12 +43,20 @@ struct Partition;
class Database;
class Storage;
class Client final : private FullyBufferedSocket, TimeoutMonitor {
class Client final
: FullyBufferedSocket, TimeoutMonitor,
public boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> {
public:
Partition &partition;
struct playlist &playlist;
struct PlayerControl &player_control;
struct Disposer {
void operator()(Client *client) const {
delete client;
}
};
unsigned permission;
/** the uid of the client process, or -1 if unknown */

View File

@ -28,28 +28,15 @@
void
ClientList::Remove(Client &client)
{
assert(size > 0);
assert(!list.empty());
auto i = std::find(list.begin(), list.end(), &client);
assert(i != list.end());
list.erase(i);
--size;
list.erase(list.iterator_to(client));
}
void
ClientList::CloseAll()
{
while (!list.empty()) {
delete list.front();
list.pop_front();
#ifndef NDEBUG
--size;
#endif
}
assert(size == 0);
list.clear_and_dispose(Client::Disposer());
}
void
@ -57,6 +44,6 @@ ClientList::IdleAdd(unsigned flags)
{
assert(flags != 0);
for (const auto &client : list)
client->IdleAdd(flags);
for (auto &client : list)
client.IdleAdd(flags);
}

View File

@ -20,21 +20,21 @@
#ifndef MPD_CLIENT_LIST_HXX
#define MPD_CLIENT_LIST_HXX
#include <list>
#include "Client.hxx"
class Client;
class ClientList {
typedef std::list<Client *> List;
typedef boost::intrusive::list<Client,
boost::intrusive::constant_time_size<true>> List;
const unsigned max_size;
unsigned size;
List list;
public:
ClientList(unsigned _max_size)
:max_size(_max_size), size(0) {}
:max_size(_max_size) {}
~ClientList() {
CloseAll();
}
@ -48,12 +48,11 @@ public:
}
bool IsFull() const {
return size >= max_size;
return list.size() >= max_size;
}
void Add(Client &client) {
list.push_front(&client);
++size;
list.push_front(client);
}
void Remove(Client &client);

View File

@ -82,8 +82,8 @@ handle_channels(Client &client,
std::set<std::string> channels;
for (const auto &c : *client.partition.instance.client_list)
channels.insert(c->subscriptions.begin(),
c->subscriptions.end());
channels.insert(c.subscriptions.begin(),
c.subscriptions.end());
for (const auto &channel : channels)
client_printf(client, "channel: %s\n", channel.c_str());
@ -122,8 +122,8 @@ handle_send_message(Client &client,
bool sent = false;
const ClientMessage msg(argv[1], argv[2]);
for (const auto &c : *client.partition.instance.client_list)
if (c->PushMessage(msg))
for (auto &c : *client.partition.instance.client_list)
if (c.PushMessage(msg))
sent = true;
if (sent)