From 3ce34c5c14645c5d0ef2eb42ea39e4c09a350c0d Mon Sep 17 00:00:00 2001 From: Pavel Artsishevsky Date: Mon, 25 Nov 2024 15:25:00 +0100 Subject: [PATCH] Remove queue from SinkDriver::update_effective_sinks() Signed-off-by: Pavel Artsishevsky --- include/slimlog/sink-inl.h | 69 +++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/include/slimlog/sink-inl.h b/include/slimlog/sink-inl.h index 4d85087..c958c64 100644 --- a/include/slimlog/sink-inl.h +++ b/include/slimlog/sink-inl.h @@ -17,10 +17,9 @@ #include #include // IWYU pragma: keep -#include #include +#include #include -#include #include #include #include @@ -63,16 +62,12 @@ SinkDriver::SinkDriver(const Logger* logger, SinkDriver template SinkDriver::~SinkDriver() { - try { - const typename ThreadingPolicy::WriteLock lock(m_mutex); - for (auto* child : m_children) { - child->set_parent(m_parent); - } - if (m_parent) { - m_parent->remove_child(this); - } - } catch (...) { - std::terminate(); + const typename ThreadingPolicy::WriteLock lock(m_mutex); + for (auto* child : m_children) { + child->set_parent(m_parent); + } + if (m_parent) { + m_parent->remove_child(this); } } @@ -154,33 +149,39 @@ auto SinkDriver::remove_child(SinkDriver* child) -> voi template auto SinkDriver::update_effective_sinks() -> void { - // Queue for level order traversal - std::queue nodes; - nodes.push(this); - while (!nodes.empty()) { - auto* node = nodes.front(); - if (node->m_parent) { - node->m_effective_sinks = node->m_parent->m_effective_sinks; - for (const auto& [sink, enabled] : node->m_sinks) { - if (enabled) { - node->m_effective_sinks.insert_or_assign(sink.get(), node->m_logger); - } else { - node->m_effective_sinks.erase(sink.get()); - } + SinkDriver* current = this; + while (current) { + // Update the current node's effective sinks + current->m_effective_sinks = current->m_parent ? current->m_parent->m_effective_sinks + : decltype(current->m_effective_sinks)(); + for (const auto& [sink, enabled] : current->m_sinks) { + if (enabled) { + current->m_effective_sinks.insert_or_assign(sink.get(), current->m_logger); + } else { + current->m_effective_sinks.erase(sink.get()); } - } else { - node->m_effective_sinks.clear(); - for (const auto& [sink, enabled] : node->m_sinks) { - if (enabled) { - node->m_effective_sinks.emplace(sink.get(), node->m_logger); + } + + // Find the next node in level order + SinkDriver* next = nullptr; + if (current->m_children.empty()) { + // Move to the next sibling or parent's sibling + SinkDriver* parent = current->m_parent; + SinkDriver* prev = current; + while (parent && !next) { + if (auto prev_it = parent->m_children.find(prev); + std::distance(prev_it, parent->m_children.end()) > 1) { + next = *std::next(prev_it); } + prev = parent; + parent = parent->m_parent != this ? parent->m_parent : nullptr; } + } else { + // Nove to next level + next = *current->m_children.begin(); } - nodes.pop(); - for (auto* child : node->m_children) { - nodes.push(child); - } + current = next; } }