graph: return opaque graph_label_t for each label added

Gets rid of the strcmp() lookup, store the graph label locally
instead and just pass that in.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/gclient.c b/gclient.c
index e2fbfac..5e333d4 100644
--- a/gclient.c
+++ b/gclient.c
@@ -400,10 +400,10 @@
 		gtk_entry_set_text(GTK_ENTRY(ge->eta.write_bw), rate_str[1]);
 		gtk_entry_set_text(GTK_ENTRY(ge->eta.write_iops), iops_str[1]);
 
-		graph_add_xy_data(ge->graphs.iops_graph, "Read IOPS", je->elapsed_sec, je->iops[0], iops_str[0]);
-		graph_add_xy_data(ge->graphs.iops_graph, "Write IOPS", je->elapsed_sec, je->iops[1], iops_str[1]);
-		graph_add_xy_data(ge->graphs.bandwidth_graph, "Read Bandwidth", je->elapsed_sec, je->rate[0], rate_str[0]);
-		graph_add_xy_data(ge->graphs.bandwidth_graph, "Write Bandwidth", je->elapsed_sec, je->rate[1], rate_str[1]);
+		graph_add_xy_data(ge->graphs.iops_graph, ge->graphs.read_iops, je->elapsed_sec, je->iops[0], iops_str[0]);
+		graph_add_xy_data(ge->graphs.iops_graph, ge->graphs.write_iops, je->elapsed_sec, je->iops[1], iops_str[1]);
+		graph_add_xy_data(ge->graphs.bandwidth_graph, ge->graphs.read_bw, je->elapsed_sec, je->rate[0], rate_str[0]);
+		graph_add_xy_data(ge->graphs.bandwidth_graph, ge->graphs.write_bw, je->elapsed_sec, je->rate[1], rate_str[1]);
 
 		free(rate_str[0]);
 		free(rate_str[1]);
@@ -488,10 +488,10 @@
 		gtk_entry_set_text(GTK_ENTRY(ui->eta.write_bw), rate_str[1]);
 		gtk_entry_set_text(GTK_ENTRY(ui->eta.write_iops), iops_str[1]);
 
-		graph_add_xy_data(ui->graphs.iops_graph, "Read IOPS", je->elapsed_sec, je->iops[0], iops_str[0]);
-		graph_add_xy_data(ui->graphs.iops_graph, "Write IOPS", je->elapsed_sec, je->iops[1], iops_str[1]);
-		graph_add_xy_data(ui->graphs.bandwidth_graph, "Read Bandwidth", je->elapsed_sec, je->rate[0], rate_str[0]);
-		graph_add_xy_data(ui->graphs.bandwidth_graph, "Write Bandwidth", je->elapsed_sec, je->rate[1], rate_str[1]);
+		graph_add_xy_data(ui->graphs.iops_graph, ui->graphs.read_iops, je->elapsed_sec, je->iops[0], iops_str[0]);
+		graph_add_xy_data(ui->graphs.iops_graph, ui->graphs.write_iops, je->elapsed_sec, je->iops[1], iops_str[1]);
+		graph_add_xy_data(ui->graphs.bandwidth_graph, ui->graphs.read_bw, je->elapsed_sec, je->rate[0], rate_str[0]);
+		graph_add_xy_data(ui->graphs.bandwidth_graph, ui->graphs.write_bw, je->elapsed_sec, je->rate[1], rate_str[1]);
 
 		free(rate_str[0]);
 		free(rate_str[1]);
@@ -865,8 +865,10 @@
 	graph_y_title(g, "Percent");
 
 	for (i = 0; i < len; i++) {
-		graph_add_label(g, labels[i]);
-		graph_add_data(g, labels[i], lat[i]);
+		graph_label_t l;
+
+		l = graph_add_label(g, labels[i]);
+		graph_add_data(g, l, lat[i]);
 	}
 
 	return g;
@@ -1053,11 +1055,12 @@
 	graph_y_title(g, "Time");
 
 	for (i = 0; i < len; i++) {
+		graph_label_t l;
 		char fbuf[8];
 
 		sprintf(fbuf, "%2.2f%%", plist[i].u.f);
-		graph_add_label(g, fbuf);
-		graph_add_data(g, fbuf, (double) ovals[i]);
+		l = graph_add_label(g, fbuf);
+		graph_add_data(g, l, (double) ovals[i]);
 	}
 
 	return g;
diff --git a/gfio.c b/gfio.c
index 3a0aa8f..8fd5739 100644
--- a/gfio.c
+++ b/gfio.c
@@ -75,45 +75,45 @@
 	},
 };
 
