aboutsummaryrefslogtreecommitdiffstats
path: root/src/libserver/symcache
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rspamd.com>2022-08-17 21:30:54 +0100
committerVsevolod Stakhov <vsevolod@rspamd.com>2022-08-17 21:30:54 +0100
commita92526d6c6ac780f88959f382529b41e5e6e4194 (patch)
treead92092743805a40df5ae098a5febb290f64d0ce /src/libserver/symcache
parent6e726dc807bfd927329b223586d809bd3d3d58f6 (diff)
downloadrspamd-a92526d6c6ac780f88959f382529b41e5e6e4194.tar.gz
rspamd-a92526d6c6ac780f88959f382529b41e5e6e4194.zip
[Minor] Add function to find out the maximum timeout for all symbols
Diffstat (limited to 'src/libserver/symcache')
-rw-r--r--src/libserver/symcache/symcache_impl.cxx65
-rw-r--r--src/libserver/symcache/symcache_internal.hxx6
2 files changed, 71 insertions, 0 deletions
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;
};