commit 6c9f364: [Project] Further rework tracking

Vsevolod Stakhov vsevolod at rspamd.com
Sat Apr 30 19:21:15 UTC 2022


Author: Vsevolod Stakhov
Date: 2022-04-03 21:46:14 +0100
URL: https://github.com/rspamd/rspamd/commit/6c9f364444edcf65b8cfdb2ffe001b7ddb6ed832

[Project] Further rework tracking

---
 src/libserver/symcache/symcache_impl.cxx     | 91 ++++++++++++++++++++--------
 src/libserver/symcache/symcache_internal.hxx | 33 +++++++++-
 2 files changed, 99 insertions(+), 25 deletions(-)

diff --git a/src/libserver/symcache/symcache_impl.cxx b/src/libserver/symcache/symcache_impl.cxx
index 7836c80b9..76bbf70b4 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 420004064..b41c4a3df 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<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


More information about the Commits mailing list