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 11, 2016
1 parent 300c5b8 commit 9254a9e
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 @@ -1266,4 +1266,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 9254a9e

Please sign in to comment.