[tracker] tracker-sparql: Various improvements/fixes for --tree command line option



commit 4e9e66c5ffa877b75623ecde14bbb7462af52460
Author: Martyn Russell <martyn lanedo com>
Date:   Fri Feb 21 07:16:01 2014 +0000

    tracker-sparql: Various improvements/fixes for --tree command line option
    
    Specifically:
    - Fix offset error when highlighting parts of the tree when -s is used
    - Use GNode APIs g_node_traverse() to print and find nodes, reducing code size
    - Remove unnecessary memory allocation for --get-longhand
    - Fix memory leak of longhand to shorthand conversion in --tree
    - Avoid memory allocations when generating filter hashtable

 src/tracker-utils/tracker-sparql.c |  319 +++++++++++++++++++-----------------
 1 files changed, 171 insertions(+), 148 deletions(-)
---
diff --git a/src/tracker-utils/tracker-sparql.c b/src/tracker-utils/tracker-sparql.c
index ab8f85d..fae5df9 100644
--- a/src/tracker-utils/tracker-sparql.c
+++ b/src/tracker-utils/tracker-sparql.c
@@ -43,24 +43,39 @@
 #define SNIPPET_BEGIN "\033[1;31m" /* Red */
 #define SNIPPET_END   "\033[0m"
 
-typedef struct {
+typedef struct _NodeData NodeData;
+typedef struct _NodeFindData NodeFindData;
+typedef struct _NodePrintData NodePrintData;
+
+struct _NodeData {
        gchar *class;
-       gboolean parent_known;
-} NodeData;
-
-static gboolean    parse_list_notifies (const gchar  *option_name,
-                                        const gchar  *value,
-                                        gpointer      data,
-                                        GError      **error);
-static gboolean    parse_list_indexes  (const gchar  *option_name,
-                                        const gchar  *value,
-                                        gpointer      data,
-                                        GError      **error);
-static gboolean    parse_tree          (const gchar  *option_name,
-                                        const gchar  *value,
-                                        gpointer      data,
-                                        GError      **error);
-static inline void tree_node_data_free (NodeData     *data);
+       guint parent_known:1;
+};
+
+struct _NodeFindData {
+       GEqualFunc func;
+       GNode *node;
+       const gchar *class;
+};
+
+struct _NodePrintData {
+       GHashTable *prefixes;
+       GHashTable  *filter_parents;
+       const gchar *highlight_text;
+};
+
+static gboolean parse_list_notifies (const gchar  *option_name,
+                                     const gchar  *value,
+                                     gpointer      data,
+                                     GError      **error);
+static gboolean parse_list_indexes  (const gchar  *option_name,
+                                     const gchar  *value,
+                                     gpointer      data,
+                                     GError      **error);
+static gboolean parse_tree          (const gchar  *option_name,
+                                     const gchar  *value,
+                                     gpointer      data,
+                                     GError      **error);
 
 static gchar *file;
 static gchar *query;
@@ -291,7 +306,7 @@ parse_tree (const gchar  *option_name,
 }
 
 
-inline static gchar *
+static gchar *
 get_longhand_str (GHashTable  *prefixes,
                   const gchar *shorthand)
 {
@@ -327,12 +342,10 @@ get_longhand_str (GHashTable  *prefixes,
                }
        }
 
-       g_free (namespace);
-
-       return g_strdup (shorthand);
+       return namespace;
 }
 
