dee

Merge lp:~mhr3/dee/fix-prefix-search into lp:dee

Proposed by Michal Hruby
Status: Merged
Approved by: Mikkel Kamstrup Erlandsen
Approved revision: 344
Merged at revision: 345
Proposed branch: lp:~mhr3/dee/fix-prefix-search
Merge into: lp:dee
Diff against target: 129 lines (+68/-10)
2 files modified
src/dee-tree-index.c (+24/-10)
tests/test-index.c (+44/-0)
To merge this branch: bzr merge lp:~mhr3/dee/fix-prefix-search
Reviewer Review Type Date Requested Status
Mikkel Kamstrup Erlandsen (community) Approve
Review via email: mp+93307@code.launchpad.net

Description of the change

Fixes a bug in prefix searching.

Added tests for the issue.

To post a comment you must log in.
Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

Tests pass and code looks swell

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/dee-tree-index.c'
2--- src/dee-tree-index.c 2011-11-29 12:17:25 +0000
3+++ src/dee-tree-index.c 2012-02-15 22:09:17 +0000
4@@ -226,7 +226,7 @@
5 DeeTermMatchFlag flags)
6 {
7 Term search_term, *term_result;
8- GSequenceIter *iter, *begin, *end;
9+ GSequenceIter *found_iter, *iter, *previous, *begin, *end;
10
11 begin = g_sequence_get_begin_iter (terms);
12 end = g_sequence_get_end_iter (terms);
13@@ -239,24 +239,38 @@
14
15 if (flags & DEE_TERM_MATCH_EXACT)
16 {
17+ // FIXME: do we need to make sure this is the first iter?
18 return g_sequence_lookup (terms, &search_term,
19 (GCompareDataFunc) term_cmp, analyzer);
20 }
21 else if (flags & DEE_TERM_MATCH_PREFIX)
22 {
23- iter = g_sequence_search (terms, &search_term,
24- (GCompareDataFunc) term_cmp, analyzer);
25- term_result = g_sequence_get (iter);
26- if (g_str_has_prefix (term_result->col_key, term))
27- return iter;
28- else if (iter != begin)
29- {
30- /* We might be placed immediately after the iter we want */
31- iter = g_sequence_iter_prev (iter);
32+ found_iter = g_sequence_search (terms, &search_term,
33+ (GCompareDataFunc) term_cmp, analyzer);
34+
35+ /* What can happen now is:
36+ * 1) found_iter has our prefix
37+ * 2) found_iter as well as the found_iter->previous have our prefix
38+ * 3) found_iter doesn't have it, but found_iter->previous does
39+ * 4) there isn't any nearby iter that has the prefix */
40+ previous = iter = found_iter;
41+ /* We might be placed after the iter we want */
42+ while (previous != begin)
43+ {
44+ previous = g_sequence_iter_prev (previous);
45+ term_result = g_sequence_get (previous);
46+ if (g_str_has_prefix (term_result->col_key, term)) iter = previous;
47+ else break;
48+ }
49+ if (iter == found_iter)
50+ {
51+ /* We never checked this one */
52 term_result = g_sequence_get (iter);
53 if (g_str_has_prefix (term_result->col_key, term))
54 return iter;
55 }
56+ else
57+ return iter;
58 }
59 else
60 {
61
62=== modified file 'tests/test-index.c'
63--- tests/test-index.c 2011-12-14 10:49:16 +0000
64+++ tests/test-index.c 2012-02-15 22:09:17 +0000
65@@ -369,6 +369,47 @@
66 }
67
68 static void
69+test_prefix_2_rows (Fixture *fix, gconstpointer data)
70+{
71+ DeeModelIter *iter, *i0, *i1;
72+ DeeResultSet *results;
73+
74+ g_assert (dee_index_get_supported_term_match_flags (fix->index) &
75+ DEE_TERM_MATCH_PREFIX);
76+
77+ i0 = dee_model_append (fix->model, "Caravan scrap yard", 0);
78+ i1 = dee_model_append (fix->model, "Scraper foo", 1);
79+
80+ /* NOTE: We can NOT infer anything about the ordering of the matching
81+ * iters inside a single term */
82+ results = dee_index_lookup (fix->index, "scrap", DEE_TERM_MATCH_PREFIX);
83+ g_assert_cmpint (dee_result_set_get_n_rows (results), ==, 2);
84+ iter = dee_result_set_next (results);
85+ g_assert (iter == i0 || iter == i1);
86+ iter = dee_result_set_next (results);
87+ g_assert (iter == i0 || iter == i1);
88+ g_object_unref (results);
89+
90+ results = dee_index_lookup (fix->index, "scra", DEE_TERM_MATCH_PREFIX);
91+ g_assert_cmpint (dee_result_set_get_n_rows (results), ==, 2);
92+ iter = dee_result_set_next (results);
93+ g_assert (iter == i0 || iter == i1);
94+ iter = dee_result_set_next (results);
95+ g_assert (iter == i0 || iter == i1);
96+ g_object_unref (results);
97+
98+ results = dee_index_lookup (fix->index, "scraper", DEE_TERM_MATCH_PREFIX);
99+ g_assert_cmpint (dee_result_set_get_n_rows (results), ==, 1);
100+ iter = dee_result_set_next (results);
101+ g_assert (iter == i1);
102+ g_object_unref (results);
103+
104+ results = dee_index_lookup (fix->index, "scraperer", DEE_TERM_MATCH_PREFIX);
105+ g_assert_cmpint (dee_result_set_get_n_rows (results), ==, 0);
106+ g_object_unref (results);
107+}
108+
109+static void
110 test_prefix_3_rows (Fixture *fix, gconstpointer data)
111 {
112 DeeModelIter *iter, *i0, *i1;
113@@ -393,6 +434,7 @@
114
115 results = dee_index_lookup (fix->index, "hel", DEE_TERM_MATCH_PREFIX);
116 g_assert_cmpint (dee_result_set_get_n_rows (results), ==, 2);
117+ iter = dee_result_set_next (results);
118 g_assert (iter == i0 || iter == i1);
119 iter = dee_result_set_next (results);
120 g_assert (iter == i0 || iter == i1);
121@@ -470,6 +512,8 @@
122 setup_text_tree, test_text_with_dupe_terms_per_row, teardown);
123 g_test_add ("/Index/Tree/Prefix1Row", Fixture, 0,
124 setup_text_tree, test_prefix_1_row, teardown);
125+ g_test_add ("/Index/Tree/Prefix2Rows", Fixture, 0,
126+ setup_text_tree, test_prefix_2_rows, teardown);
127 g_test_add ("/Index/Tree/Prefix3Rows", Fixture, 0,
128 setup_text_tree, test_prefix_3_rows, teardown);
129 g_test_add ("/Index/Tree/Prefix4RowsAndClear", Fixture, 0,

Subscribers

People subscribed via source and target branches

to all changes: