util/Intrusive*: move `constant_time_size` to an options struct

This makes it easier to add more options later.
This commit is contained in:
Max Kellermann 2023-09-11 18:48:21 +02:00 committed by Max Kellermann
parent 1f495efb46
commit f01793ad4a
8 changed files with 44 additions and 31 deletions

View File

@ -49,7 +49,7 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
std::unique_ptr<ClientListener> listener; std::unique_ptr<ClientListener> listener;
IntrusiveList<Client, ClientPerPartitionListHook, false> clients; IntrusiveList<Client, ClientPerPartitionListHook> clients;
/** /**
* Monitor for idle events local to this partition. * Monitor for idle events local to this partition.

View File

@ -1,8 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
// Copyright The Music Player Daemon Project // Copyright The Music Player Daemon Project
#ifndef MPD_REMOTE_TAG_CACHE_HXX #pragma once
#define MPD_REMOTE_TAG_CACHE_HXX
#include "input/RemoteTagScanner.hxx" #include "input/RemoteTagScanner.hxx"
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
@ -84,12 +83,13 @@ class RemoteTagCache final {
*/ */
ItemList invoke_list; ItemList invoke_list;
IntrusiveHashSet<Item, 127, IntrusiveHashSet<
IntrusiveHashSetOperators<std::hash<std::string_view>, Item, 127,
std::equal_to<std::string_view>, IntrusiveHashSetOperators<std::hash<std::string_view>,
Item::GetUri>, std::equal_to<std::string_view>,
IntrusiveHashSetBaseHookTraits<Item>, Item::GetUri>,
true> map; IntrusiveHashSetBaseHookTraits<Item>,
IntrusiveHashSetOptions{.constant_time_size = true}> map;
public: public:
RemoteTagCache(EventLoop &event_loop, RemoteTagCache(EventLoop &event_loop,
@ -107,5 +107,3 @@ private:
void ItemResolved(Item &item) noexcept; void ItemResolved(Item &item) noexcept;
}; };
#endif

View File

@ -1,15 +1,16 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
// Copyright The Music Player Daemon Project // Copyright The Music Player Daemon Project
#ifndef MPD_CLIENT_LIST_HXX #pragma once
#define MPD_CLIENT_LIST_HXX
#include "Client.hxx" #include "Client.hxx"
#include "util/IntrusiveList.hxx" #include "util/IntrusiveList.hxx"
class ClientList { class ClientList {
using List = using List = IntrusiveList<
IntrusiveList<Client, IntrusiveListMemberHookTraits<&Client::list_siblings>, true>; Client,
IntrusiveListMemberHookTraits<&Client::list_siblings>,
IntrusiveListOptions{.constant_time_size = true}>;
const unsigned max_size; const unsigned max_size;
@ -39,5 +40,3 @@ public:
void Remove(Client &client) noexcept; void Remove(Client &client) noexcept;
}; };
#endif

View File

