graph: cleanup tooltip alias handling
[fio.git] / graph.c
diff --git a/graph.c b/graph.c
index 7304b009646c5288b3f7f92bc73989e3bd90fb16..2f00dab4361d4280f48da66c9a84102ee173b82b 100644 (file)
--- a/graph.c
+++ b/graph.c
@@ -688,32 +688,37 @@ static void graph_label_add_value(struct graph_label *i, void *value,
        struct graph_value *x;
 
        x = malloc(sizeof(*x));
+       memset(x, 0, sizeof(*x));
        x->value = value;
-       if (tooltip)
-               x->tooltip = strdup(tooltip);
-       else
-               x->tooltip = NULL;
        x->next = NULL;
-       if (!i->tail) {
+       if (!i->tail)
                i->values = x;
-       } else {
+       else
                i->tail->next = x;
-       }
        i->tail = x;
        i->value_count++;
 
-       if (x->tooltip) {
+       if (tooltip) {
                double yval = gety(x);
                double miny = yval / TOOLTIP_DELTA;
                double maxy = yval * TOOLTIP_DELTA;
+               struct prio_tree_node *ret;
 
+               INIT_PRIO_TREE_NODE(&x->node);
                x->node.start = miny;
                x->node.last = maxy;
                if (x->node.last == x->node.start)
                        x->node.last++;
 
-               prio_tree_insert(&i->prio_tree, &x->node);
-               i->tooltip_count++;
+               /*
+                * If ret != &x->node, we have an alias. Since the values
+                * should be identical, we can drop it
+                */
+               ret = prio_tree_insert(&i->prio_tree, &x->node);
+               if (ret == &x->node) {
+                       x->tooltip = strdup(tooltip);
+                       i->tooltip_count++;
+               }
        }
 
        if (i->parent->per_label_limit != -1 &&
@@ -777,13 +782,18 @@ int graph_add_xy_data(struct graph *bg, const char *label,
        return 0;
 }
 
-static void graph_free_values(struct graph_value *values)
+static void graph_free_values(struct graph_label *l, struct graph_value *values)
 {
        struct graph_value *i, *next;
 
        for (i = values; i; i = next) {
                next = i->next;
                free(i->value);
+               if (i->tooltip) {
+                       free(i->tooltip);
+                       prio_tree_remove(&l->prio_tree, &i->node);
+                       l->tooltip_count--;
+               }
                free(i);
        }       
 }
@@ -794,7 +804,7 @@ static void graph_free_labels(struct graph_label *labels)
 
        for (i = labels; i; i = next) {
                next = i->next;
-               graph_free_values(i->values);
+               graph_free_values(i, i->values);
                free(i);
        }       
 }
@@ -909,6 +919,7 @@ const char *graph_find_tooltip(struct graph *g, int ix, int iy)
        best_delta = UINT_MAX;
        i = g->labels;
        do {
+               INIT_PRIO_TREE_ITER(&iter);
                prio_tree_iter_init(&iter, &i->prio_tree, y, y);
 
                n = prio_tree_next(&iter);