[babl] babl: cache state between babl runs
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [babl] babl: cache state between babl runs
- Date: Mon, 14 Nov 2016 01:09:06 +0000 (UTC)
commit 9e1f58146508dfc462ca68246582d1136ee8191d
Author: Øyvind Kolås <pippin gimp org>
Date: Mon Nov 14 00:45:15 2016 +0100
babl: cache state between babl runs
Store the contents of discovered babl_paths between runs, for now in
/tmp/babl.db , should move to a per-user dir to make it survive reboots.
The code should also check a versioning string at the start and bail if there
is any mismatch... since the data should be reconstructable; and more reliable
when reconstructed than a possibly old version.
babl/babl-fish-path.c | 31 ++++---
babl/babl.c | 245 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 262 insertions(+), 14 deletions(-)
---
diff --git a/babl/babl-fish-path.c b/babl/babl-fish-path.c
index bf9c520..f15d0e2 100644
--- a/babl/babl-fish-path.c
+++ b/babl/babl-fish-path.c
@@ -88,11 +88,11 @@ get_conversion_path (PathContext *pc,
int current_length,
int max_length);
-static char *
-create_name (char *buf,
- const Babl *source,
- const Babl *destination,
- int is_reference);
+char *
+_babl_fish_create_name (char *buf,
+ const Babl *source,
+ const Babl *destination,
+ int is_reference);
static double legal_error (void);
@@ -238,11 +238,11 @@ get_conversion_path (PathContext *pc,
}
}
-static char *
-create_name (char *buf,
- const Babl *source,
- const Babl *destination,
- int is_reference)
+char *
+_babl_fish_create_name (char *buf,
+ const Babl *source,
+ const Babl *destination,
+ int is_reference)
{
/* fish names are intentionally kept short */
snprintf (buf, BABL_MAX_NAME_LEN, "%s %p %p", "",
@@ -250,8 +250,11 @@ create_name (char *buf,
return buf;
}
-static int
-babl_fish_path_destroy (void *data)
+int
+_babl_fish_path_destroy (void *data);
+
+int
+_babl_fish_path_destroy (void *data)
{
Babl *babl=data;
if (babl->fish_path.conversion_list)
@@ -267,7 +270,7 @@ babl_fish_path (const Babl *source,
Babl *babl = NULL;
char name[BABL_MAX_NAME_LEN];
- create_name (name, source, destination, 1);
+ _babl_fish_create_name (name, source, destination, 1);
babl = babl_db_exist_by_name (babl_fish_db (), name);
if (babl)
{
@@ -279,7 +282,7 @@ babl_fish_path (const Babl *source,
babl = babl_calloc (1, sizeof (BablFishPath) +
strlen (name) + 1);
- babl_set_destructor (babl, babl_fish_path_destroy);
+ babl_set_destructor (babl, _babl_fish_path_destroy);
babl->class_type = BABL_FISH_PATH;
babl->instance.id = babl_fish_get_id (source, destination);
diff --git a/babl/babl.c b/babl/babl.c
index 0484d30..1287383 100644
--- a/babl/babl.c
+++ b/babl/babl.c
@@ -124,6 +124,244 @@ babl_dir_list (void)
return ret;
}
+static char *
+babl_fish_serialize (Babl *fish, char *dest, int n)
+{
+ switch (fish->class_type)
+ {
+ case BABL_FISH_PATH:
+ {
+ char *d = dest;
+
+ snprintf (d, n, "%s\n%s\n",
+ babl_get_name (fish->fish.source),
+ babl_get_name (fish->fish.destination));
+ n -= strlen (d);d += strlen (d);
+
+ snprintf (d, n, "\terror=%f", fish->fish.error);
+ n -= strlen (d);d += strlen (d);
+
+ snprintf (d, n, " processings=%i", fish->fish.processings);
+ n -= strlen (d);d += strlen (d);
+
+ snprintf (d, n, " pixels=%li", fish->fish.pixels);
+ n -= strlen (d);d += strlen (d);
+
+ snprintf (d, n, " cost=%f", fish->fish_path.cost);
+ n -= strlen (d);d += strlen (d);
+
+ snprintf (d, n, " loss=%f", fish->fish_path.loss);
+ n -= strlen (d);d += strlen (d);
+
+ snprintf (d, n, "\n");
+ n -= strlen (d);d += strlen (d);
+
+ for (int i = 0; i < fish->fish_path.conversion_list->count; i++)
+ {
+ snprintf (d, n, "\t%s\n",
+ babl_get_name(fish->fish_path.conversion_list->items[i] ));
+ n -= strlen (d);
+ d += strlen (d);
+ }
+ }
+ break;
+ case BABL_FISH_SIMPLE:
+ return NULL;
+ break;
+ case BABL_FISH_REFERENCE:
+ return NULL; break;
+ default:
+ break;
+ }
+
+ return dest;
+}
+
+static const char *fish_cache_path (void)
+{
+ return "/tmp/babl.db"; // XXX: a $HOME/.cache/babl/fishes path might be better
+}
+
+static void babl_store_db (void)
+{
+ BablDb *db = babl_fish_db ();
+ int i;
+ FILE *dbfile = fopen (fish_cache_path (), "w");
+ if (!dbfile)
+ return;
+ fprintf (dbfile, "#babl 0 %i fishes\n", db->babl_list->count);
+ for (i = 0; i< db->babl_list->count; i++)
+ {
+ Babl *fish = db->babl_list->items[i];
+ char tmp[8192];
+ if (babl_fish_serialize (fish, tmp, 4096))
+ fprintf (dbfile, "%s----\n", tmp);
+ }
+ fclose (dbfile);
+}
+
+static int
+babl_file_get_contents (const char *path,
+ char **contents,
+ long *length,
+ void *error)
+{
+ FILE *file;
+ long size;
+ char *buffer;
+
+ file = fopen (path,"rb");
+
+ if (!file)
+ return -1;
+
+ fseek (file, 0, SEEK_END);
+ size = ftell (file);
+ if (length) *length = size;
+ rewind (file);
+ buffer = malloc(size + 8);
+
+ if (!buffer)
+ {
+ fclose(file);
+ return -1;
+ }
+
+ size -= fread (buffer, 1, size, file);
+ if (size)
+ {
+ fclose (file);
+ free (buffer);
+ return -1;
+ }
+ fclose (file);
+ *contents = buffer;
+ return 0;
+}
+
+int
+_babl_fish_path_destroy (void *data);
+
+char *
+_babl_fish_create_name (char *buf,
+ const Babl *source,
+ const Babl *destination,
+ int is_reference);
+
+static void babl_init_db (const char *path)
+{
+ long length = -1;
+ char seps[] = "\n";
+ Babl *babl = NULL;
+ char *contents = NULL;
+ char *token;
+ char *tokp;
+ const Babl *from_format = NULL;
+ const Babl *to_format = NULL;
+#ifdef _WIN32 // XXX: fixme - make this work on windows
+ return;
+#endif
+
+ babl_file_get_contents (path, &contents, &length, NULL);
+ if (!contents)
+ return;
+
+ token = strtok_r (contents, seps, &tokp);
+ while( token != NULL )
+ {
+ switch (token[0])
+ {
+ case '-': /* finalize */
+ //fprintf (stderr, "%p %p\n", from_format, to_format);
+ if (babl)
+ babl_db_insert (babl_fish_db(), babl);
+ from_format = NULL;
+ to_format = NULL;
+ babl=NULL;
+ break;
+ case '#':
+ break;
+ case '\t':
+ if (strchr (token, '='))
+ {
+ char seps2[] = " ";
+ char *tokp2;
+ char *token2;
+ char name[4096];
+
+ _babl_fish_create_name (name, from_format, to_format, 1);
+ babl = babl_db_exist_by_name (babl_fish_db (), name);
+ if (babl)
+ {
+ fprintf (stderr, "%s:%i: loading of cache failed\n",
+ __FUNCTION__, __LINE__);
+ return;
+ }
+
+ babl = babl_calloc (1, sizeof (BablFishPath) +
+ strlen (name) + 1);
+ babl_set_destructor (babl, _babl_fish_path_destroy);
+
+ babl->class_type = BABL_FISH_PATH;
+ babl->instance.id = babl_fish_get_id (from_format, to_format);
+ babl->instance.name = ((char *) babl) + sizeof (BablFishPath);
+ strcpy (babl->instance.name, name);
+ babl->fish.source = from_format;
+ babl->fish.destination = to_format;
+ babl->fish_path.conversion_list = babl_list_init_with_size (10);
+
+ token2 = strtok_r (&token[1], seps2, &tokp2);
+ while( token2 != NULL )
+ {
+ if (!strncmp (token2, "error=", 6))
+ {
+ babl->fish.error = strtod (token2 + 6, NULL);
+ }
+ else if (!strncmp (token2, "cost=", 5))
+ {
+ babl->fish_path.cost = strtod (token2 + 5, NULL);
+ }
+ else if (!strncmp (token2, "loss=", 5))
+ {
+ babl->fish_path.loss = strtod (token2 + 5, NULL);
+ }
+ else if (!strncmp (token2, "pixels=", 7))
+ {
+ babl->fish.pixels = strtol (token2 + 7, NULL, 10);
+ }
+ else if (!strncmp (token2, "processings=", 12))
+ {
+ babl->fish.processings = strtol (token2 + 12, NULL, 10);
+ }
+ token2 = strtok_r (NULL, seps2, &tokp2);
+ }
+ }
+ else
+ {
+ Babl *conv =
+ (void*)babl_db_find(babl_conversion_db(), &token[1]);
+ if (!conv)
+ {
+ return;
+ }
+ else
+ babl_list_insert_last (babl->fish_path.conversion_list, conv);
+ }
+ break;
+ default:
+ if (!from_format)
+ from_format = babl_format (token);
+ else
+ to_format = babl_format (token);
+
+ break;
+ }
+ token = strtok_r (NULL, seps, &tokp);
+ }
+ if (contents)
+ free (contents);
+}
+
void
babl_init (void)
{
@@ -150,6 +388,8 @@ babl_init (void)
dir_list = babl_dir_list ();
babl_extension_load_dir_list (dir_list);
babl_free (dir_list);
+
+ babl_init_db (fish_cache_path());
}
}
@@ -158,6 +398,11 @@ babl_exit (void)
{
if (!-- ref_count)
{
+#ifdef _WIN32 // XXX: fixme - make this work on windows
+#else
+ babl_store_db ();
+#endif
+
if (getenv ("BABL_STATS"))
{
char logfile_name[] = "/tmp/babl-stats.html";
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]