commit a92526d: [Minor] Add function to find out the maximum timeout for all symbols

Vsevolod Stakhov vsevolod at rspamd.com
Wed Aug 17 20:35:04 UTC 2022


Author: Vsevolod Stakhov
Date: 2022-08-17 21:30:54 +0100
URL: https://github.com/rspamd/rspamd/commit/a92526d6c6ac780f88959f382529b41e5e6e4194 (HEAD -> master)

[Minor] Add function to find out the maximum timeout for all symbols

---
 src/libserver/symcache/symcache_impl.cxx     | 65 ++++++++++++++++++++++++++++
 src/libserver/symcache/symcache_internal.hxx |  6 +++
 2 files changed, 71 insertions(+)

diff --git a/src/libserver/symcache/symcache_impl.cxx b/src/libserver/symcache/symcache_impl.cxx
index 98244b064..7508cbf95 100644
--- a/src/libserver/symcache/symcache_impl.cxx
+++ b/src/libserver/symcache/symcache_impl.cxx
@@ -1183,4 +1183,69 @@ symcache::process_settings_elt(struct rspamd_config_settings_elt *elt) -> void
 	}
 }
 
+auto symcache::get_max_timeout() const -> double
+{
+	double accumulated_timeout = 0;
+
+	auto get_item_timeout = [](const cache_item_ptr &it) {
+		return it->get_numeric_augmentation("timeout").value_or(0.0);
+	};
+
+	/* This function returns the timeout for an item and all it's dependencies */
+	auto get_filter_timeout = [&](const cache_item_ptr &it, auto self) -> double {
+		auto own_timeout = get_item_timeout(it);
+		double max_child_timeout = 0;
+
+		for (const auto &dep : it->deps) {
+			auto cld_timeout = self(dep.item, self);
+
+			if (cld_timeout > max_child_timeout) {
+				max_child_timeout = cld_timeout;
+			}
+		}
+
+		return own_timeout + max_child_timeout;
+	};
+
+	/* For prefilters and postfilters, we just care about priorities */
+	auto pre_postfilter_iter = [&](const items_ptr_vec &vec) {
+		auto saved_priority = -1;
+		double max_timeout = 0;
+		for (const auto &it : vec) {
+			if (it->priority != saved_priority) {
+				accumulated_timeout += max_timeout;
+				max_timeout = 0;
+				saved_priority = it->priority;
+			}
+
+			auto timeout = get_item_timeout(it);
+
+			if (timeout > max_timeout) {
+				max_timeout = timeout;
+			}
+		}
+	};
+
+	pre_postfilter_iter(this->prefilters);
+	pre_postfilter_iter(this->postfilters);
+	pre_postfilter_iter(this->idempotent);
+
+	/* For normal filters, we check the maximum chain of the dependencies
+	 * This function might have O(N^2) complexity if all symbols are in a single
+	 * dependencies chain. But it is not the case in practice
+	 */
+	double max_filters_timeout = 0;
+	for (const auto &it : this->filters) {
+		auto timeout = get_filter_timeout(it, get_filter_timeout);
+
+		if (timeout > max_filters_timeout) {
+			max_filters_timeout = timeout;
+		}
+	}
+
+	accumulated_timeout += max_filters_timeout;
+
+	return accumulated_timeout;
+}
+
 }
\ No newline at end of file
diff --git a/src/libserver/symcache/symcache_internal.hxx b/src/libserver/symcache/symcache_internal.hxx
index 51fed4a57..c227c8505 100644
--- a/src/libserver/symcache/symcache_internal.hxx
+++ b/src/libserver/symcache/symcache_internal.hxx
@@ -595,6 +595,12 @@ public:
 	 * @param elt
 	 */
 	auto process_settings_elt(struct rspamd_config_settings_elt *elt) -> void;
+
+	/**
+	 * Returns maximum timeout that is requested by all rules
+	 * @return
+	 */
+	auto get_max_timeout() const -> double;
 };
 
 


More information about the Commits mailing list