diff --git a/core/filter.c b/core/filter.c index 4429861a..0f1b55d0 100644 --- a/core/filter.c +++ b/core/filter.c @@ -45,6 +45,29 @@ void filter_add(const gchar *text, unsigned int index) } } +void filter_remove(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_remove(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); diff --git a/core/tags/track.c b/core/tags/track.c index 79b6f0a0..7e963348 100644 --- a/core/tags/track.c +++ b/core/tags/track.c @@ -102,6 +102,10 @@ static void track_free(struct db_entry *dbe) if (track->tr_library) track->tr_library->li_size--; + filter_remove(track->tr_lower, dbe->dbe_index); + filter_remove(track->tr_artist->ar_lower, dbe->dbe_index); + filter_remove(track->tr_album->al_lower, dbe->dbe_index); + g_free(track->tr_title); g_free(track->tr_lower); g_free(track); diff --git a/include/core/filter.h b/include/core/filter.h index af8e9901..87bc7b89 100644 --- a/include/core/filter.h +++ b/include/core/filter.h @@ -18,6 +18,9 @@ void filter_deinit(); /* Add the input string to the index. */ void filter_add(const gchar *, unsigned int); +/* Remove the input string from the index. */ +void filter_remove(const gchar *, unsigned int); + /* Search for the input string in the index. */ void filter_search(const gchar *, struct set *); diff --git a/tests/core/filter.c b/tests/core/filter.c index 309b73b1..c12af1d7 100644 --- a/tests/core/filter.c +++ b/tests/core/filter.c @@ -65,6 +65,13 @@ static void test_filter() filter_search("", &res); test_equal(set_size(&res), 0); + /* Remove a string and search again. */ + filter_remove("hyrule symphony", 1); + filter_search("hyrule", &res); + test_equal(set_size(&res), 2); + test_equal(set_has(&res, 3), (bool)true); /* hyrule field */ + test_equal(set_has(&res, 4), (bool)true); /* hyrule castle */ + filter_deinit(); set_deinit(&res); } diff --git a/tests/core/tags/track.c b/tests/core/tags/track.c index edd89a7b..9c8517ab 100644 --- a/tests/core/tags/track.c +++ b/tests/core/tags/track.c @@ -125,7 +125,13 @@ static void test_track() static void test_track_filter() { + const struct db_ops *track_ops = test_track_ops(); struct set search = SET_INIT(); + struct track *track; + + track = test_alloc("0/Hyrule Symphony/01 - Title Theme.ogg"); + track->tr_dbe.dbe_index = 0; + track_ops->dbe_setup(&track->tr_dbe); filter_search("Title Theme", &search); test_equal(set_size(&search), 1); @@ -143,6 +149,8 @@ static void test_track_filter() test_equal(set_size(&search), 0); set_deinit(&search); + g_free(track->tr_path); + track_ops->dbe_free(&track->tr_dbe); } static void test_track_compare()