From 9bd62aef042c65427f60473e591e719c51121903 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Sep 2008 19:33:16 +0200 Subject: add tdb based shared lookup cache --- src/sound-theme-spec.c | 95 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 23 deletions(-) (limited to 'src/sound-theme-spec.c') diff --git a/src/sound-theme-spec.c b/src/sound-theme-spec.c index e906e9a..1473ec0 100644 --- a/src/sound-theme-spec.c +++ b/src/sound-theme-spec.c @@ -30,6 +30,7 @@ #include "sound-theme-spec.h" #include "malloc.h" #include "llist.h" +#include "cache.h" #define DEFAULT_THEME "freedesktop" #define FALLBACK_THEME "freedesktop" @@ -419,6 +420,7 @@ fail: static int find_sound_for_suffix( ca_sound_file **f, ca_sound_file_open_callback_t sfopen, + char **sound_path, const char *theme_name, const char *name, const char *path, @@ -456,7 +458,10 @@ static int find_sound_for_suffix( } else ret = sfopen(f, fn); - ca_free(fn); + if (ret == CA_SUCCESS && sound_path) + *sound_path = fn; + else + ca_free(fn); return ret; } @@ -464,6 +469,7 @@ static int find_sound_for_suffix( static int find_sound_in_locale( ca_sound_file **f, ca_sound_file_open_callback_t sfopen, + char **sound_path, const char *theme_name, const char *name, const char *path, @@ -484,9 +490,9 @@ static int find_sound_in_locale( sprintf(p, "%s/sounds", path); - if ((ret = find_sound_for_suffix(f, sfopen, theme_name, name, p, ".disabled", locale, subdir)) == CA_ERROR_NOTFOUND) - if ((ret = find_sound_for_suffix(f, sfopen, theme_name, name, p, ".ogg", locale, subdir)) == CA_ERROR_NOTFOUND) - ret = find_sound_for_suffix(f, sfopen, theme_name, name, p, ".wav", locale, subdir); + if ((ret = find_sound_for_suffix(f, sfopen, sound_path, theme_name, name, p, ".disabled", locale, subdir)) == CA_ERROR_NOTFOUND) + if ((ret = find_sound_for_suffix(f, sfopen, sound_path,theme_name, name, p, ".ogg", locale, subdir)) == CA_ERROR_NOTFOUND) + ret = find_sound_for_suffix(f, sfopen, sound_path,theme_name, name, p, ".wav", locale, subdir); ca_free(p); @@ -496,6 +502,7 @@ static int find_sound_in_locale( static int find_sound_for_locale( ca_sound_file **f, ca_sound_file_open_callback_t sfopen, + char **sound_path, const char *theme_name, const char *name, const char *path, @@ -512,7 +519,7 @@ static int find_sound_for_locale( ca_return_val_if_fail(locale, CA_ERROR_INVALID); /* First, try the locale def itself */ - if ((ret = find_sound_in_locale(f, sfopen, theme_name, name, path, locale, subdir)) != CA_ERROR_NOTFOUND) + if ((ret = find_sound_in_locale(f, sfopen, sound_path, theme_name, name, path, locale, subdir)) != CA_ERROR_NOTFOUND) return ret; /* Then, try to truncate at the @ */ @@ -522,7 +529,7 @@ static int find_sound_for_locale( if (!(t = ca_strndup(locale, (size_t) (e - locale)))) return CA_ERROR_OOM; - ret = find_sound_in_locale(f, sfopen, theme_name, name, path, t, subdir); + ret = find_sound_in_locale(f, sfopen, sound_path, theme_name, name, path, t, subdir); ca_free(t); if (ret != CA_ERROR_NOTFOUND) @@ -536,7 +543,7 @@ static int find_sound_for_locale( if (!(t = ca_strndup(locale, (size_t) (e - locale)))) return CA_ERROR_OOM; - ret = find_sound_in_locale(f, sfopen, theme_name, name, path, t, subdir); + ret = find_sound_in_locale(f, sfopen, sound_path, theme_name, name, path, t, subdir); ca_free(t); if (ret != CA_ERROR_NOTFOUND) @@ -545,16 +552,17 @@ static int find_sound_for_locale( /* Then, try "C" as fallback locale */ if (strcmp(locale, "C")) - if ((ret = find_sound_in_locale(f, sfopen, theme_name, name, path, "C", subdir)) != CA_ERROR_NOTFOUND) + if ((ret = find_sound_in_locale(f, sfopen, sound_path, theme_name, name, path, "C", subdir)) != CA_ERROR_NOTFOUND) return ret; /* Try without locale */ - return find_sound_in_locale(f, sfopen, theme_name, name, path, NULL, subdir); + return find_sound_in_locale(f, sfopen, sound_path, theme_name, name, path, NULL, subdir); } static int find_sound_for_name( ca_sound_file **f, ca_sound_file_open_callback_t sfopen, + char **sound_path, const char *theme_name, const char *name, const char *path, @@ -568,7 +576,7 @@ static int find_sound_for_name( ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); ca_return_val_if_fail(name && *name, CA_ERROR_INVALID); - if ((ret = find_sound_for_locale(f, sfopen, theme_name, name, path, locale, subdir)) != CA_ERROR_NOTFOUND) + if ((ret = find_sound_for_locale(f, sfopen, sound_path, theme_name, name, path, locale, subdir)) != CA_ERROR_NOTFOUND) return ret; k = strchr(name, 0); @@ -586,7 +594,7 @@ static int find_sound_for_name( if (!(n = ca_strndup(name, (size_t) (k-name)))) return CA_ERROR_OOM; - if ((ret = find_sound_for_locale(f, sfopen, theme_name, n, path, locale, subdir)) != CA_ERROR_NOTFOUND) { + if ((ret = find_sound_for_locale(f, sfopen, sound_path, theme_name, n, path, locale, subdir)) != CA_ERROR_NOTFOUND) { ca_free(n); return ret; } @@ -598,6 +606,7 @@ static int find_sound_for_name( static int find_sound_in_subdir( ca_sound_file **f, ca_sound_file_open_callback_t sfopen, + char **sound_path, const char *theme_name, const char *name, const char *locale, @@ -615,7 +624,7 @@ static int find_sound_in_subdir( return ret; if (e) { - ret = find_sound_for_name(f, sfopen, theme_name, name, e, locale, subdir); + ret = find_sound_for_name(f, sfopen, sound_path, theme_name, name, e, locale, subdir); ca_free(e); if (ret != CA_ERROR_NOTFOUND) @@ -635,7 +644,7 @@ static int find_sound_in_subdir( if (!(p = ca_strndup(g, k))) return CA_ERROR_OOM; - ret = find_sound_for_name(f, sfopen, theme_name, name, p, locale, subdir); + ret = find_sound_for_name(f, sfopen, sound_path, theme_name, name, p, locale, subdir); ca_free(p); if (ret != CA_ERROR_NOTFOUND) @@ -654,6 +663,7 @@ static int find_sound_in_subdir( static int find_sound_in_profile( ca_sound_file **f, ca_sound_file_open_callback_t sfopen, + char **sound_path, ca_theme_data *t, const char *name, const char *locale, @@ -670,7 +680,7 @@ static int find_sound_in_profile( if (data_dir_matches(d, profile)) { int ret; - if ((ret = find_sound_in_subdir(f, sfopen, d->theme_name, name, locale, d->dir_name)) != CA_ERROR_NOTFOUND) + if ((ret = find_sound_in_subdir(f, sfopen, sound_path, d->theme_name, name, locale, d->dir_name)) != CA_ERROR_NOTFOUND) return ret; } @@ -680,6 +690,7 @@ static int find_sound_in_profile( static int find_sound_in_theme( ca_sound_file **f, ca_sound_file_open_callback_t sfopen, + char **sound_path, ca_theme_data *t, const char *name, const char *locale, @@ -694,22 +705,23 @@ static int find_sound_in_theme( if (t) { /* First, try the profile def itself */ - if ((ret = find_sound_in_profile(f, sfopen, t, name, locale, profile)) != CA_ERROR_NOTFOUND) + if ((ret = find_sound_in_profile(f, sfopen, sound_path, t, name, locale, profile)) != CA_ERROR_NOTFOUND) return ret; /* Then, fall back to stereo */ if (!ca_streq(profile, DEFAULT_OUTPUT_PROFILE)) - if ((ret = find_sound_in_profile(f, sfopen, t, name, locale, DEFAULT_OUTPUT_PROFILE)) != CA_ERROR_NOTFOUND) + if ((ret = find_sound_in_profile(f, sfopen, sound_path, t, name, locale, DEFAULT_OUTPUT_PROFILE)) != CA_ERROR_NOTFOUND) return ret; } /* And fall back to no profile */ - return find_sound_in_subdir(f, sfopen, t ? t->name : NULL, name, locale, NULL); + return find_sound_in_subdir(f, sfopen, sound_path, t ? t->name : NULL, name, locale, NULL); } static int find_sound_for_theme( ca_sound_file **f, ca_sound_file_open_callback_t sfopen, + char **sound_path, ca_theme_data **t, const char *theme, const char *name, @@ -732,17 +744,18 @@ static int find_sound_for_theme( ret = load_theme_data(t, FALLBACK_THEME); if (ret == CA_SUCCESS) - if ((ret = find_sound_in_theme(f, sfopen, *t, name, locale, profile)) != CA_ERROR_NOTFOUND) + if ((ret = find_sound_in_theme(f, sfopen, sound_path, *t, name, locale, profile)) != CA_ERROR_NOTFOUND) return ret; /* Then, fall back to "unthemed" files */ - return find_sound_in_theme(f, sfopen, NULL, name, locale, profile); + return find_sound_in_theme(f, sfopen, sound_path, NULL, name, locale, profile); } int ca_lookup_sound_with_callback( ca_sound_file **f, - ca_sound_file_open_callback_t sfopen, - ca_theme_data **t, + ca_sound_file_open_callback_t sfopen, + char **sound_path, + ca_theme_data **t, ca_proplist *cp, ca_proplist *sp) { int ret = CA_ERROR_INVALID; @@ -754,6 +767,11 @@ int ca_lookup_sound_with_callback( ca_return_val_if_fail(sp, CA_ERROR_INVALID); ca_return_val_if_fail(sfopen, CA_ERROR_INVALID); + *f = NULL; + + if (sound_path) + *sound_path = NULL; + ca_mutex_lock(cp->mutex); ca_mutex_lock(sp->mutex); @@ -775,7 +793,36 @@ int ca_lookup_sound_with_callback( if (!(profile = ca_proplist_gets_unlocked(cp, CA_PROP_CANBERRA_XDG_THEME_OUTPUT_PROFILE))) profile = DEFAULT_OUTPUT_PROFILE; - ret = find_sound_for_theme(f, sfopen, t, theme, name, locale, profile); +#ifdef HAVE_CACHE + if ((ret = ca_cache_lookup_sound(f, sfopen, sound_path, theme, name, locale, profile)) >= 0) { + + /* This entry is available in the cache, let's transform + * negative cache entries to CA_ERROR_NOTFOUND */ + + if (!*f) + ret = CA_ERROR_NOTFOUND; + + } else { + char *spath = NULL; + + /* Either this entry was not available in the database, + * neither positive nor negative, or the database was + * corrupt, or it was out-of-date. In all cases try to + * find the entry manually. */ + + if ((ret = find_sound_for_theme(f, sfopen, sound_path ? sound_path : &spath, t, theme, name, locale, profile)) >= 0) + /* Ok, we found it. Let's update the cache */ + ca_cache_store_sound(theme, name, locale, profile, sound_path ? *sound_path : spath); + else if (ret == CA_ERROR_NOTFOUND) + /* Doesn't seem to be around, let's create a negative cache entry */ + ca_cache_store_sound(theme, name, locale, profile, NULL); + + ca_free(spath); + } + +#else + ret = find_sound_for_theme(f, sfopen, sound_path, t, theme, name, locale, profile); +#endif } if (ret == CA_ERROR_NOTFOUND || !name) { @@ -791,10 +838,12 @@ int ca_lookup_sound_with_callback( int ca_lookup_sound( ca_sound_file **f, + char **sound_path, ca_theme_data **t, ca_proplist *cp, ca_proplist *sp) { - return ca_lookup_sound_with_callback(f, ca_sound_file_open, t, cp, sp); + + return ca_lookup_sound_with_callback(f, ca_sound_file_open, sound_path, t, cp, sp); } void ca_theme_data_free(ca_theme_data *t) { -- cgit