struct rspamd_stat_cache {
const char *name;
- gpointer (*init)(struct rspamd_stat_ctx *ctx, struct rspamd_config *cfg);
+ gpointer (*init)(struct rspamd_stat_ctx *ctx,
+ struct rspamd_config *cfg, const ucl_object_t *cf);
gint (*process)(struct rspamd_task *task,
gboolean is_spam,
gpointer ctx);
};
gpointer rspamd_stat_cache_sqlite3_init(struct rspamd_stat_ctx *ctx,
- struct rspamd_config *cfg);
+ struct rspamd_config *cfg,
+ const ucl_object_t *cf);
gint rspamd_stat_cache_sqlite3_process (
struct rspamd_task *task,
gboolean is_spam, gpointer c);
gpointer
rspamd_stat_cache_sqlite3_init(struct rspamd_stat_ctx *ctx,
- struct rspamd_config *cfg)
+ struct rspamd_config *cfg,
+ const ucl_object_t *cf)
{
struct rspamd_stat_sqlite3_ctx *new = NULL;
- struct rspamd_classifier_config *clf;
- const ucl_object_t *obj, *elt;
- GList *cur;
+ const ucl_object_t *elt;
gchar dbpath[PATH_MAX];
+ const gchar *path;
sqlite3 *sqlite;
- gboolean has_sqlite_cache = FALSE;
GError *err = NULL;
- rspamd_snprintf (dbpath, sizeof (dbpath), SQLITE_CACHE_PATH);
- cur = cfg->classifiers;
- while (cur) {
- clf = cur->data;
+ if (cf) {
+ elt = ucl_object_find_key (cf, "path");
- obj = ucl_object_find_key (clf->opts, "cache");
-
- /* Sqlite3 cache is the default learn cache method */
- if (obj == NULL) {
- has_sqlite_cache = TRUE;
- break;
+ if (elt != NULL) {
+ path = ucl_object_tostring (elt);
+ }
+ else {
+ path = SQLITE_CACHE_PATH;
}
- else if (ucl_object_type (obj) == UCL_OBJECT) {
- elt = ucl_object_find_key (obj, "name");
+ }
- if (ucl_object_type (elt) == UCL_STRING &&
- g_ascii_strcasecmp (ucl_object_tostring (elt), "sqlite3") == 0) {
+ rspamd_snprintf (dbpath, sizeof (dbpath), "%s", path);
- has_sqlite_cache = TRUE;
- elt = ucl_object_find_key (obj, "path");
- if (elt != NULL && ucl_object_type (elt) == UCL_STRING) {
- rspamd_snprintf (dbpath, sizeof (dbpath), "%s",
- ucl_object_tostring (elt));
- }
- }
- }
+ sqlite = rspamd_sqlite3_open_or_create (cfg->cfg_pool,
+ dbpath, create_tables_sql, &err);
- cur = g_list_next (cur);
+ if (sqlite == NULL) {
+ msg_err ("cannot open sqlite3 cache: %e", err);
+ g_error_free (err);
+ err = NULL;
}
+ else {
+ new = g_slice_alloc (sizeof (*new));
+ new->db = sqlite;
+ new->prstmt = rspamd_sqlite3_init_prstmt (sqlite, prepared_stmts,
+ RSPAMD_STAT_CACHE_MAX, &err);
- if (has_sqlite_cache) {
- sqlite = rspamd_sqlite3_open_or_create (cfg->cfg_pool,
- dbpath, create_tables_sql, &err);
-
- if (sqlite == NULL) {
- msg_err_config ("cannot open sqlite3 cache: %e", err);
+ if (new->prstmt == NULL) {
+ msg_err ("cannot open sqlite3 cache: %e", err);
g_error_free (err);
err = NULL;
- }
- else {
- new = g_slice_alloc (sizeof (*new));
- new->db = sqlite;
- new->prstmt = rspamd_sqlite3_init_prstmt (sqlite, prepared_stmts,
- RSPAMD_STAT_CACHE_MAX, &err);
-
- if (new->prstmt == NULL) {
- msg_err_config ("cannot open sqlite3 cache: %e", err);
- g_error_free (err);
- err = NULL;
- sqlite3_close (sqlite);
- g_slice_free1 (sizeof (*new), new);
- new = NULL;
- }
+ sqlite3_close (sqlite);
+ g_slice_free1 (sizeof (*new), new);
+ new = NULL;
}
}
struct rspamd_statfile_config *stf;
struct rspamd_stat_backend *bk;
struct rspamd_statfile *st;
+ struct rspamd_classifier *cl;
+ const ucl_object_t *cache_obj = NULL, *cache_name_obj;
+ const gchar *cache_name = NULL;
if (stat_ctx == NULL) {
stat_ctx = g_slice_alloc0 (sizeof (*stat_ctx));
}
- stat_ctx->backends = stat_backends;
+ stat_ctx->backends_subrs = stat_backends;
stat_ctx->backends_count = G_N_ELEMENTS (stat_backends);
- stat_ctx->classifiers = stat_classifiers;
+ stat_ctx->classifiers_subrs = stat_classifiers;
stat_ctx->classifiers_count = G_N_ELEMENTS (stat_classifiers);
- stat_ctx->tokenizers = stat_tokenizers;
+ stat_ctx->tokenizers_subrs = stat_tokenizers;
stat_ctx->tokenizers_count = G_N_ELEMENTS (stat_tokenizers);
- stat_ctx->caches = stat_caches;
+ stat_ctx->caches_subrs = stat_caches;
stat_ctx->caches_count = G_N_ELEMENTS (stat_caches);
stat_ctx->cfg = cfg;
+ stat_ctx->statfiles = g_ptr_array_new ();
+ stat_ctx->classifiers = g_ptr_array_new ();
REF_RETAIN (stat_ctx->cfg);
/* Create statfiles from the classifiers */
clf->tokenizer, NULL);
}
+ cl = g_slice_alloc0 (sizeof (*cl));
+ cl->cfg = clf;
+ cl->statfiles_ids = g_array_new (FALSE, FALSE, sizeof (gint));
+
+ /* Init classifier cache */
+ if (clf->opts) {
+ cache_obj = ucl_object_find_key (clf->opts, "cache");
+
+ if (cache_obj) {
+ cache_name_obj = ucl_object_find_key (cache_obj, "name");
+ }
+
+ if (cache_name_obj) {
+ cache_name = ucl_object_tostring (cache_name_obj);
+ }
+ }
+
+ cl->cache = rspamd_stat_get_cache (cache_name);
+ g_assert (cl->cache != NULL);
+ cl->cachecf = cl->cache->init (stat_ctx, cfg, cache_obj);
+
curst = clf->statfiles;
while (curst) {
stf = curst->data;
st = g_slice_alloc0 (sizeof (*st));
- st->clcf = clf;
+ st->classifier = cl;
st->stcf = stf;
- st->tkcf = stat_ctx->tkcf;
- st->bkcf = stat_ctx->backends[i].init (stat_ctx, cfg, st);
- msg_debug_config ("added backend %s", stat_ctx->backends[i].name);
+ st->bkcf = stat_ctx->backends_subrs[i].init (stat_ctx, cfg, st);
+ msg_debug_config ("added backend %s",
+ stat_ctx->backends_subrs[i].name);
if (st->bkcf == NULL) {
msg_err_config ("cannot init backend %s for statfile %s",
g_slice_free1 (sizeof (*st), st);
}
else {
+ st->id = stat_ctx->statfiles->len;
g_ptr_array_add (stat_ctx->statfiles, st);
+ g_array_append_val (cl->statfiles_ids, st->id);
}
curst = curst->next;
}
- cur = cur->next;
- }
+ g_ptr_array_add (stat_ctx->classifiers, cl);
- /* Init caches */
- for (i = 0; i < stat_ctx->caches_count; i ++) {
- stat_ctx->caches[i].ctx = stat_ctx->caches[i].init (stat_ctx, cfg);
- msg_debug_config ("added cache %s", stat_ctx->caches[i].name);
+ cur = cur->next;
}
}
g_assert (stat_ctx != NULL);
for (i = 0; i < stat_ctx->backends_count; i ++) {
- if (stat_ctx->backends[i].close != NULL) {
- stat_ctx->backends[i].close (stat_ctx->backends[i].ctx);
- msg_debug_config ("closed backend %s", stat_ctx->backends[i].name);
+ if (stat_ctx->backends_subrs[i].close != NULL) {
+ stat_ctx->backends_subrs[i].close (stat_ctx->backends_subrs[i].ctx);
+ msg_debug_config ("closed backend %s", stat_ctx->backends_subrs[i].name);
}
}
guint i;
for (i = 0; i < stat_ctx->classifiers_count; i ++) {
- if (strcmp (name, stat_ctx->classifiers[i].name) == 0) {
- return &stat_ctx->classifiers[i];
+ if (strcmp (name, stat_ctx->classifiers_subrs[i].name) == 0) {
+ return &stat_ctx->classifiers_subrs[i];
}
}
}
for (i = 0; i < stat_ctx->backends_count; i ++) {
- if (strcmp (name, stat_ctx->backends[i].name) == 0) {
- return &stat_ctx->backends[i];
+ if (strcmp (name, stat_ctx->backends_subrs[i].name) == 0) {
+ return &stat_ctx->backends_subrs[i];
}
}
}
for (i = 0; i < stat_ctx->tokenizers_count; i ++) {
- if (strcmp (name, stat_ctx->tokenizers[i].name) == 0) {
- return &stat_ctx->tokenizers[i];
+ if (strcmp (name, stat_ctx->tokenizers_subrs[i].name) == 0) {
+ return &stat_ctx->tokenizers_subrs[i];
+ }
+ }
+
+ return NULL;
+}
+
+struct rspamd_stat_cache *
+rspamd_stat_get_cache (const gchar *name)
+{
+ guint i;
+
+ if (name == NULL || name[0] == '\0') {
+ name = RSPAMD_DEFAULT_CACHE;
+ }
+
+ for (i = 0; i < stat_ctx->caches_count; i++) {
+ if (strcmp (name, stat_ctx->caches_subrs[i].name) == 0) {
+ return &stat_ctx->caches_subrs[i];
}
}
struct rspamd_stat_ctx {
/* Subroutines for all objects */
- struct rspamd_stat_classifier *classifiers;
+ struct rspamd_stat_classifier *classifiers_subrs;
guint classifiers_count;
- struct rspamd_stat_tokenizer *tokenizers;
+ struct rspamd_stat_tokenizer *tokenizers_subrs;
guint tokenizers_count;
- struct rspamd_stat_backend *backends;
+ struct rspamd_stat_backend *backends_subrs;
guint backends_count;
- struct rspamd_stat_cache *caches;
+ struct rspamd_stat_cache *caches_subrs;
guint caches_count;
/* Runtime configuration */
- GPtrArray *statfiles; /* struct statfile */
+ GPtrArray *statfiles; /* struct rspamd_statfile */
+ GPtrArray *classifiers; /* struct rspamd_classifier */
struct rspamd_config *cfg;
/* Global tokenizer */
struct rspamd_stat_tokenizer *tokenizer;
struct rspamd_stat_classifier * rspamd_stat_get_classifier (const gchar *name);
struct rspamd_stat_backend * rspamd_stat_get_backend (const gchar *name);
struct rspamd_stat_tokenizer * rspamd_stat_get_tokenizer (const gchar *name);
+struct rspamd_stat_cache * rspamd_stat_get_cache (const gchar *name);
static GQuark rspamd_stat_quark (void)
{