Merge lp:~tombeckmann/+junk/libcolumbus into lp:~elementary-pantheon/slingshot/trunk

Proposed by Tom Beckmann on 2014-03-03
Status: Rejected
Rejected by: Tom Beckmann on 2014-06-29
Proposed branch: lp:~tombeckmann/+junk/libcolumbus
Merge into: lp:~elementary-pantheon/slingshot/trunk
Diff against target: 289 lines (+208/-4)
4 files modified
CMakeLists.txt (+15/-1)
src/Backend/AppSystem.vala (+33/-3)
src/Backend/ColumbusSearchModel.vala (+88/-0)
vapi/libcolumbus.vapi (+72/-0)
To merge this branch: bzr merge lp:~tombeckmann/+junk/libcolumbus
Reviewer Review Type Date Requested Status
Daniel Fore 2014-03-03 Needs Fixing on 2014-03-07
Review via email: mp+209144@code.launchpad.net

Description of the change

This adds support for libcolumbus, it replaces the previous search and weighting algorithm, which is still used if columbus is disabled before compilation. If I'm not completely mistaken, the app relevancies as provided by Zeitgeist should still be used to sort the results returned by libcolubmus.

Please test if the results shown are indeed sensible, otherwise I'll go and adjust the index weights or check which part of the API I misunderstood.

To post a comment you must log in.
Daniel Fore (danrabbit) wrote :

Hrm I'm getting a build error: make[2]: *** No rule to make target `../src/Widgets/SearchViewInterface.vala'

In my head I would think User Input > LibColumbus > Zeitgeist > Search Results. I think that's what you're saying you did right?

Tom Beckmann (tombeckmann) wrote :

You can just remove src/Widgets/SearchViewInterface.vala to make it compile, I'll fix it once I get back to my computer, which will take a while.
Theoretically that's what should happen, yes.

lp:~tombeckmann/+junk/libcolumbus updated on 2014-03-04
409. By Tom Beckmann on 2014-03-04

remove reference to non existent file

Tom Beckmann (tombeckmann) wrote :

Should work fine now.

Rico Tzschichholz (ricotz) wrote :

Relative header-paths in vapis aren't a good idea.
Aren't there bindings for libcolumbus itself to avoid using ccode with a primitive vapi?

lp:~tombeckmann/+junk/libcolumbus updated on 2014-03-04
410. By Tom Beckmann on 2014-03-04

add real libcolumbus vapi by ricotz, improve search results

Tom Beckmann (tombeckmann) wrote :

Thanks to ricotz providing a vapi for libcolumbus I could drop the C code now. Also the search results should be a lot better now.

lp:~tombeckmann/+junk/libcolumbus updated on 2014-03-04
411. By Tom Beckmann on 2014-03-04

forgot most important class -.-

412. By Tom Beckmann on 2014-03-04

add some docs, remove debug print

Daniel Fore (danrabbit) wrote :

Hrm, I feel like the top result isn't as good as it was before.

It's pretty cool getting results even when you have typos, but when I don't make typos (such as typing "mi") I'm not getting the result I expect ("Midori" or "Minecraft")

Since typos shouldn't return results, can we list results returned from the actual typed string first and results returned from libcolumbus after those?

That way, we'll get "minecraft" listed before "terminal" (command line) when I type "mine"

review: Needs Fixing

Unmerged revisions

412. By Tom Beckmann on 2014-03-04

add some docs, remove debug print

411. By Tom Beckmann on 2014-03-04

forgot most important class -.-

410. By Tom Beckmann on 2014-03-04

add real libcolumbus vapi by ricotz, improve search results

409. By Tom Beckmann on 2014-03-04

remove reference to non existent file

408. By Tom Beckmann on 2014-03-03