@ -6,8 +6,7 @@
* Internal declarations for the "httpd" audio output plugin. * Internal declarations for the "httpd" audio output plugin.
*/ */
#ifndef MPD_OUTPUT_HTTPD_INTERNAL_H #pragma once
#define MPD_OUTPUT_HTTPD_INTERNAL_H
#include "HttpdClient.hxx" #include "HttpdClient.hxx"
#include "output/Interface.hxx" #include "output/Interface.hxx"
@ -121,8 +120,9 @@ private:
* A linked list containing all clients which are currently * A linked list containing all clients which are currently
* connected. * connected.
*/ */
IntrusiveList<HttpdClient, IntrusiveListBaseHookTraits<HttpdClient>, IntrusiveList<
true> clients; HttpdClient, IntrusiveListBaseHookTraits<HttpdClient>,
IntrusiveListOptions{.constant_time_size = true}> clients;
/** /**
* The maximum number of clients connected at the same time. * The maximum number of clients connected at the same time.
@ -255,5 +255,3 @@ private:
}; };
extern const class Domain httpd_output_domain; extern const class Domain httpd_output_domain;
#endif

View File

@ -14,6 +14,10 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
struct IntrusiveForwardListOptions {
bool constant_time_size = false;
};
struct IntrusiveForwardListNode { struct IntrusiveForwardListNode {
IntrusiveForwardListNode *next; IntrusiveForwardListNode *next;
}; };
@ -93,8 +97,10 @@ struct IntrusiveForwardListMemberHookTraits {
*/ */
template<typename T, template<typename T,
typename HookTraits=IntrusiveForwardListBaseHookTraits<T>, typename HookTraits=IntrusiveForwardListBaseHookTraits<T>,
bool constant_time_size=false> IntrusiveForwardListOptions options=IntrusiveForwardListOptions{}>
class IntrusiveForwardList { class IntrusiveForwardList {
static constexpr bool constant_time_size = options.constant_time_size;
IntrusiveForwardListNode head{nullptr}; IntrusiveForwardListNode head{nullptr};
[[no_unique_address]] [[no_unique_address]]
@ -145,7 +151,7 @@ public:
:head(src.head) :head(src.head)
{ {
// shallow copies mess with the counter // shallow copies mess with the counter
static_assert(!constant_time_size); static_assert(!options.constant_time_size);
} }
IntrusiveForwardList &operator=(IntrusiveForwardList &&src) noexcept { IntrusiveForwardList &operator=(IntrusiveForwardList &&src) noexcept {

View File

@ -10,6 +10,10 @@
#include <array> #include <array>
#include <numeric> // for std::accumulate() #include <numeric> // for std::accumulate()
struct IntrusiveHashSetOptions {
bool constant_time_size = false;
};
template<IntrusiveHookMode mode=IntrusiveHookMode::NORMAL> template<IntrusiveHookMode mode=IntrusiveHookMode::NORMAL>
struct IntrusiveHashSetHook { struct IntrusiveHashSetHook {
using SiblingsHook = IntrusiveListHook<mode>; using SiblingsHook = IntrusiveListHook<mode>;
@ -106,8 +110,10 @@ struct IntrusiveHashSetOperators {
template<typename T, std::size_t table_size, template<typename T, std::size_t table_size,
typename Operators, typename Operators,
typename HookTraits=IntrusiveHashSetBaseHookTraits<T>, typename HookTraits=IntrusiveHashSetBaseHookTraits<T>,
bool constant_time_size=false> IntrusiveHashSetOptions options=IntrusiveHashSetOptions{}>
class IntrusiveHashSet { class IntrusiveHashSet {
static constexpr bool constant_time_size = options.constant_time_size;
[[no_unique_address]] [[no_unique_address]]
OptionalCounter<constant_time_size> counter; OptionalCounter<constant_time_size> counter;

View File

@ -13,6 +13,10 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
struct IntrusiveListOptions {
bool constant_time_size = false;
};
struct IntrusiveListNode { struct IntrusiveListNode {
IntrusiveListNode *next, *prev; IntrusiveListNode *next, *prev;
@ -27,7 +31,7 @@ template<IntrusiveHookMode _mode=IntrusiveHookMode::NORMAL>
class IntrusiveListHook { class IntrusiveListHook {
template<typename T> friend struct IntrusiveListBaseHookTraits; template<typename T> friend struct IntrusiveListBaseHookTraits;
template<auto member> friend struct IntrusiveListMemberHookTraits; template<auto member> friend struct IntrusiveListMemberHookTraits;
template<typename T, typename HookTraits, bool> friend class IntrusiveList; template<typename T, typename HookTraits, IntrusiveListOptions> friend class IntrusiveList;
protected: protected:
IntrusiveListNode siblings; IntrusiveListNode siblings;
@ -135,8 +139,10 @@ struct IntrusiveListMemberHookTraits {
*/ */
template<typename T, template<typename T,
typename HookTraits=IntrusiveListBaseHookTraits<T>, typename HookTraits=IntrusiveListBaseHookTraits<T>,
bool constant_time_size=false> IntrusiveListOptions options=IntrusiveListOptions{}>
class IntrusiveList { class IntrusiveList {
static constexpr bool constant_time_size = options.constant_time_size;
IntrusiveListNode head{&head, &head}; IntrusiveListNode head{&head, &head};
[[no_unique_address]] [[no_unique_address]]

View File

@ -14,11 +14,11 @@
*/ */
template<typename T, typename Compare=typename T::Compare, template<typename T, typename Compare=typename T::Compare,
typename HookTraits=IntrusiveListBaseHookTraits<T>, typename HookTraits=IntrusiveListBaseHookTraits<T>,
bool constant_time_size=false> IntrusiveListOptions options=IntrusiveListOptions{}>
class IntrusiveSortedList class IntrusiveSortedList
: public IntrusiveList<T, HookTraits, constant_time_size> : public IntrusiveList<T, HookTraits, options>
{ {
using Base = IntrusiveList<T, HookTraits, constant_time_size>; using Base = IntrusiveList<T, HookTraits, options>;
[[no_unique_address]] [[no_unique_address]]
Compare compare; Compare compare;