From 7ece08c71d12dfcebfc0395f7727d717033f0641 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Mon, 14 Jun 2010 19:18:07 +0200 Subject: [PATCH] graph_def.[ch]: Implemented DEF-based graph generation. --- graph_def.c | 130 ++++++++++++++++++++++++++++------------------- graph_def.h | 13 ++++- graph_list.c | 163 ++++++++++++++++++++++++++++++++++++----------------------- 3 files changed, 191 insertions(+), 115 deletions(-) diff --git a/graph_def.c b/graph_def.c index 181788a..926fde2 100644 --- a/graph_def.c +++ b/graph_def.c @@ -12,6 +12,7 @@ struct graph_def_s { graph_ident_t *select; + char *ds_name; uint32_t color; graph_def_t *next; @@ -24,11 +25,15 @@ struct graph_def_s /* * Public functions */ -graph_def_t *def_create (graph_config_t *cfg, graph_ident_t *ident) /* {{{ */ +graph_def_t *def_create (graph_config_t *cfg, graph_ident_t *ident, /* {{{ */ + const char *ds_name) { graph_ident_t *selector; graph_def_t *ret; + if ((cfg == NULL) || (ident == NULL) || (ds_name == NULL)) + return (NULL); + selector = gl_graph_get_selector (cfg); if (selector == NULL) return (NULL); @@ -40,6 +45,15 @@ graph_def_t *def_create (graph_config_t *cfg, graph_ident_t *ident) /* {{{ */ return (NULL); } memset (ret, 0, sizeof (*ret)); + + ret->ds_name = strdup (ds_name); + if (ret->ds_name == NULL) + { + ident_destroy (selector); + free (ret); + return (NULL); + } + ret->color = get_random_color (); ret->next = NULL; @@ -48,6 +62,7 @@ graph_def_t *def_create (graph_config_t *cfg, graph_ident_t *ident) /* {{{ */ if (ret->select == NULL) { ident_destroy (selector); + free (ret->ds_name); free (ret); return (NULL); } @@ -67,6 +82,8 @@ void def_destroy (graph_def_t *def) /* {{{ */ ident_destroy (def->select); + free (def->ds_name); + free (def); def_destroy (next); @@ -88,28 +105,56 @@ int def_append (graph_def_t *head, graph_def_t *def) /* {{{ */ return (0); } /* }}} int def_append */ -graph_def_t *def_search (graph_def_t *head, graph_ident_t *ident) /* {{{ */ +graph_def_t *def_search (graph_def_t *head, graph_ident_t *ident, /* {{{ */ + const char *ds_name) { graph_def_t *ptr; - if ((head == NULL) || (ident == NULL)) + if ((head == NULL) || (ident == NULL) || (ds_name == NULL)) return (NULL); for (ptr = head; ptr != NULL; ptr = ptr->next) - if (ident_matches (ptr->select, ident)) + { + if (!ident_matches (ptr->select, ident)) + continue; + + if (strcmp (ptr->ds_name, ds_name) == 0) return (ptr); + } return (NULL); } /* }}} graph_def_t *def_search */ +_Bool def_matches (graph_def_t *def, graph_ident_t *ident) /* {{{ */ +{ + return (ident_matches (def->select, ident)); +} /* }}} _Bool def_matches */ + +int def_foreach (graph_def_t *def, def_callback_t callback, /* {{{ */ + void *user_data) +{ + graph_def_t *ptr; + + if ((def == NULL) || (callback == NULL)) + return (EINVAL); + + for (ptr = def; ptr != NULL; ptr = ptr->next) + { + int status; + + status = (*callback) (ptr, user_data); + if (status != 0) + return (status); + } + + return (0); +} /* }}} int def_foreach */ + int def_get_rrdargs (graph_def_t *def, graph_ident_t *ident, /* {{{ */ str_array_t *args) { char *file; - char **dses = NULL; - size_t dses_num = 0; - int status; - size_t i; + int index; if ((def == NULL) || (ident == NULL) || (args == NULL)) return (EINVAL); @@ -123,50 +168,33 @@ int def_get_rrdargs (graph_def_t *def, graph_ident_t *ident, /* {{{ */ DEBUG ("gl_ident_get_rrdargs: file = %s;\n", file); - status = ds_list_from_rrd_file (file, &dses_num, &dses); - if (status != 0) - { - free (file); - return (status); - } - - for (i = 0; i < dses_num; i++) - { - int index; - - DEBUG ("gl_ident_get_rrdargs: ds[%lu] = %s;\n", (unsigned long) i, dses[i]); - - index = array_argc (args); - - /* CDEFs */ - array_append_format (args, "DEF:def_%04i_min=%s:%s:MIN", - index, file, dses[i]); - array_append_format (args, "DEF:def_%04i_avg=%s:%s:AVERAGE", - index, file, dses[i]); - array_append_format (args, "DEF:def_%04i_max=%s:%s:MAX", - index, file, dses[i]); - /* VDEFs */ - array_append_format (args, "VDEF:vdef_%04i_min=def_%04i_min,MINIMUM", - index, index); - array_append_format (args, "VDEF:vdef_%04i_avg=def_%04i_avg,AVERAGE", - index, index); - array_append_format (args, "VDEF:vdef_%04i_max=def_%04i_max,MAXIMUM", - index, index); - array_append_format (args, "VDEF:vdef_%04i_lst=def_%04i_avg,LAST", - index, index); - - /* Graph part */ - array_append_format (args, "LINE1:def_%04i_avg#%06"PRIx32":%s", - index, def->color, dses[i]); - array_append_format (args, "GPRINT:vdef_%04i_min:%%lg min,", index); - array_append_format (args, "GPRINT:vdef_%04i_avg:%%lg avg,", index); - array_append_format (args, "GPRINT:vdef_%04i_max:%%lg max,", index); - array_append_format (args, "GPRINT:vdef_%04i_lst:%%lg last\\l", index); - - free (dses[i]); - } + index = array_argc (args); + + /* CDEFs */ + array_append_format (args, "DEF:def_%04i_min=%s:%s:MIN", + index, file, def->ds_name); + array_append_format (args, "DEF:def_%04i_avg=%s:%s:AVERAGE", + index, file, def->ds_name); + array_append_format (args, "DEF:def_%04i_max=%s:%s:MAX", + index, file, def->ds_name); + /* VDEFs */ + array_append_format (args, "VDEF:vdef_%04i_min=def_%04i_min,MINIMUM", + index, index); + array_append_format (args, "VDEF:vdef_%04i_avg=def_%04i_avg,AVERAGE", + index, index); + array_append_format (args, "VDEF:vdef_%04i_max=def_%04i_max,MAXIMUM", + index, index); + array_append_format (args, "VDEF:vdef_%04i_lst=def_%04i_avg,LAST", + index, index); + + /* Graph part */ + array_append_format (args, "LINE1:def_%04i_avg#%06"PRIx32":%s", + index, def->color, def->ds_name); + array_append_format (args, "GPRINT:vdef_%04i_min:%%lg min,", index); + array_append_format (args, "GPRINT:vdef_%04i_avg:%%lg avg,", index); + array_append_format (args, "GPRINT:vdef_%04i_max:%%lg max,", index); + array_append_format (args, "GPRINT:vdef_%04i_lst:%%lg last\\l", index); - free (dses); free (file); return (0); diff --git a/graph_def.h b/graph_def.h index f9c4f5a..3c27ac8 100644 --- a/graph_def.h +++ b/graph_def.h @@ -8,13 +8,22 @@ struct graph_def_s; typedef struct graph_def_s graph_def_t; -graph_def_t *def_create (graph_config_t *cfg, graph_ident_t *ident); +typedef int (*def_callback_t) (graph_def_t *def, + void *user_data); + +graph_def_t *def_create (graph_config_t *cfg, graph_ident_t *ident, + const char *ds_name); void def_destroy (graph_def_t *def); int def_append (graph_def_t *head, graph_def_t *def); -graph_def_t *def_search (graph_def_t *head, graph_ident_t *ident); +graph_def_t *def_search (graph_def_t *head, graph_ident_t *ident, + const char *ds_name); + +_Bool def_matches (graph_def_t *def, graph_ident_t *ident); + +int def_foreach (graph_def_t *def, def_callback_t callback, void *user_data); int def_get_rrdargs (graph_def_t *def, graph_ident_t *ident, str_array_t *args); diff --git a/graph_list.c b/graph_list.c index 80fab28..e203df4 100644 --- a/graph_list.c +++ b/graph_list.c @@ -61,6 +61,13 @@ struct graph_config_s /* {{{ */ graph_config_t *next; }; /* }}} struct graph_config_s */ +struct def_callback_data_s +{ + graph_instance_t *inst; + str_array_t *args; +}; +typedef struct def_callback_data_s def_callback_data_t; + /* * Global variables */ @@ -532,77 +539,113 @@ static const char *get_part_from_param (const char *prim_key, /* {{{ */ return (param (sec_key)); } /* }}} const char *get_part_from_param */ -int gl_ident_get_rrdargs (graph_config_t *cfg, /* {{{ */ - graph_instance_t *inst, - graph_ident_t *ident, - str_array_t *args) +/* Create one DEF for each data source in the file. Called by + * "gl_inst_get_default_defs" for each file. */ +static graph_def_t *gl_ident_get_default_defs (graph_config_t *cfg, /* {{{ */ + graph_ident_t *ident, graph_def_t *def_head) { + graph_def_t *defs = NULL; char *file; char **dses = NULL; size_t dses_num = 0; int status; size_t i; - if ((cfg == NULL) || (inst == NULL) || (ident == NULL) || (args == NULL)) - return (EINVAL); + if ((cfg == NULL) || (ident == NULL)) + return (def_head); file = ident_to_file (ident); if (file == NULL) { - DEBUG ("gl_ident_get_rrdargs: ident_to_file returned NULL.\n"); - return (-1); + DEBUG ("gl_ident_get_default_defs: ident_to_file returned NULL.\n"); + return (def_head); } - DEBUG ("gl_ident_get_rrdargs: file = %s;\n", file); + DEBUG ("gl_ident_get_default_defs: file = %s;\n", file); status = ds_list_from_rrd_file (file, &dses_num, &dses); if (status != 0) { free (file); - return (status); + return (def_head); } for (i = 0; i < dses_num; i++) { - int index; - - DEBUG ("gl_ident_get_rrdargs: ds[%lu] = %s;\n", (unsigned long) i, dses[i]); - - index = array_argc (args); - - /* CDEFs */ - array_append_format (args, "DEF:def_%04i_min=%s:%s:MIN", - index, file, dses[i]); - array_append_format (args, "DEF:def_%04i_avg=%s:%s:AVERAGE", - index, file, dses[i]); - array_append_format (args, "DEF:def_%04i_max=%s:%s:MAX", - index, file, dses[i]); - /* VDEFs */ - array_append_format (args, "VDEF:vdef_%04i_min=def_%04i_min,MINIMUM", - index, index); - array_append_format (args, "VDEF:vdef_%04i_avg=def_%04i_avg,AVERAGE", - index, index); - array_append_format (args, "VDEF:vdef_%04i_max=def_%04i_max,MAXIMUM", - index, index); - array_append_format (args, "VDEF:vdef_%04i_lst=def_%04i_avg,LAST", - index, index); - - /* Graph part */ - array_append_format (args, "LINE1:def_%04i_avg#%06"PRIx32":%s", - index, get_random_color (), dses[i]); - array_append_format (args, "GPRINT:vdef_%04i_min:%%lg min,", index); - array_append_format (args, "GPRINT:vdef_%04i_avg:%%lg avg,", index); - array_append_format (args, "GPRINT:vdef_%04i_max:%%lg max,", index); - array_append_format (args, "GPRINT:vdef_%04i_lst:%%lg last\\l", index); + graph_def_t *def; + + def = def_search (def_head, ident, dses[i]); + if (def != NULL) + continue; + + def = def_create (cfg, ident, dses[i]); + if (def == NULL) + continue; + + if (defs == NULL) + defs = def; + else + def_append (defs, def); free (dses[i]); } - free (dses); + free (dses); free (file); + return (defs); +} /* }}} int gl_ident_get_default_defs */ + +/* Create one or more DEFs for each file in the graph instance. The number + * depends on the number of data sources in each of the files. Called from + * "gl_instance_get_rrdargs" if no DEFs are available from the configuration. + * */ +static graph_def_t *gl_inst_get_default_defs (graph_config_t *cfg, /* {{{ */ + graph_instance_t *inst) +{ + graph_def_t *defs = NULL; + size_t i; + + if ((cfg == NULL) || (inst == NULL)) + return (NULL); + + for (i = 0; i < inst->files_num; i++) + { + graph_def_t *def; + + def = gl_ident_get_default_defs (cfg, inst->files[i], defs); + if (def == NULL) + continue; + + if (defs == NULL) + defs = def; + else + def_append (defs, def); + } + + return (defs); +} /* }}} graph_def_t *gl_inst_get_default_defs */ + +/* Called with each DEF in turn. Calls "def_get_rrdargs" with every appropriate + * file / DEF pair. */ +static int gl_instance_get_rrdargs_cb (graph_def_t *def, void *user_data) /* {{{ */ +{ + def_callback_data_t *data = user_data; + graph_instance_t *inst = data->inst; + str_array_t *args = data->args; + + size_t i; + + for (i = 0; i < inst->files_num; i++) + { + if (!def_matches (def, inst->files[i])) + continue; + + def_get_rrdargs (def, inst->files[i], args); + } + return (0); -} /* }}} int gl_ident_get_rrdargs */ +} /* }}} int gl_instance_get_rrdargs_cb */ /* * Global functions @@ -830,7 +873,9 @@ int gl_instance_get_rrdargs (graph_config_t *cfg, /* {{{ */ graph_instance_t *inst, str_array_t *args) { - size_t i; + def_callback_data_t data = { inst, args }; + graph_def_t *default_defs; + int status; if ((cfg == NULL) || (inst == NULL) || (args == NULL)) return (EINVAL); @@ -841,30 +886,24 @@ int gl_instance_get_rrdargs (graph_config_t *cfg, /* {{{ */ array_append (args, cfg->title); } - for (i = 0; i < inst->files_num; i++) + if (cfg->defs == NULL) { - graph_def_t *def; - int status; + default_defs = gl_inst_get_default_defs (cfg, inst); - def = def_search (cfg->defs, inst->files[i]); - if (def == NULL) - { - def = def_create (cfg, inst->files[i]); - if (def == NULL) - return (-1); - - if (cfg->defs == NULL) - cfg->defs = def; - else - def_append (cfg->defs, def); - } + if (default_defs == NULL) + return (-1); - status = def_get_rrdargs (def, inst->files[i], args); - if (status != 0) - return (status); + status = def_foreach (default_defs, gl_instance_get_rrdargs_cb, &data); + + if (default_defs != NULL) + def_destroy (default_defs); + } + else + { + status = def_foreach (cfg->defs, gl_instance_get_rrdargs_cb, &data); } - return (0); + return (status); } /* }}} int gl_instance_get_rrdargs */ graph_ident_t *gl_instance_get_selector (graph_instance_t *inst) /* {{{ */ -- 2.11.0