From 44beae519d1966ebf96d53f858f4ea15932d0849 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 6 Sep 2023 15:56:10 +0200 Subject: [PATCH] tag/Pool: use doubly-linked list This adds some memory overhead but eliminates the linear search from tag_pool_put_item(). --- src/tag/Pool.cxx | 47 +++++++---------------------------------------- 1 file changed, 7 insertions(+), 40 deletions(-) diff --git a/src/tag/Pool.cxx b/src/tag/Pool.cxx index e27ee539d..006b1c35a 100644 --- a/src/tag/Pool.cxx +++ b/src/tag/Pool.cxx @@ -4,7 +4,7 @@ #include "Pool.hxx" #include "Item.hxx" #include "util/Cast.hxx" -#include "util/IntrusiveForwardList.hxx" +#include "util/IntrusiveList.hxx" #include "util/VarSize.hxx" #include @@ -18,7 +18,7 @@ Mutex tag_pool_lock; struct TagPoolSlot { - IntrusiveForwardListHook list_hook; + IntrusiveListHook list_hook; uint8_t ref = 1; TagItem item; @@ -45,8 +45,8 @@ TagPoolSlot::Create(TagType type, value); } -static std::array>, +static std::array>, 16127> slots; static inline unsigned @@ -60,19 +60,6 @@ calc_hash(TagType type, std::string_view p) noexcept return hash ^ type; } -static inline unsigned -calc_hash(TagType type, const char *p) noexcept -{ - unsigned hash = 5381; - - assert(p != nullptr); - - while (*p != 0) - hash = (hash << 5) + hash + *p++; - - return hash ^ type; -} - static constexpr TagPoolSlot * tag_item_to_slot(TagItem *item) noexcept { @@ -85,20 +72,12 @@ tag_value_list(TagType type, std::string_view value) noexcept return slots[calc_hash(type, value) % slots.size()]; } -static inline auto & -tag_value_list(TagType type, const char *value) noexcept -{ - return slots[calc_hash(type, value) % slots.size()]; -} - TagItem * tag_pool_get_item(TagType type, std::string_view value) noexcept { auto &list = tag_value_list(type, value); - for (auto i = list.before_begin(), n = std::next(i); n != list.end(); i = n) { - auto &slot = *n++; - + for (auto &slot : list) { if (slot.item.type == type && value == slot.item.value && slot.ref < TagPoolSlot::MAX_REF) { @@ -141,18 +120,6 @@ tag_pool_put_item(TagItem *item) noexcept if (slot->ref > 0) return; - auto &list = tag_value_list(item->type, item->value); - for (auto i = list.before_begin();;) { - const auto n = std::next(i); - auto &s = *n; - assert(i != list.end()); - - if (&s == slot) { - list.erase_after(i); - DeleteVarSize(slot); - return; - } - - i = n; - } + slot->list_hook.unlink(); + DeleteVarSize(slot); }