]> Pileus Git - ~andy/gtk/blob - tests/testtreemodel.c
stylecontext: Do invalidation on first resize container
[~andy/gtk] / tests / testtreemodel.c
1 /* testtreemodel.c
2  * Copyright (C) 2004  Red Hat, Inc.,  Matthias Clasen <mclasen@redhat.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include "config.h"
19
20 #include <string.h>
21
22 #ifdef HAVE_MALLINFO
23 #include <malloc.h>
24 #endif
25
26 #include <gtk/gtk.h>
27
28 static gint repeats = 2;
29 static gint max_size = 8;
30
31 static GOptionEntry entries[] = {
32   { "repeats", 'r', 0, G_OPTION_ARG_INT, &repeats, "Average over N repetitions", "N" },
33   { "max-size", 'm', 0, G_OPTION_ARG_INT, &max_size, "Test up to 2^M items", "M" },
34   { NULL }
35 };
36
37
38 typedef void (ClearFunc)(GtkTreeModel *model);
39 typedef void (InsertFunc)(GtkTreeModel *model,
40                           gint          items,
41                           gint          i);
42
43 static void
44 list_store_append (GtkTreeModel *model,
45                    gint          items,
46                    gint          i)
47 {
48   GtkListStore *store = GTK_LIST_STORE (model);
49   GtkTreeIter iter;
50   gchar *text;
51
52   text = g_strdup_printf ("row %d", i);
53   gtk_list_store_append (store, &iter);
54   gtk_list_store_set (store, &iter, 0, i, 1, text, -1);
55   g_free (text);
56 }
57
58 static void
59 list_store_prepend (GtkTreeModel *model,
60                     gint          items,
61                     gint          i)
62 {
63   GtkListStore *store = GTK_LIST_STORE (model);
64   GtkTreeIter iter;
65   gchar *text;
66
67   text = g_strdup_printf ("row %d", i);
68   gtk_list_store_prepend (store, &iter);
69   gtk_list_store_set (store, &iter, 0, i, 1, text, -1);
70   g_free (text);
71 }
72
73 static void
74 list_store_insert (GtkTreeModel *model,
75                    gint          items,
76                    gint          i)
77 {
78   GtkListStore *store = GTK_LIST_STORE (model);
79   GtkTreeIter iter;
80   gchar *text;
81   gint n;
82
83   text = g_strdup_printf ("row %d", i);
84   n = g_random_int_range (0, i + 1);
85   gtk_list_store_insert (store, &iter, n);
86   gtk_list_store_set (store, &iter, 0, i, 1, text, -1);
87   g_free (text);
88 }
89
90 static gint
91 compare (GtkTreeModel *model,
92          GtkTreeIter  *a,
93          GtkTreeIter  *b,
94          gpointer      data)
95 {
96   gchar *str_a, *str_b;
97   gint result;
98
99   gtk_tree_model_get (model, a, 1, &str_a, -1);
100   gtk_tree_model_get (model, b, 1, &str_b, -1);
101   
102   result = strcmp (str_a, str_b);
103
104   g_free (str_a);
105   g_free (str_b);
106
107   return result;
108 }
109
110 static void
111 tree_store_append (GtkTreeModel *model,
112                    gint          items,
113                    gint          i)
114 {
115   GtkTreeStore *store = GTK_TREE_STORE (model);
116   GtkTreeIter iter;
117   gchar *text;
118
119   text = g_strdup_printf ("row %d", i);
120   gtk_tree_store_append (store, &iter, NULL);
121   gtk_tree_store_set (store, &iter, 0, i, 1, text, -1);
122   g_free (text);
123 }
124
125 static void
126 tree_store_prepend (GtkTreeModel *model,
127                     gint          items,
128                     gint          i)
129 {
130   GtkTreeStore *store = GTK_TREE_STORE (model);
131   GtkTreeIter iter;
132   gchar *text;
133
134   text = g_strdup_printf ("row %d", i);
135   gtk_tree_store_prepend (store, &iter, NULL);
136   gtk_tree_store_set (store, &iter, 0, i, 1, text, -1);
137   g_free (text);
138 }
139
140 static void
141 tree_store_insert_flat (GtkTreeModel *model,
142                         gint          items,
143                         gint          i)
144 {
145   GtkTreeStore *store = GTK_TREE_STORE (model);
146   GtkTreeIter iter;
147   gchar *text;
148   gint n;
149
150   text = g_strdup_printf ("row %d", i);
151   n = g_random_int_range (0, i + 1);
152   gtk_tree_store_insert (store, &iter, NULL, n);
153   gtk_tree_store_set (store, &iter, 0, i, 1, text, -1);
154   g_free (text);
155 }
156
157 typedef struct {
158   gint i;
159   gint n;
160   gboolean found;
161   GtkTreeIter iter;
162 } FindData;
163
164 static gboolean
165 find_nth (GtkTreeModel *model,
166           GtkTreePath  *path,
167           GtkTreeIter  *iter,
168           gpointer      data)
169 {
170   FindData *fdata = (FindData *)data; 
171
172   if (fdata->i >= fdata->n)
173     {
174       fdata->iter = *iter;
175       fdata->found = TRUE;
176       return TRUE;
177     }
178
179   fdata->i++;
180
181   return FALSE;
182 }
183
184 static void
185 tree_store_insert_deep (GtkTreeModel *model,
186                         gint          items,
187                         gint          i)
188 {
189   GtkTreeStore *store = GTK_TREE_STORE (model);
190   GtkTreeIter iter;
191   gchar *text;
192   FindData data;
193
194   text = g_strdup_printf ("row %d", i);
195   data.n = g_random_int_range (0, items);
196   data.i = 0;
197   data.found = FALSE;
198   if (data.n < i)
199     gtk_tree_model_foreach (model, find_nth, &data);
200   gtk_tree_store_insert (store, &iter, data.found ? &(data.iter) : NULL, data.n);
201   gtk_tree_store_set (store, &iter, 0, i, 1, text, -1);
202   g_free (text);
203 }
204
205
206 static void
207 test_run (gchar        *title,
208           GtkTreeModel *store,
209           ClearFunc    *clear,
210           InsertFunc   *insert)
211 {
212   gint i, k, d, items;
213   GTimer *timer;
214   gdouble elapsed;
215   int uordblks_before = 0, memused;
216
217   g_print ("%s (average over %d runs, time in milliseconds)\n"
218            "items \ttime      \ttime/item \tused memory\n", title, repeats);
219
220   timer = g_timer_new ();
221
222   for (k = 0; k < max_size; k++)
223     {
224       items = 1 << k;
225       elapsed = 0.0;
226       for (d = 0; d < repeats; d++)
227         {
228           (*clear)(store);
229 #ifdef HAVE_MALLINFO
230           /* Peculiar location of this, btw.  -- MW.  */
231           uordblks_before = mallinfo().uordblks;
232 #endif
233           g_timer_reset (timer);
234           g_timer_start (timer);
235           for (i = 0; i < items; i++)
236             (*insert) (store, items, i);
237           g_timer_stop (timer);
238           elapsed += g_timer_elapsed (timer, NULL);
239         }
240       
241       elapsed = elapsed * 1000 / repeats;
242 #ifdef HAVE_MALLINFO
243       memused = (mallinfo().uordblks - uordblks_before) / 1024;
244 #else
245       memused = 0;
246 #endif
247       g_print ("%d \t%f \t%f  \t%dk\n", 
248                items, elapsed, elapsed/items, memused);
249     }  
250 }
251
252 int
253 main (int argc, char *argv[])
254 {
255   GtkTreeModel *model;
256   
257   gtk_init_with_args (&argc, &argv, NULL, entries, NULL, NULL);
258
259   model = GTK_TREE_MODEL (gtk_list_store_new (2, G_TYPE_INT, G_TYPE_STRING));
260   
261   test_run ("list store append", 
262             model, 
263             (ClearFunc*)gtk_list_store_clear, 
264             (InsertFunc*)list_store_append);
265
266   test_run ("list store prepend", 
267             model, 
268             (ClearFunc*)gtk_list_store_clear, 
269             (InsertFunc*)list_store_prepend);
270
271   test_run ("list store insert", 
272             model, 
273             (ClearFunc*)gtk_list_store_clear, 
274             (InsertFunc*)list_store_insert);
275
276   gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (model), 
277                                            compare, NULL, NULL);
278   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), 
279                                         GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
280                                         GTK_SORT_ASCENDING);
281
282   test_run ("list store insert (sorted)", 
283             model, 
284             (ClearFunc*)gtk_list_store_clear, 
285             (InsertFunc*)list_store_insert);
286
287   g_object_unref (model);
288   
289   model = GTK_TREE_MODEL (gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_STRING));
290
291   test_run ("tree store append", 
292             model, 
293             (ClearFunc*)gtk_tree_store_clear, 
294             (InsertFunc*)tree_store_append);
295
296   test_run ("tree store prepend", 
297             model, 
298             (ClearFunc*)gtk_tree_store_clear, 
299             (InsertFunc*)tree_store_prepend);
300
301   test_run ("tree store insert (flat)", 
302             model, 
303             (ClearFunc*)gtk_tree_store_clear, 
304             (InsertFunc*)tree_store_insert_flat);
305
306   test_run ("tree store insert (deep)", 
307             model, 
308             (ClearFunc*)gtk_tree_store_clear, 
309             (InsertFunc*)tree_store_insert_deep);
310
311   gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (model), 
312                                            compare, NULL, NULL);
313   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), 
314                                         GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
315                                         GTK_SORT_ASCENDING);
316
317   test_run ("tree store insert (flat, sorted)", 
318             model, 
319             (ClearFunc*)gtk_tree_store_clear, 
320             (InsertFunc*)tree_store_insert_flat);
321
322   test_run ("tree store insert (deep, sorted)", 
323             model, 
324             (ClearFunc*)gtk_tree_store_clear, 
325             (InsertFunc*)tree_store_insert_deep);
326
327   return 0;
328 }