add support for libcolumbus

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2014-02-23 19:56:35 +0000
3+++ CMakeLists.txt 2014-03-04 23:27:45 +0000
4@@ -54,8 +54,19 @@
5 message ("-- Zeitgeist integration disabled")
6 endif ()
7
8+option (USE_LIBCOLUMBUS "Use libcolumbus for fuzzy matching" ON)
9+
10+if (USE_LIBCOLUMBUS)
11+ message ("-- libcolumbus integration enabled")
12+ set (LIBCOLUMBUS_DEPS libcolumbus)
13+ set (LIBCOLUMBUS_OPTIONS --define=HAVE_LIBCOLUMBUS --vapidir=${CMAKE_SOURCE_DIR}/vapi)
14+ set (LIBCOLUMBUS_SOURCES src/Backend/ColumbusSearchModel.vala)
15+else ()
16+ message ("-- libcolumbus integration disabled")
17+endif ()
18+
19 set (CORE_DEPS "gobject-2.0;glib-2.0;gio-2.0;gio-unix-2.0;gee-0.8;libgnome-menu-3.0;libwnck-3.0;gdk-x11-3.0;${UNITY_DEPS};")
20-set (UI_DEPS "gtk+-3.0>=3.2.0;granite;${ZEITGEIST_DEPS};")
21+set (UI_DEPS "gtk+-3.0>=3.2.0;granite;${ZEITGEIST_DEPS};${LIBCOLUMBUS_DEPS};")
22
23 find_package (PkgConfig)
24 pkg_check_modules (DEPS REQUIRED "${CORE_DEPS}${UI_DEPS}" gthread-2.0)
25@@ -81,16 +92,19 @@
26 src/Widgets/SearchItem.vala
27 src/Widgets/Sidebar.vala
28 src/Widgets/CategoryView.vala
29+ ${LIBCOLUMBUS_SOURCES}
30 PACKAGES
31 ${CORE_DEPS}
32 ${UI_DEPS}
33 CUSTOM_VAPIS
34 vapi/config.vapi
35+ ${LIBCOLUMBUS_VAPI}
36 OPTIONS
37 --thread
38 -g
39 ${UNITY_OPTIONS}
40 ${ZEITGEIST_OPTIONS}
41+ ${LIBCOLUMBUS_OPTIONS}
42 )
43
44 # Comment this out to enable C compiler warnings
45
46=== modified file 'src/Backend/AppSystem.vala'
47--- src/Backend/AppSystem.vala 2013-01-10 16:53:50 +0000
48+++ src/Backend/AppSystem.vala 2014-03-04 23:27:45 +0000
49@@ -26,6 +26,10 @@
50 private RelevancyService rl_service;
51 #endif
52
53+#if HAVE_LIBCOLUMBUS
54+ private ColumbusSearch.Model search_model;
55+#endif
56+
57 public signal void changed ();
58
59 construct {
60@@ -35,6 +39,10 @@
61 rl_service.update_complete.connect (update_popularity);
62 #endif
63
64+#if HAVE_LIBCOLUMBUS
65+ search_model = new ColumbusSearch.Model ();
66+#endif
67+
68 apps_menu = new GMenu.Tree ("pantheon-applications.menu", GMenu.TreeFlags.INCLUDE_EXCLUDED | GMenu.TreeFlags.SORT_DISPLAY_NAME);
69 apps_menu.changed.connect (update_app_system);
70
71@@ -90,9 +98,24 @@
72
73 apps.clear ();
74
75- foreach (var cat in categories)
76- apps.set (cat.get_name (), get_apps_by_category (cat));
77-
78+#if HAVE_LIBCOLUMBUS
79+ search_model.clear ();
80+#endif
81+
82+ foreach (var cat in categories) {
83+ var category_apps = get_apps_by_category (cat);
84+ apps.set (cat.get_name (), category_apps);
85+#if HAVE_LIBCOLUMBUS
86+ foreach (var app in category_apps) {
87+ search_model.add_entry (app, app.name,
88+ app.description, app.exec);
89+ }
90+#endif
91+ }
92+
93+#if HAVE_LIBCOLUMBUS
94+ search_model.finished_adding ();
95+#endif
96 }
97
98 public Gee.ArrayList<GMenu.TreeDirectory> get_categories () {
99@@ -171,6 +194,12 @@
100
101 var filtered = new Gee.ArrayList<App> ();
102
103+#if HAVE_LIBCOLUMBUS
104+ List<void*> results = search_model.match (search);
105+ foreach (var result in results) {
106+ filtered.add (result as App);
107+ }
108+#else
109 /** It's a bit stupid algorithm, simply check if the char is present
110 * some of the App values, then assign it a double. This is very simple:
111 * if an App name coincide with the search string they have obvious the
112@@ -213,6 +242,7 @@
113 }
114 }
115 }
116+#endif
117
118 filtered.sort ((a, b) => Utils.sort_apps_by_relevancy ((App) a, (App) b));
119
120
121=== added file 'src/Backend/ColumbusSearchModel.vala'
122--- src/Backend/ColumbusSearchModel.vala 1970-01-01 00:00:00 +0000
123+++ src/Backend/ColumbusSearchModel.vala 2014-03-04 23:27:45 +0000
124@@ -0,0 +1,88 @@
125+
126+#if HAVE_LIBCOLUMBUS
127+using Columbus;
128+
129+namespace ColumbusSearch
130+{
131+ public class Model : Object {
132+ Corpus corpus;
133+ Matcher matcher;
134+
135+ Word field_name;
136+ Word field_description;
137+ Word field_exec;
138+
139+ public Model () {
140+ corpus = new Corpus ();
141+ matcher = new Matcher ();
142+
143+ field_name = new Word ("name");
144+ field_description = new Word ("description");
145+ field_exec = new Word ("exec");
146+ }
147+
148+ /**
149+ * Add an entry to the model.
150+ *
151+ * @param id A pointer to the app which is identified by these values. It
152+ * is internally used as an id.
153+ * @param name The app's name
154+ * @param description The app's description
155+ * @param exec The app's executable line
156+ */
157+ public void add_entry (void *id, string name, string description, string exec) {
158+ var doc = new Document ((DocumentID)id);
159+
160+ doc.add_text (field_name, name);
161+ doc.add_text (field_description, description);
162+ doc.add_text (field_exec, exec);
163+
164+ corpus.add_document (doc);
165+ }
166+
167+ /**
168+ * Call this function after you added all the entries to build the index
169+ */
170+ public void finished_adding ()
171+ {
172+ matcher.index (corpus);
173+
174+ var errors = matcher.get_error_values ();
175+ errors.add_standard_errors ();
176+ errors.set_substring_mode ();
177+
178+ var weights = matcher.get_index_weights ();
179+ weights.set_weight (field_description, 0.5);
180+ }
181+
182+ /**
183+ * Clear the current model
184+ */
185+ public void clear () {
186+ corpus = new Corpus ();
187+ }
188+
189+ /**
190+ * Search in the model. Don't forget to call finished_adding before calling this
191+ *
192+ * @param query The query string to be searched for
193+ * @return Returns a list of the ids which represent pointers to the app
194+ * objects as added earlier.
195+ */
196+ public List<void*> match (string query) {
197+ var result = matcher.match (query);
198+ var len = result.size ();
199+
200+ var list = new List<void*> ();
201+ for (var i = 0; i < len; i++) {
202+ list.prepend ((void*)result.get_id (i));
203+ }
204+
205+ list.reverse ();
206+
207+ return list;
208+ }
209+ }
210+}
211+
212+#endif
213
214=== added file 'vapi/libcolumbus.vapi'
215--- vapi/libcolumbus.vapi 1970-01-01 00:00:00 +0000
216+++ vapi/libcolumbus.vapi 2014-03-04 23:27:45 +0000
217@@ -0,0 +1,72 @@
218+/* libcolumbus.vapi generated by vapigen, do not modify. */
219+
220+[CCode (cprefix = "Col", lower_case_cprefix = "col_")]
221+namespace Columbus {
222+ [CCode (cheader_filename = "columbus.h", free_function = "col_corpus_delete")]
223+ [Compact]
224+ public class Corpus {
225+ [CCode (has_construct_function = false, type = "ColCorpus")]
226+ public Corpus ();
227+ public void add_document (Columbus.Document d);
228+ public void @delete ();
229+ }
230+ [CCode (cheader_filename = "columbus.h", free_function = "col_document_delete")]
231+ [Compact]
232+ public class Document {
233+ [CCode (has_construct_function = false, type = "ColDocument")]
234+ public Document (Columbus.DocumentID id);
235+ public void add_text (Columbus.Word field_name, string text_as_utf8);
236+ public void @delete ();
237+ public Columbus.DocumentID get_id ();
238+ }
239+ [CCode (cheader_filename = "columbus.h", free_function = "")]
240+ [Compact]
241+ public class ErrorValues {
242+ public void add_standard_errors ();
243+ public void set_substring_mode ();
244+ }
245+ [CCode (cheader_filename = "columbus.h", free_function = "")]
246+ [Compact]
247+ public class IndexWeights {
248+ public double get_weight (Columbus.Word field);
249+ public void set_weight (Columbus.Word field, double new_weight);
250+ }
251+ [CCode (cheader_filename = "columbus.h", free_function = "col_match_results_delete")]
252+ [Compact]
253+ public class MatchResults {
254+ [CCode (has_construct_function = false, type = "ColMatchResults")]
255+ public MatchResults ();
256+ public void @delete ();
257+ public Columbus.DocumentID get_id (size_t i);
258+ public double get_relevancy (size_t i);
259+ public size_t size ();
260+ }
261+ [CCode (cheader_filename = "columbus.h", free_function = "col_matcher_delete")]
262+ [Compact]
263+ public class Matcher {
264+ [CCode (has_construct_function = false, type = "ColMatcher")]
265+ public Matcher ();
266+ public void @delete ();
267+ public Columbus.ErrorValues get_error_values ();
268+ public Columbus.IndexWeights get_index_weights ();
269+ public void index (Columbus.Corpus c);
270+ public Columbus.MatchResults match (string query_as_utf8);
271+ }
272+ [CCode (cheader_filename = "columbus.h", free_function = "col_word_delete")]
273+ [Compact]
274+ public class Word {
275+ [CCode (has_construct_function = false, type = "ColWord")]
276+ public Word (string utf8_word);
277+ public void as_utf8 (string buf, uint bufSize);
278+ public void @delete ();
279+ public size_t length ();
280+ }
281+ [CCode (cname = "uintptr_t", cheader_filename = "columbus.h", cprefix = "")]
282+ [SimpleType]
283+ public struct DocumentID {
284+ }
285+ [CCode (cname = "uint32_t", cheader_filename = "columbus.h", cprefix = "")]
286+ [SimpleType]
287+ public struct WordID {
288+ }
289+}

Subscribers

People subscribed via source and target branches