-static struct graph *setup_iops_graph(void)
+static void setup_iops_graph(struct gfio_graphs *gg)
 {
 	struct graph *g;
 
 	g = graph_new(DRAWING_AREA_XDIM / 2.0, DRAWING_AREA_YDIM, gfio_graph_font);
 	graph_title(g, "IOPS (IOs/sec)");
 	graph_x_title(g, "Time (secs)");
-	graph_add_label(g, "Read IOPS");
-	graph_add_label(g, "Write IOPS");
-	graph_set_color(g, "Read IOPS", 0.13, 0.54, 0.13);
-	graph_set_color(g, "Write IOPS", 1.0, 0.0, 0.0);
+	gg->read_iops = graph_add_label(g, "Read IOPS");
+	gg->write_iops = graph_add_label(g, "Write IOPS");
+	graph_set_color(g, gg->read_iops, 0.13, 0.54, 0.13);
+	graph_set_color(g, gg->write_iops, 1.0, 0.0, 0.0);
 	line_graph_set_data_count_limit(g, gfio_graph_limit);
 	graph_add_extra_space(g, 0.0, 0.0, 0.0, 0.0);
 	graph_set_graph_all_zeroes(g, 0);
-	return g;
+	gg->bandwidth_graph = g;
 }
 
-static struct graph *setup_bandwidth_graph(void)
+static void setup_bandwidth_graph(struct gfio_graphs *gg)
 {
 	struct graph *g;
 
 	g = graph_new(DRAWING_AREA_XDIM / 2.0, DRAWING_AREA_YDIM, gfio_graph_font);
 	graph_title(g, "Bandwidth (bytes/sec)");
 	graph_x_title(g, "Time (secs)");
-	graph_add_label(g, "Read Bandwidth");
-	graph_add_label(g, "Write Bandwidth");
-	graph_set_color(g, "Read Bandwidth", 0.13, 0.54, 0.13);
-	graph_set_color(g, "Write Bandwidth", 1.0, 0.0, 0.0);
+	gg->read_bw = graph_add_label(g, "Read Bandwidth");
+	gg->write_bw = graph_add_label(g, "Write Bandwidth");
+	graph_set_color(g, gg->read_bw, 0.13, 0.54, 0.13);
+	graph_set_color(g, gg->write_bw, 1.0, 0.0, 0.0);
 	graph_set_base_offset(g, 1);
 	line_graph_set_data_count_limit(g, 100);
 	graph_add_extra_space(g, 0.0, 0.0, 0.0, 0.0);
 	graph_set_graph_all_zeroes(g, 0);
-	return g;
+	gg->iops_graph = g;
 }
 
 static void setup_graphs(struct gfio_graphs *g)
 {
-	g->iops_graph = setup_iops_graph();
-	g->bandwidth_graph = setup_bandwidth_graph();
+	setup_iops_graph(g);
+	setup_bandwidth_graph(g);
 }
 
 void clear_ge_ui_info(struct gui_entry *ge)
diff --git a/gfio.h b/gfio.h
index 71b2db7..b8de680 100644
--- a/gfio.h
+++ b/gfio.h
@@ -6,6 +6,7 @@
 #include "stat.h"
 #include "thread_options.h"
 #include "ghelpers.h"
+#include "graph.h"
 
 struct probe_widget {
 	GtkWidget *hostname;
@@ -37,7 +38,11 @@
 #define DRAWING_AREA_YDIM 400
 	GtkWidget *drawing_area;
 	struct graph *iops_graph;
+	graph_label_t read_iops;
+	graph_label_t write_iops;
 	struct graph *bandwidth_graph;
+	graph_label_t read_bw;
+	graph_label_t write_bw;
 };
 
 /*
diff --git a/graph.c b/graph.c
index c543171..841bab6 100644
--- a/graph.c
+++ b/graph.c
@@ -45,6 +45,7 @@
 
 enum {
 	GV_F_ON_PRIO	= 1,
+	GV_F_PRIO_SKIP	= 2,
 };
 
 struct graph_value {
@@ -703,19 +704,20 @@
 	return NULL;
 }
 
-void graph_add_label(struct graph *bg, const char *label)
+graph_label_t graph_add_label(struct graph *bg, const char *label)
 {
 	struct graph_label *i;
 	
 	i = graph_find_label(bg, label);
 	if (i)
-		return; /* already present. */
+		return i; /* already present. */
 	i = calloc(1, sizeof(*i));
 	INIT_FLIST_HEAD(&i->value_list);
 	i->parent = bg;
 	setstring(&i->label, label);
 	flist_add_tail(&i->list, &bg->label_list);
 	INIT_PRIO_TREE_ROOT(&i->prio_tree);
