summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartyn Russell <martyn@lanedo.com>2014-02-21 07:16:01 (GMT)
committerMartyn Russell <martyn@lanedo.com>2014-02-21 07:16:01 (GMT)
commit4e9e66c5ffa877b75623ecde14bbb7462af52460 (patch)
tree69994e5a1db272d0a25d746f8303d7b980e5f363
parent53601307dd8ed9b1927bfcaf983f4272c391ce82 (diff)
downloadtracker-4e9e66c5ffa877b75623ecde14bbb7462af52460.tar.gz
tracker-4e9e66c5ffa877b75623ecde14bbb7462af52460.tar.xz
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
-rw-r--r--src/tracker-utils/tracker-sparql.c319
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);