2
* Copyright © 2012 Canonical Ltd.
4
* This program is free software: you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License version 3, as
6
* published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranties of
10
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11
* PURPOSE. See the GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License along
14
* with this program. If not, see <http://www.gnu.org/licenses/>.
16
* Author: Ryan Lortie <desrt@desrt.ca>
19
#include "hudsettings.h"
22
#include "hudsource.h"
24
#include <glib-object.h>
26
#include "word-list.h"
28
/* Max nested depth of menu items */
31
/* Max number of items per submenu */
34
/* Max number of words per label.
35
* NB: keep MAX_WORDS * MAX_DEPTH under 32
39
/* Longest word in the word-list (upper bound) */
40
#define MAX_LETTERS 20
42
/* hardcode some parameters for reasons of determinism.
44
HudSettings hud_settings = {
45
.indicator_penalty = 50,
48
.end_drop_penalty = 1,
60
typedef GObjectClass RandomSourceClass;
62
static void random_source_iface_init (HudSourceInterface *iface);
63
G_DEFINE_TYPE_WITH_CODE (RandomSource, random_source, G_TYPE_OBJECT,
64
G_IMPLEMENT_INTERFACE (HUD_TYPE_SOURCE, random_source_iface_init))
67
random_source_search (HudSource *hud_source,
68
GPtrArray *results_array,
69
HudTokenList *search_tokens)
71
RandomSource *source = (RandomSource *) hud_source;
75
g_hash_table_iter_init (&iter, source->items);
76
while (g_hash_table_iter_next (&iter, &item, NULL))
80
result = hud_result_get_if_matched (item, search_tokens, 0);
82
g_ptr_array_add (results_array, result);
87
random_source_ignore_use (HudSource *source)
92
make_word (GRand *rand,
99
choice = g_rand_int_range (rand, 0, G_N_ELEMENTS (word_list));
100
word = word_list[choice];
109
make_words (GRand *rand,
116
buffer = g_malloc ((MAX_LETTERS + 1) * n_words);
119
for (i = 0; i < n_words; i++)
124
ptr = make_word (rand, ptr);
132
static HudStringList *
133
random_source_make_name (GRand *rand,
134
HudStringList *context)
139
label = make_words (rand, g_rand_int_range (rand, 1, MAX_WORDS + 1));
140
name = hud_string_list_cons (label, context);
147
random_source_populate_table (GRand *rand,
149
HudStringList *context,
155
n_items = g_rand_int_range (rand, 1, MAX_ITEMS + 1);
157
for (i = 0; i < n_items; i++)
163
name = random_source_make_name (rand, context);
165
if (depth != MAX_DEPTH)
166
/* Decrease the chances of a particular item being a submenu as we
167
* go deeper into the menu structure.
169
is_submenu = g_rand_int_range (rand, 0, depth + 1) == 0;
171
/* At the maximum depth, prevent any items from being submenus. */
174
item = hud_item_new (name, NULL, NULL, !is_submenu);
175
g_hash_table_add (items, item);
178
random_source_populate_table (rand, items, name, depth + 1);
180
hud_string_list_unref (name);
185
random_source_finalize (GObject *object)
187
RandomSource *source = (RandomSource *) object;
189
g_hash_table_unref (source->items);
191
G_OBJECT_CLASS (random_source_parent_class)
196
random_source_init (RandomSource *source)
198
source->items = g_hash_table_new_full (NULL, NULL, g_object_unref, NULL);
202
random_source_iface_init (HudSourceInterface *iface)
204
iface->use = random_source_ignore_use;
205
iface->unuse = random_source_ignore_use;
206
iface->search = random_source_search;
210
random_source_class_init (RandomSourceClass *class)
212
class->finalize = random_source_finalize;
216
random_source_new (GRand *rand)
218
RandomSource *source;
220
source = g_object_new (random_source_get_type (), NULL);
221
random_source_populate_table (rand, source->items, NULL, 0);
223
return HUD_SOURCE (source);
227
test_query_performance (void)
234
rand = g_rand_new_with_seed (1234);
235
source = random_source_new (rand);
237
for (i = 1; i <= 6; i++)
245
search = make_words (rand, i);
247
/* simulate the user typing it in, one character at a time */
248
for (j = 1; search[j - 1]; j++)
250
gchar *part_search = g_strndup (search, j);
252
start_time = g_get_monotonic_time ();
253
query = hud_query_new (source, part_search, 1u<<30);
254
g_print ("%-60s: %dus (%d hits)\n", part_search,
255
(int) (g_get_monotonic_time () - start_time),
256
hud_query_get_n_results (query));
257
hud_query_close (query);
258
g_object_unref (query);
259
g_free (part_search);
265
g_object_unref (source);
270
main (int argc, char **argv)
272
g_test_init (&argc, &argv, NULL);
275
g_test_add_func ("/hud/query-performance", test_query_performance);
277
return g_test_run ();