Skip to content

Commit

Permalink
dict-sql: Cache reading settings files.
Browse files Browse the repository at this point in the history
The settings were read for every dict init, which was done for every new
dict connection. This was using a lot of CPU. There are usually only a
couple dict-sql settings files, so we cache all of the ones we read.
  • Loading branch information
sirainen committed May 12, 2016
1 parent 5aa6420 commit fa4f8f3
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 4 deletions.
49 changes: 47 additions & 2 deletions src/lib-dict/dict-sql-settings.c
Expand Up @@ -3,6 +3,7 @@
#include "lib.h"
#include "array.h"
#include "str.h"
#include "hash.h"
#include "settings.h"
#include "dict-sql-settings.h"

Expand Down Expand Up @@ -42,6 +43,14 @@ static const struct setting_def dict_sql_map_setting_defs[] = {
{ 0, NULL, 0 }
};

struct dict_sql_settings_cache {
pool_t pool;
const char *path;
struct dict_sql_settings *set;
};

static HASH_TABLE(const char *, struct dict_sql_settings_cache *) dict_sql_settings_cache;

static const char *pattern_read_name(const char **pattern)
{
const char *p = *pattern, *name;
Expand Down Expand Up @@ -235,9 +244,20 @@ parse_section(const char *type, const char *name ATTR_UNUSED,
}

struct dict_sql_settings *
dict_sql_settings_read(pool_t pool, const char *path, const char **error_r)
dict_sql_settings_read(const char *path, const char **error_r)
{
struct setting_parser_ctx ctx;
struct dict_sql_settings_cache *cache;
pool_t pool = pool_alloconly_create("dict sql settings", 1024);

if (!hash_table_is_created(dict_sql_settings_cache)) {
hash_table_create(&dict_sql_settings_cache, default_pool, 0,
str_hash, strcmp);
}

cache = hash_table_lookup(dict_sql_settings_cache, path);
if (cache != NULL)
return cache->set;

memset(&ctx, 0, sizeof(ctx));
ctx.pool = pool;
Expand All @@ -246,14 +266,39 @@ dict_sql_settings_read(pool_t pool, const char *path, const char **error_r)
p_array_init(&ctx.set->maps, pool, 8);

if (!settings_read(path, NULL, parse_setting, parse_section,
&ctx, error_r))
&ctx, error_r)) {
pool_unref(&pool);
return NULL;
}

if (ctx.set->connect == NULL) {
*error_r = t_strdup_printf("Error in configuration file %s: "
"Missing connect setting", path);
pool_unref(&pool);
return NULL;
}

cache = p_new(pool, struct dict_sql_settings_cache, 1);
cache->pool = pool;
cache->path = p_strdup(pool, path);
cache->set = ctx.set;

hash_table_insert(dict_sql_settings_cache, cache->path, cache);
return ctx.set;
}

void dict_sql_settings_deinit(void)
{
struct hash_iterate_context *iter;
struct dict_sql_settings_cache *cache;
const char *key;

if (!hash_table_is_created(dict_sql_settings_cache))
return;

iter = hash_table_iterate_init(dict_sql_settings_cache);
while (hash_table_iterate(iter, dict_sql_settings_cache, &key, &cache))
pool_unref(&cache->pool);
hash_table_iterate_deinit(&iter);
hash_table_destroy(&dict_sql_settings_cache);
}
4 changes: 3 additions & 1 deletion src/lib-dict/dict-sql-settings.h
Expand Up @@ -33,6 +33,8 @@ struct dict_sql_settings {
};

struct dict_sql_settings *
dict_sql_settings_read(pool_t pool, const char *path, const char **error_r);
dict_sql_settings_read(const char *path, const char **error_r);

void dict_sql_settings_deinit(void);

#endif
3 changes: 2 additions & 1 deletion src/lib-dict/dict-sql.c
Expand Up @@ -88,7 +88,7 @@ sql_dict_init(struct dict *driver, const char *uri,
dict->pool = pool;
dict->dict = *driver;
dict->username = p_strdup(pool, set->username);
dict->set = dict_sql_settings_read(pool, uri, error_r);
dict->set = dict_sql_settings_read(uri, error_r);
if (dict->set == NULL) {
pool_unref(&pool);
return -1;
Expand Down Expand Up @@ -1289,4 +1289,5 @@ void dict_sql_unregister(void)
dict_driver_unregister(&dict_sql_drivers[i]);
i_free(dict_sql_drivers);
sql_db_cache_deinit(&dict_sql_db_cache);
dict_sql_settings_deinit();
}

0 comments on commit fa4f8f3

Please sign in to comment.