From: Vsevolod Stakhov Date: Sun, 3 Apr 2022 20:46:14 +0000 (+0100) Subject: [Project] Further rework tracking X-Git-Tag: 3.3~293^2~44 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6c9f364444edcf65b8cfdb2ffe001b7ddb6ed832;p=thirdparty%2Frspamd.git [Project] Further rework tracking --- diff --git a/src/libserver/symcache/symcache_impl.cxx b/src/libserver/symcache/symcache_impl.cxx index 7836c80b93..76bbf70b4b 100644 --- a/src/libserver/symcache/symcache_impl.cxx +++ b/src/libserver/symcache/symcache_impl.cxx @@ -27,38 +27,36 @@ auto symcache::init() -> bool auto res = true; reload_time = cfg->cache_reload_time; - if (cfg->cache_filename != NULL) { + if (cfg->cache_filename != nullptr) { res = load_items(); } - struct rspamd_symcache_item *it, *vit; - struct cache_dependency *dep; - struct delayed_cache_dependency *ddep; - struct delayed_cache_condition *dcond; - GList *cur; - gint i, j; - cur = cache->delayed_deps; - while (cur) { - ddep = cur->data; - - vit = rspamd_symcache_find_filter(cache, ddep->from, false); - it = rspamd_symcache_find_filter(cache, ddep->from, true); + /* Deal with the delayed dependencies */ + for (const auto &delayed_dep : *delayed_deps) { + auto virt_item = get_item_by_name(delayed_dep.from, false); + auto real_item = get_item_by_name(delayed_dep.from, true); - if (it == NULL || vit == NULL) { - msg_err_cache ("cannot register delayed dependency between %s and %s: " - "%s is missing", ddep->from, ddep->to, ddep->from); + if (virt_item == nullptr || real_item == nullptr) { + msg_err_cache("cannot register delayed dependency between %s and %s: " + "%s is missing", + delayed_dep.from.data(), + delayed_dep.to.data(), delayed_dep.from.data()); } else { - msg_debug_cache ("delayed between %s(%d:%d) -> %s", ddep->from, - it->id, vit->id, ddep->to); - rspamd_symcache_add_dependency(cache, it->id, ddep->to, vit != it ? - vit->id : -1); + msg_debug_cache("delayed between %s(%d:%d) -> %s", + delayed_dep.from.data(), + real_item->id, virt_item->id, + delayed_dep.to.data()); + add_dependency(real_item->id, delayed_dep.to, virt_item != real_item ? + virt_item->id : -1); } - - cur = g_list_next (cur); } + /* Remove delayed dependencies, as they are no longer needed at this point */ + delayed_deps.reset(); + + cur = cache->delayed_conditions; while (cur) { dcond = cur->data; @@ -320,14 +318,16 @@ bool symcache::save_items() const auto symcache::get_item_by_id(int id, bool resolve_parent) const -> const cache_item * { if (id < 0 || id >= items_by_id.size()) { - g_error("internal error: requested item with id %d, when we have just %d items in the cache", + msg_err_cache("internal error: requested item with id %d, when we have just %d items in the cache", id, (int)items_by_id.size()); - g_abort(); + return nullptr; } auto &ret = items_by_id[id]; if (!ret) { + msg_err_cache("internal error: requested item with id %d but it is empty; qed", + id); return nullptr; } @@ -338,6 +338,49 @@ auto symcache::get_item_by_id(int id, bool resolve_parent) const -> const cache_ return ret.get(); } +auto symcache::get_item_by_name(std::string_view name, bool resolve_parent) const -> const cache_item * +{ + auto it = items_by_symbol.find(name); + + if (it == items_by_symbol.end()) { + return nullptr; + } + + if (resolve_parent && it->second->is_virtual()) { + return it->second->get_parent(*this); + } + + return it->second.get(); +} + +auto symcache::add_dependency(int id_from, std::string_view to, int virtual_id_from)-> void +{ + g_assert (id_from >= 0 && id_from < (gint)items_by_id.size()); + const auto &source = items_by_id[id_from]; + g_assert (source.get() != nullptr); + + source->deps.emplace_back(cache_dependency{ + .item = cache_item_ptr{nullptr}, + .sym = std::string(to), + .id = id_from, + .vid = -1, + }); + + + if (virtual_id_from >= 0) { + g_assert (virtual_id_from < (gint)virtual_symbols.size()); + /* We need that for settings id propagation */ + const auto &vsource = virtual_symbols[virtual_id_from]; + g_assert (vsource.get() != nullptr); + vsource->deps.emplace_back(cache_dependency{ + .item = cache_item_ptr{nullptr}, + .sym = std::string(to), + .id = -1, + .vid = virtual_id_from, + }); + } +} + auto cache_item::get_parent(const symcache &cache) const -> const cache_item * { diff --git a/src/libserver/symcache/symcache_internal.hxx b/src/libserver/symcache/symcache_internal.hxx index 420004064a..b41c4a3dfa 100644 --- a/src/libserver/symcache/symcache_internal.hxx +++ b/src/libserver/symcache/symcache_internal.hxx @@ -217,6 +217,13 @@ public: auto get_parent(const symcache &cache) const -> const cache_item *; }; +struct cache_dependency { + cache_item_ptr item; /* Real dependency */ + std::string sym; /* Symbolic dep name */ + int id; /* Real from */ + int vid; /* Virtual from */ +}; + struct cache_item { /* This block is likely shared */ struct rspamd_symcache_item_stat *st; @@ -248,7 +255,7 @@ struct cache_item { id_list forbidden_ids; /* Dependencies */ - std::vector deps; + std::vector deps; /* Reverse dependencies */ std::vector rdeps; @@ -319,6 +326,8 @@ public: peak_cb = -1; cache_id = rspamd_random_uint64_fast(); L = (lua_State *)cfg->lua_state; + delayed_conditions = std::make_unique>(); + delayed_deps = std::make_unique>(); } virtual ~symcache() { @@ -327,7 +336,29 @@ public: } } + /** + * Get an item by ID + * @param id + * @param resolve_parent + * @return + */ auto get_item_by_id(int id, bool resolve_parent) const -> const cache_item *; + /** + * Get an item by it's name + * @param name + * @param resolve_parent + * @return + */ + auto get_item_by_name(std::string_view name, bool resolve_parent) const -> const cache_item *; + + /** + * Add a direct dependency + * @param id_from + * @param to + * @param virtual_id_from + * @return + */ + auto add_dependency(int id_from, std::string_view to, int virtual_id_from) -> void; /* * Initialises the symbols cache, must be called after all symbols are added