/* * Copyright 2013 (c) Anna Schumaker. */ #include #include static GHashTable *filter_index = NULL; void filter_init() { filter_index = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, set_free); } void filter_deinit() { g_hash_table_destroy(filter_index); } void filter_add(const gchar *text, unsigned int index) { const gchar *c = g_utf8_next_char(text); glong begin, end; struct set *set; gchar *substr; for (begin = 0, end = 1; end <= g_utf8_strlen(text, -1); end++) { substr = g_utf8_substring(text, begin, end); set = g_hash_table_lookup(filter_index, substr); if (!set) { set = set_alloc(); g_hash_table_insert(filter_index, substr, set); } set_insert(set, index); if (g_unichar_isspace(g_utf8_get_char(c))) { c = g_utf8_next_char(c); begin = ++end; } c = g_utf8_next_char(c); } } void filter_search(const gchar *text, struct set *res) { gchar *lower = string_lowercase(text); struct set *found; glong begin, end; gchar *c, *substr; set_clear(res); c = lower; for (begin = 0, end = 1; end <= g_utf8_strlen(lower, -1); end++) { c = g_utf8_next_char(c); if ((*c != '\0') && !g_unichar_isspace(g_utf8_get_char(c))) continue; substr = g_utf8_substring(lower, begin, end); found = g_hash_table_lookup(filter_index, substr); g_free(substr); if (!found) { set_clear(res); break; } if (begin == 0) set_copy(found, res); else set_inline_intersect(found, res); c = g_utf8_next_char(c); begin = ++end; } g_free(lower); }