core/filter: Call GHashTable functions directly

Implements #43: Filter code can use a GHashTable directly
Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2016-04-29 10:35:32 -04:00 committed by Anna Schumaker
parent 63b46b6161
commit fda3f761a0
6 changed files with 63 additions and 65 deletions

View File

@ -7,24 +7,24 @@
static GHashTable *filter_index = NULL; static GHashTable *filter_index = NULL;
void __filter_copy(const struct set *lhs, struct set *rhs) void __filter_copy(GHashTable *lhs, GHashTable *rhs)
{ {
GHashTableIter iter; GHashTableIter iter;
gpointer data; gpointer data;
g_hash_table_iter_init(&iter, lhs->s_set); g_hash_table_iter_init(&iter, lhs);
while (g_hash_table_iter_next(&iter, &data, NULL)) while (g_hash_table_iter_next(&iter, &data, NULL))
set_insert(rhs, GPOINTER_TO_UINT(data)); g_hash_table_add(rhs, data);
} }
void __filter_inline_intersect(const struct set *lhs, struct set *rhs) void __filter_inline_intersect(GHashTable *lhs, GHashTable *rhs)
{ {
GHashTableIter iter; GHashTableIter iter;
gpointer data; gpointer data;
g_hash_table_iter_init(&iter, rhs->s_set); g_hash_table_iter_init(&iter, rhs);
while (g_hash_table_iter_next(&iter, &data, NULL)) { while (g_hash_table_iter_next(&iter, &data, NULL)) {
if (!set_has(lhs, GPOINTER_TO_UINT(data))) if (!g_hash_table_contains(lhs, data))
g_hash_table_iter_remove(&iter); g_hash_table_iter_remove(&iter);
} }
} }
@ -32,8 +32,8 @@ void __filter_inline_intersect(const struct set *lhs, struct set *rhs)
void filter_init() void filter_init()
{ {
filter_index = g_hash_table_new_full(g_str_hash, g_str_equal, filter_index = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
g_free, set_free); (GDestroyNotify)g_hash_table_destroy);
} }
void filter_deinit() void filter_deinit()
@ -45,7 +45,7 @@ void filter_add(const gchar *text, void *data)
{ {
const gchar *c = g_utf8_next_char(text); const gchar *c = g_utf8_next_char(text);
glong begin, end; glong begin, end;
struct set *set; GHashTable *set;
gchar *substr; gchar *substr;
for (begin = 0, end = 1; end <= g_utf8_strlen(text, -1); end++) { for (begin = 0, end = 1; end <= g_utf8_strlen(text, -1); end++) {
@ -53,11 +53,11 @@ void filter_add(const gchar *text, void *data)
set = g_hash_table_lookup(filter_index, substr); set = g_hash_table_lookup(filter_index, substr);
if (!set) { if (!set) {
set = set_alloc(); set = g_hash_table_new(g_direct_hash, g_direct_equal);
g_hash_table_insert(filter_index, substr, set); g_hash_table_insert(filter_index, substr, set);
} }
set_insert(set, GPOINTER_TO_UINT(data)); g_hash_table_add(set, data);
if (g_unichar_isspace(g_utf8_get_char(c))) { if (g_unichar_isspace(g_utf8_get_char(c))) {
c = g_utf8_next_char(c); c = g_utf8_next_char(c);
@ -72,7 +72,7 @@ void filter_remove(const gchar *text, void *data)
{ {
const gchar *c = g_utf8_next_char(text); const gchar *c = g_utf8_next_char(text);
glong begin, end; glong begin, end;
struct set *set; GHashTable *set;
gchar *substr; gchar *substr;
for (begin = 0, end = 1; end <= g_utf8_strlen(text, -1); end++) { for (begin = 0, end = 1; end <= g_utf8_strlen(text, -1); end++) {
@ -80,7 +80,7 @@ void filter_remove(const gchar *text, void *data)
set = g_hash_table_lookup(filter_index, substr); set = g_hash_table_lookup(filter_index, substr);
if (set) if (set)
set_remove(set, GPOINTER_TO_UINT(data)); g_hash_table_remove(set, data);
if (g_unichar_isspace(g_utf8_get_char(c))) { if (g_unichar_isspace(g_utf8_get_char(c))) {
c = g_utf8_next_char(c); c = g_utf8_next_char(c);
@ -91,14 +91,14 @@ void filter_remove(const gchar *text, void *data)
} }
} }
void filter_search(const gchar *text, struct set *res) void filter_search(const gchar *text, GHashTable *res)
{ {
gchar *lower = string_lowercase(text); gchar *lower = string_lowercase(text);
struct set *found; GHashTable *found;
glong begin, end; glong begin, end;
gchar *c, *substr; gchar *c, *substr;
set_clear(res); g_hash_table_remove_all(res);
c = lower; c = lower;
for (begin = 0, end = 1; end <= g_utf8_strlen(lower, -1); end++) { for (begin = 0, end = 1; end <= g_utf8_strlen(lower, -1); end++) {
@ -111,7 +111,7 @@ void filter_search(const gchar *text, struct set *res)
g_free(substr); g_free(substr);
if (!found) { if (!found) {
set_clear(res); g_hash_table_remove_all(res);
break; break;
} }

View File

@ -70,7 +70,7 @@ static gboolean __queue_visible_func(GtkTreeModel *model, GtkTreeIter *iter,
return TRUE; return TRUE;
track = gui_queue_model_iter_get_track(gq_queue->gq_model, iter); track = gui_queue_model_iter_get_track(gq_queue->gq_model, iter);
return set_has(&gq_queue->gq_visible, GPOINTER_TO_UINT(track)); return g_hash_table_contains(gq_queue->gq_visible, track);
} }
void __queue_filter(GtkSearchEntry *entry, gpointer data) void __queue_filter(GtkSearchEntry *entry, gpointer data)
@ -80,7 +80,7 @@ void __queue_filter(GtkSearchEntry *entry, gpointer data)
if (!gq_queue) if (!gq_queue)
return; return;
if (strlen(text) > 0) if (strlen(text) > 0)
filter_search(text, &gq_queue->gq_visible); filter_search(text, gq_queue->gq_visible);
gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(gq_queue->gq_filter)); gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(gq_queue->gq_filter));
gui_view_scroll(); gui_view_scroll();
} }
@ -97,7 +97,7 @@ struct gui_queue *gui_queue_alloc(struct queue *queue, const gchar *text,
GTK_TREE_MODEL(gq->gq_model), NULL); GTK_TREE_MODEL(gq->gq_model), NULL);
gq->gq_queue = queue; gq->gq_queue = queue;
set_init(&gq->gq_visible); gq->gq_visible = g_hash_table_new(g_direct_hash, g_direct_equal);
gtk_tree_model_filter_set_visible_func( gtk_tree_model_filter_set_visible_func(
GTK_TREE_MODEL_FILTER(gq->gq_filter), GTK_TREE_MODEL_FILTER(gq->gq_filter),
__queue_visible_func, __queue_visible_func,
@ -110,7 +110,7 @@ void gui_queue_free(struct queue *queue)
{ {
struct gui_queue *gq = gui_queue(queue); struct gui_queue *gq = gui_queue(queue);
set_deinit(&gq->gq_visible); g_hash_table_destroy(gq->gq_visible);
queue->q_private = NULL; queue->q_private = NULL;
if (gq_queue == gq) if (gq_queue == gq)

View File

@ -6,8 +6,7 @@
*/ */
#ifndef OCARINA_CORE_FILTER_H #ifndef OCARINA_CORE_FILTER_H
#define OCARINA_CORE_FILTER_H #define OCARINA_CORE_FILTER_H
#include <glib.h>
#include <core/containers/set.h>
/* Called to initialize the filter index. */ /* Called to initialize the filter index. */
void filter_init(); void filter_init();
@ -22,6 +21,6 @@ void filter_add(const gchar *, void *);
void filter_remove(const gchar *, void *); void filter_remove(const gchar *, void *);
/* Search for the input string in the index. */ /* Search for the input string in the index. */
void filter_search(const gchar *, struct set *); void filter_search(const gchar *, GHashTable *);
#endif /* OCARINA_CORE_FILTER_H */ #endif /* OCARINA_CORE_FILTER_H */

View File

@ -4,7 +4,6 @@
#ifndef OCARINA_GUI_QUEUE_H #ifndef OCARINA_GUI_QUEUE_H
#define OCARINA_GUI_QUEUE_H #define OCARINA_GUI_QUEUE_H
#include <core/containers/set.h>
#include <core/queue.h> #include <core/queue.h>
#include <gui/model.h> #include <gui/model.h>
@ -21,7 +20,7 @@ struct gui_queue {
GuiQueueModel *gq_model; GuiQueueModel *gq_model;
GtkTreeModel *gq_filter; GtkTreeModel *gq_filter;
struct queue *gq_queue; struct queue *gq_queue;
struct set gq_visible; GHashTable *gq_visible;
}; };

View File

@ -25,7 +25,7 @@ const gchar *test_strings[] = {
static void test_filter() static void test_filter()
{ {
struct set res = SET_INIT(); GHashTable *res = g_hash_table_new(g_direct_hash, g_direct_equal);
unsigned int i; unsigned int i;
filter_init(); filter_init();
@ -34,46 +34,46 @@ static void test_filter()
} test_loop_passed(); } test_loop_passed();
/* Search for a word! */ /* Search for a word! */
filter_search("hyrule", &res); filter_search("hyrule", res);
test_equal(set_size(&res), 3); test_equal(g_hash_table_size(res), 3);
test_equal(set_has(&res, 1), (bool)true); /* hyrule symphony */ test_equal(g_hash_table_contains(res, GUINT_TO_POINTER(1)), true); /* hyrule symphony */
test_equal(set_has(&res, 3), (bool)true); /* hyrule field */ test_equal(g_hash_table_contains(res, GUINT_TO_POINTER(3)), true); /* hyrule field */
test_equal(set_has(&res, 4), (bool)true); /* hyrule castle */ test_equal(g_hash_table_contains(res, GUINT_TO_POINTER(4)), true); /* hyrule castle */
/* A second search should clear the set. */ /* A second search should clear the set. */
filter_search("zelda", &res); filter_search("zelda", res);
test_equal(set_size(&res), 2); test_equal(g_hash_table_size(res), 2);
test_equal(set_has(&res, 11), (bool)true); /* princess zelda */ test_equal(g_hash_table_contains(res, GUINT_TO_POINTER(11)), true); /* princess zelda */
test_equal(set_has(&res, 13), (bool)true); /* the legend of zelda medley */ test_equal(g_hash_table_contains(res, GUINT_TO_POINTER(13)), true); /* the legend of zelda medley */
/* Partial word search. */ /* Partial word search. */
filter_search("ko", &res); filter_search("ko", res);
test_equal(set_size(&res), 2); test_equal(g_hash_table_size(res), 2);
test_equal(set_has(&res, 0), (bool)true); /* koji kondo */ test_equal(g_hash_table_contains(res, GUINT_TO_POINTER(0)), true); /* koji kondo */
test_equal(set_has(&res, 2), (bool)true); /* kokiri forest */ test_equal(g_hash_table_contains(res, GUINT_TO_POINTER(2)), true); /* kokiri forest */
/* Multiple word search. */ /* Multiple word search. */
filter_search("hyrule field", &res); filter_search("hyrule field", res);
test_equal(set_size(&res), 1); test_equal(g_hash_table_size(res), 1);
test_equal(set_has(&res, 3), (bool)true); /* hyrule field */ test_equal(g_hash_table_contains(res, GUINT_TO_POINTER(3)), true); /* hyrule field */
/* Search for unknown word. */ /* Search for unknown word. */
filter_search("field termina", &res); filter_search("field termina", res);
test_equal(set_size(&res), 0); test_equal(g_hash_table_size(res), 0);
/* Search for empty string. */ /* Search for empty string. */
filter_search("", &res); filter_search("", res);
test_equal(set_size(&res), 0); test_equal(g_hash_table_size(res), 0);
/* Remove a string and search again. */ /* Remove a string and search again. */
filter_remove("hyrule symphony", GUINT_TO_POINTER(1)); filter_remove("hyrule symphony", GUINT_TO_POINTER(1));
filter_search("hyrule", &res); filter_search("hyrule", res);
test_equal(set_size(&res), 2); test_equal(g_hash_table_size(res), 2);
test_equal(set_has(&res, 3), (bool)true); /* hyrule field */ test_equal(g_hash_table_contains(res, GUINT_TO_POINTER(3)), true); /* hyrule field */
test_equal(set_has(&res, 4), (bool)true); /* hyrule castle */ test_equal(g_hash_table_contains(res, GUINT_TO_POINTER(4)), true); /* hyrule castle */
filter_deinit(); filter_deinit();
set_deinit(&res); g_hash_table_destroy(res);
} }
DECLARE_UNIT_TESTS( DECLARE_UNIT_TESTS(

View File

@ -126,29 +126,29 @@ static void test_track()
static void test_track_filter() static void test_track_filter()
{ {
const struct db_ops *track_ops = test_track_ops(); const struct db_ops *track_ops = test_track_ops();
struct set search = SET_INIT(); GHashTable *search = g_hash_table_new(g_direct_hash, g_direct_equal);
struct track *track; struct track *track;
track = test_alloc("0/Hyrule Symphony/01 - Title Theme.ogg"); track = test_alloc("0/Hyrule Symphony/01 - Title Theme.ogg");
track->tr_dbe.dbe_index = 0; track->tr_dbe.dbe_index = 0;
track_ops->dbe_setup(&track->tr_dbe); track_ops->dbe_setup(&track->tr_dbe);
filter_search("Title Theme", &search); filter_search("Title Theme", search);
test_equal(set_size(&search), 1); test_equal(g_hash_table_size(search), 1);
test_equal(set_has(&search, GPOINTER_TO_UINT(track)), (bool)true); test_equal(g_hash_table_contains(search, track), true);
filter_search("Koji Kondo", &search); filter_search("Koji Kondo", search);
test_equal(set_size(&search), 1); test_equal(g_hash_table_size(search), 1);
test_equal(set_has(&search, GPOINTER_TO_UINT(track)), (bool)true); test_equal(g_hash_table_contains(search, track), true);
filter_search("Hyrule Symphony", &search); filter_search("Hyrule Symphony", search);
test_equal(set_size(&search), 1); test_equal(g_hash_table_size(search), 1);
test_equal(set_has(&search, GPOINTER_TO_UINT(track)), (bool)true); test_equal(g_hash_table_contains(search, track), true);
filter_search("No Track", &search); filter_search("No Track", search);
test_equal(set_size(&search), 0); test_equal(g_hash_table_size(search), 0);
set_deinit(&search); g_hash_table_destroy(search);
g_free(track->tr_path); g_free(track->tr_path);
track_ops->dbe_free(&track->tr_dbe); track_ops->dbe_free(&track->tr_dbe);
} }