]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Project] Further rework tracking
authorVsevolod Stakhov <vsevolod@rspamd.com>
Sun, 3 Apr 2022 20:46:14 +0000 (21:46 +0100)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Sun, 3 Apr 2022 20:46:14 +0000 (21:46 +0100)
src/libserver/symcache/symcache_impl.cxx
src/libserver/symcache/symcache_internal.hxx

index 7836c80b93edfcc92084416e96446239eca241dc..76bbf70b4b1812a35267c60164fcc49b6723b362 100644 (file)
@@ -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 *
 {
index 420004064a5587c96c27459614c79319c59ba1f0..b41c4a3dfa024b16a35bfeef0b9b2a797ef4464b 100644 (file)
@@ -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<cache_item_ptr> deps;
+       std::vector<cache_dependency> deps;
        /* Reverse dependencies */
        std::vector<cache_item_ptr> 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<std::vector<delayed_cache_condition>>();
+               delayed_deps = std::make_unique<std::vector<delayed_cache_dependency>>();
        }
 
        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