-inline static gchar *
+static gchar *
 get_shorthand_str (GHashTable  *prefixes,
                    const gchar *longhand)
 {
@@ -361,7 +374,7 @@ get_shorthand_str (GHashTable  *prefixes,
        return g_strdup (longhand);
 }
 
-inline static gchar *
+static gchar *
 get_shorthand_str_for_offsets (GHashTable  *prefixes,
                                const gchar *str)
 {
@@ -521,7 +534,31 @@ print_cursor (TrackerSparqlCursor *cursor,
        }
 }
 
-static inline GNode *
+static NodeData *
+tree_node_data_new (const gchar *class,
+                    gboolean     parent_known)
+{
+       NodeData *data;
+
+       data = g_slice_new0 (NodeData);
+       data->class = g_strdup (class);
+       data->parent_known = parent_known;
+
+       return data;
+}
+
+static void
+tree_node_data_free (NodeData *data)
+{
+       if (data == NULL) {
+               return;
+       }
+
+       g_free (data->class);
+       g_slice_free (NodeData, data);
+}
+
+static GNode *
 tree_new (void)
 {
        return g_node_new (NULL);
@@ -534,7 +571,7 @@ tree_free_foreach (GNode *node)
        return FALSE;
 }
 
-static inline void
+static void
 tree_free (GNode *node)
 {
        g_node_traverse (node,
@@ -546,39 +583,52 @@ tree_free (GNode *node)
        g_node_destroy (node);
 }
 
-static NodeData *
-tree_node_data_new (const gchar *class,
-                    gboolean     parent_known)
+static gboolean
+tree_node_find_foreach (GNode    *node,
+                        gpointer  user_data)
 {
-       NodeData *data;
+       NodeFindData *data;
+       NodeData *node_data;
 
-       data = g_slice_new0 (NodeData);
-       data->class = g_strdup (class);
-       data->parent_known = parent_known;
+       if (!node) {
+               return FALSE;
+       }
 
-       return data;
-}
+       node_data = node->data;
 
-static void
-tree_node_data_free (NodeData *data)
-{
-       if (!data) {
-               return;
+       if (!node_data) {
+               return FALSE;
        }
 
-       g_free (data->class);
-       g_slice_free (NodeData, data);
+       data = user_data;
+
+       if ((data->func) (data->class, node_data->class)) {
+               data->node = node;
+               return TRUE;
+       }
+
+       return FALSE;
 }
 
-static gboolean
-tree_node_data_equal (GNode       *node,
-                      const gchar *class)
+static GNode *
+tree_node_find (GNode       *node,
+                const gchar *class,
+                GEqualFunc   func)
 {
-       NodeData *data;
+       NodeFindData data;
+
+       data.class = class;
+       data.node = NULL;
+       data.func = func;
 
-       data = node->data;
+       g_node_traverse (node,
+                        G_POST_ORDER,
+                        G_TRAVERSE_ALL,
+                        -1,
+                        tree_node_find_foreach,
+                        &data);
 
-       return strcmp (class, data->class) == 0 ? TRUE : FALSE;
+       return data.node;
 }
 
 static GNode *
@@ -586,46 +636,19 @@ tree_node_lookup (GNode        *tree,
                   const gchar  *class,
                   GNode       **parent_node)
 {
-       GNode *parent, *child, *node_found, *parent_found;
+       GNode *node;
 
-       node_found = parent_found = NULL;
+       node = tree_node_find (tree, class, g_str_equal);
 
        if (parent_node) {
-               *parent_node = NULL;
-       }
-
-       if (!tree) {
-               return NULL;
-       }
-
-       parent = tree;
-
-       for (child = g_node_first_child (parent);
-            child != NULL;
-            child = g_node_next_sibling (child)) {
-               if (tree_node_data_equal (child, class)) {
-                       node_found = child;
-               } else if (!G_NODE_IS_LEAF (child)) {
-                       node_found = tree_node_lookup (child, class, parent_node);
-               }
-
-               if (node_found) {
-                       break;
+               if (node) {
+                       *parent_node = node->parent;
+               } else {
+                       *parent_node = NULL;
                }
        }
 
-       if (node_found) {
-               /* Found, exit ... */
-               parent_found = parent;
-       } else {
-               /* Descent down the child */
-       }
-
-       if (parent_node) {
-               *parent_node = parent_found;
-       }
-
-       return node_found;
+       return node;
 }
 
 static GNode *
@@ -659,7 +682,6 @@ tree_add_class (GNode       *root,
                         * and we will reorder it when we know more...
                         */
                } else {
-
                        /* Lookup parent node and add to that. */
                        parent_node = tree_node_lookup (root, parent, NULL);
 
@@ -700,7 +722,7 @@ tree_add_class (GNode       *root,
        return node;
 }
 
-static inline gchar *
+static gchar *
 highlight (const gchar *text,
            const gchar *highlight_text)
 {
@@ -730,92 +752,91 @@ highlight (const gchar *text,
 
        p += strlen (highlight_text);
        if (p[0] != '\0')
-               s = g_string_append (s, p + 1);
+               s = g_string_append (s, p);
 
        return g_string_free (s, FALSE);
 }
 
-static void
-tree_print (GNode       *tree,
-            GHashTable  *prefixes,
-            GHashTable  *filter_parents,
-            const gchar *highlight_text)
+static gboolean
+tree_print_foreach (GNode    *node,
+                    gpointer  user_data)
 {
-       GNode *parent;
-
-       if (!tree) {
-               return;
-       }
+       NodeData *nd;
+       NodePrintData *pd;
+       gboolean print = TRUE;
 
-       /* Print, depth first */
+       gchar *shorthand, *highlighted;
+       const gchar *text;
+       gint depth, i;
 
-       parent = tree;
+       nd = node->data;
+       pd = user_data;
 
-       if (!parent->data) {
-               /* Handle root */
+       if (!nd) {
                g_print ("ROOT\n");
+               return FALSE;
        }
 
-       while (parent) {
-               GNode *child, *next = NULL;
-
-               for (child = g_node_first_child (parent);
-                    child != NULL;
-                    child = g_node_next_sibling (child)) {
-                       NodeData *data;
-                       gboolean print = TRUE;
+       /* Filter based on parent classes */
+       if (pd->filter_parents) {
+               print = g_hash_table_lookup (pd->filter_parents, nd->class) != NULL;
+       }
 
-                       data = child->data;
+       if (!print) {
+               return FALSE;
+       }
 
-                       /* Filter based on parent classes */
-                       if (filter_parents && data) {
-                               print = g_hash_table_lookup (filter_parents, data->class) != NULL;
-                       }
+       shorthand = NULL;
 
-                       if (print) {
-                               gchar *shorthand, *highlighted;
-                               const gchar *text;
-                               gint depth, i;
+       if (pd->prefixes) {
+               shorthand = get_shorthand_str (pd->prefixes, nd->class);
+       }
 
-                               shorthand = NULL;
+       depth = g_node_depth (node);
 
-                               if (prefixes) {
-                                       shorthand = get_shorthand_str (prefixes, data->class);
-                               }
+       for (i = 1; i < depth; i++) {
+               if (i == depth - 1) {
+                       const gchar *branch = "+";
 
-                               depth = g_node_depth (child);
+                       if (!node->next) {
+                               branch = "`";
+                       } else if (G_NODE_IS_LEAF (node)) {
+                               branch = "|";
+                       }
 
-                               for (i = 1; i < depth; i++) {
-                                       if (i == depth - 1) {
-                                               const gchar *branch = "+";
+                       g_print ("  %s", branch);
+               } else {
+                       g_print ("  |");
+               }
+       }
 
-                                               if (!child->next) {
-                                                       branch = "`";
-                                               } else if (G_NODE_IS_LEAF (child)) {
-                                                       branch = "|";
-                                               }
+       text = shorthand ? shorthand : nd->class;
+       highlighted = highlight (text, pd->highlight_text);
+       g_print ("-- %s (C)\n", highlighted);
+       g_free (highlighted);
+       g_free (shorthand);
 
-                                               g_print ("  %s", branch);
-                                       } else {
-                                               g_print ("  |");
-                                       }
-                               }
+       return FALSE;
+}
 
-                               text = shorthand ? shorthand : data->class;
-                               highlighted = highlight (text, highlight_text);
-                               g_print ("-- %s (C)\n", highlighted);
-                               g_free (highlighted);
-                               g_free (shorthand);
-                       }
+static void
+tree_print (GNode       *node,
+            GHashTable  *prefixes,
+            GHashTable  *filter_parents,
+            const gchar *highlight_text)
+{
+       NodePrintData data;
 
-                       tree_print (child, prefixes, filter_parents, highlight_text);
-               }
+       data.prefixes = prefixes;
+       data.filter_parents = filter_parents;
+       data.highlight_text = highlight_text;
 
-               if (!next) {
-                       /* Descent down the child */
-                       parent = next;
-               }
-       }
+       g_node_traverse (node,
+                        G_PRE_ORDER,
+                        G_TRAVERSE_ALL,
+                        -1,
+                        tree_print_foreach,
+                        &data);
 }
 
 static gint
@@ -869,7 +890,7 @@ tree_get (TrackerSparqlConnection *connection,
                found_node = tree_node_lookup (root, class_lookup_longhand, NULL);
                filter_parents = g_hash_table_new_full (g_str_hash,
                                                        g_str_equal,
-                                                       g_free,
+                                                       NULL,
                                                        NULL);
 
                for (node = found_node; node; node = node->parent) {
@@ -880,13 +901,15 @@ tree_get (TrackerSparqlConnection *connection,
                        }
 
                        g_hash_table_insert (filter_parents,
-                                            g_strdup (data->class),
+                                            data->class,
                                             GINT_TO_POINTER(1));
                }
        } else {
                filter_parents = NULL;
        }
 
+       g_free (class_lookup_longhand);
+
        /* Print */
        tree_print (root, prefixes, filter_parents, highlight_text);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]