+	return i;
 }
 
 static void __graph_value_drop(struct graph_label *l, struct graph_value *v)
@@ -730,6 +732,11 @@
 
 static void graph_value_drop(struct graph_label *l, struct graph_value *v)
 {
+	if (v->flags & GV_F_PRIO_SKIP) {
+		__graph_value_drop(l, v);
+		return;
+	}
+
 	/*
 	 * Find head, the guy that's on the prio tree
 	 */
@@ -804,7 +811,8 @@
 			flist_add_tail(&x->alias, &alias->alias);
 		} else
 			x->flags = GV_F_ON_PRIO;
-	}
+	} else
+		x->flags = GV_F_PRIO_SKIP;
 
 	if (g->per_label_limit != -1 &&
 		i->value_count > g->per_label_limit) {
@@ -832,17 +840,14 @@
 	}
 }
 
-int graph_add_data(struct graph *bg, const char *label, const double value)
+int graph_add_data(struct graph *bg, graph_label_t label, const double value)
 {
-	struct graph_label *i;
+	struct graph_label *i = label;
 	double *d;
 
 	d = malloc(sizeof(*d));
 	*d = value;
 
-	i = graph_find_label(bg, label);
-	if (!i)
-		return -1;
 	graph_label_add_value(i, d, NULL);
 	return 0;
 }
@@ -862,16 +867,12 @@
 	return 0;
 }
 
-int graph_add_xy_data(struct graph *bg, const char *label,
+int graph_add_xy_data(struct graph *bg, graph_label_t label,
 		      const double x, const double y, const char *tooltip)
 {
-	struct graph_label *i;
+	struct graph_label *i = label;
 	struct xyvalue *xy;
 
-	i = graph_find_label(bg, label);
-	if (!i)
-		return -1;
-
 	if (bg->dont_graph_all_zeroes && y == 0.0 && !graph_nonzero_y(i))
 		i->hide = 1;
 	else
@@ -907,11 +908,10 @@
 	}	
 }
 
-void graph_set_color(struct graph *gr, const char *label,
-	double red, double green, double blue)
+void graph_set_color(struct graph *gr, graph_label_t label, double red,
+		     double green, double blue)
 {
-	struct flist_head *entry;
-	struct graph_label *i;
+	struct graph_label *i = label;
 	double r, g, b;
 
 	if (red < 0.0) { /* invisible color */
@@ -931,16 +931,9 @@
 			b = 1.0;
 	}
 
-	flist_for_each(entry, &gr->label_list) {
-		i = flist_entry(entry, struct graph_label, list);
-
-		if (strcmp(i->label, label) == 0) {
-			i->r = r;	
-			i->g = g;	
-			i->b = b;	
-			break;
-		}
-	}
+	i->r = r;
+	i->g = g;
+	i->b = b;
 }
 
 void graph_free(struct graph *bg)
diff --git a/graph.h b/graph.h
index 2315045..e7d879d 100644
--- a/graph.h
+++ b/graph.h
@@ -2,7 +2,9 @@
 #define GRAPH_H
 
 struct graph;
+struct graph_label;
 
+typedef struct graph_label * graph_label_t;
 
 struct graph *graph_new(unsigned int xdim, unsigned int ydim, const char *font);
 /* graph_new() Returns a new graph structure of the given dimensions and font */
@@ -25,7 +27,7 @@
 /* graph_x_title() sets the title of the x axis to the given string */
 void graph_y_title(struct graph *g, const char *title);
 /* graph_y_title() sets the title of the y axis to the given string */
-void graph_add_label(struct graph *g, const char *label);
+graph_label_t graph_add_label(struct graph *g, const char *label);
 /* graph_add_label() adds a new "stream" of data to be graphed.
  * For line charts, each label is a separate line on the graph.
  * For bar charts, each label is a grouping of columns on the x-axis
@@ -47,13 +49,13 @@
  * label.
  */
 
-int graph_add_data(struct graph *g, const char *label, const double value);
+int graph_add_data(struct graph *g, graph_label_t label, const double value);
 /* graph_add_data() is used to add data to the labels of a bar graph */
-int graph_add_xy_data(struct graph *g, const char *label,
+int graph_add_xy_data(struct graph *g, graph_label_t label,
 		const double x, const double y, const char *tooltip);
 /* graph_add_xy_data is used to add data to the labels of a line graph */
 
-void graph_set_color(struct graph *g, const char *label,
+void graph_set_color(struct graph *g, graph_label_t label,
 		double red, double green, double blue);
 #define INVISIBLE_COLOR (-1.0)
 /* graph_set_color is used to set the color used to plot the data in