GPtrArray *items_by_order;
GPtrArray *items_by_id;
GList *delayed_deps;
+ GList *delayed_conditions;
rspamd_mempool_t *static_pool;
gdouble max_weight;
guint used_items;
gchar *to;
};
+struct delayed_cache_condition {
+ gchar *sym;
+ gint cbref;
+ lua_State *L;
+};
+
struct cache_savepoint {
guchar *processed_bits;
guint pass;
struct cache_item *it, *dit;
struct cache_dependency *dep, *rdep;
struct delayed_cache_dependency *ddep;
+ struct delayed_cache_condition *dcond;
GList *cur;
guint i, j;
+ gint id;
g_ptr_array_sort_with_data (cache->items_by_order, cache_logic_cmp, cache);
while (cur) {
ddep = cur->data;
- it = g_hash_table_lookup (cache->items_by_symbol, ddep->from);
+ id = rspamd_symbols_cache_find_symbol (cache, ddep->from);
+ if (id != -1) {
+ it = g_ptr_array_index (cache->items_by_id, id);
+ }
+ else {
+ it = NULL;
+ }
if (it == NULL) {
msg_err_cache ("cannot register delayed dependency between %s and %s, "
cur = g_list_next (cur);
}
+ cur = cache->delayed_conditions;
+ while (cur) {
+ dcond = cur->data;
+
+ id = rspamd_symbols_cache_find_symbol (cache, dcond->sym);
+ if (id != -1) {
+ it = g_ptr_array_index (cache->items_by_id, id);
+ }
+ else {
+ it = NULL;
+ }
+
+ if (it == NULL) {
+ msg_err_cache (
+ "cannot register delayed condition for %s",
+ dcond->sym);
+ luaL_unref (dcond->L, LUA_REGISTRYINDEX, dcond->cbref);
+ }
+ else {
+ rspamd_symbols_cache_add_condition (cache, it->id, dcond->L,
+ dcond->cbref);
+ }
+
+ cur = g_list_next (cur);
+ }
+
for (i = 0; i < cache->items_by_id->len; i ++) {
it = g_ptr_array_index (cache->items_by_id, i);
item->condition_cb = cbref;
+ msg_debug_cache ("adding condition at lua ref %d to %s (%d)",
+ cbref, item->symbol, item->id);
+
return TRUE;
}
+gboolean rspamd_symbols_cache_add_condition_delayed (struct symbols_cache *cache,
+ const gchar *sym, lua_State *L, gint cbref)
+{
+ gint id;
+ struct delayed_cache_condition *ncond;
+
+ g_assert (cache != NULL);
+ g_assert (sym != NULL);
+
+ id = rspamd_symbols_cache_find_symbol (cache, sym);
+
+ if (id != -1) {
+ /* We already know id, so just register a direct condition */
+ return rspamd_symbols_cache_add_condition (cache, id, L, cbref);
+ }
+
+ ncond = g_slice_alloc (sizeof (*ncond));
+ ncond->sym = g_strdup (sym);
+ ncond->cbref = cbref;
+ ncond->L = L;
+
+ cache->delayed_conditions = g_list_prepend (cache->delayed_conditions, ncond);
+
+ return TRUE;
+}
+
+
void
rspamd_symbols_cache_destroy (struct symbols_cache *cache)
{
GList *cur;
struct delayed_cache_dependency *ddep;
+ struct delayed_cache_condition *dcond;
if (cache != NULL) {
g_list_free (cache->delayed_deps);
}
+ if (cache->delayed_conditions) {
+ cur = cache->delayed_conditions;
+
+ while (cur) {
+ dcond = cur->data;
+ g_free (dcond->sym);
+ g_slice_free1 (sizeof (*dcond), dcond);
+ cur = g_list_next (cur);
+ }
+
+ g_list_free (cache->delayed_conditions);
+ }
+
g_hash_table_destroy (cache->items_by_symbol);
rspamd_mempool_delete (cache->static_pool);
g_ptr_array_free (cache->items_by_id, TRUE);
item = g_hash_table_lookup (cache->items_by_symbol, name);
if (item != NULL) {
- return item->id;
+
+ while (item != NULL && item->parent != -1) {
+ item = g_ptr_array_index (cache->items_by_id, item->parent);
+ }
+
+ return item ? item->id : -1;
}
return -1;
* @param cbref callback reference (returned by luaL_ref)
* @return TRUE if condition has been added
*/
-gboolean rspamd_symbols_cache_add_condition (struct symbols_cache *cache, gint id, lua_State *L, gint cbref);
+gboolean rspamd_symbols_cache_add_condition (struct symbols_cache *cache,
+ gint id, lua_State *L, gint cbref);
+
+
+/**
+ * Add delayed condition to the specific symbol in cache. So symbol can be absent
+ * to the moment of addition
+ * @param cache
+ * @param id id of symbol
+ * @param L lua state pointer
+ * @param cbref callback reference (returned by luaL_ref)
+ * @return TRUE if condition has been added
+ */
+gboolean rspamd_symbols_cache_add_condition_delayed (struct symbols_cache *cache,
+ const gchar *sym, lua_State *L, gint cbref);
/**
- * Find symbol in cache by id and returns its id
+ * Find symbol in cache by id and returns its id resolving virtual symbols if
+ * applicable
* @param cache
* @param name
* @return id of symbol or (-1) if a symbol has not been found