aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-12-02 21:23:17 -0500
committerSteven Rostedt <rostedt@goodmis.org>2009-12-17 21:43:47 -0500
commit064e10948d40840c8521f7f94cc3275eb8075b07 (patch)
treed4029da9e8ba72e7eefdab569014a6744aabe02e
parentac9d350897a5a6fec7b0e10cc421dc9a0aa995eb (diff)
Add paging of large data files
Loading a large (100,000+ entry) data file can take a very long time, and is quite annoying to wait for. This patch breaks the data up into pages (10,000 rows per page). Then it lets the user move about the pages with a scroll button. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--Makefile2
-rw-r--r--trace-filter.c1
-rw-r--r--trace-view-store.c103
-rw-r--r--trace-view-store.h59
-rw-r--r--trace-view.c72
5 files changed, 205 insertions, 32 deletions
diff --git a/Makefile b/Makefile
index 8d4e48d..d01856a 100644
--- a/Makefile
+++ b/Makefile
@@ -22,7 +22,7 @@ all: $(TARGETS)
22 22
23LIB_FILE = libtracecmd.a 23LIB_FILE = libtracecmd.a
24 24
25HEADERS = parse-events.h trace-cmd.h trace-local.h 25HEADERS = parse-events.h trace-cmd.h trace-local.h trace-view-store.h
26 26
27trace-read.o:: $(HEADERS) 27trace-read.o:: $(HEADERS)
28trace-cmd.o:: $(HEADERS) $(LIB_FILE) 28trace-cmd.o:: $(HEADERS) $(LIB_FILE)
diff --git a/trace-filter.c b/trace-filter.c
index 8d6fced..b7d8176 100644
--- a/trace-filter.c
+++ b/trace-filter.c
@@ -347,6 +347,7 @@ void trace_filter_cpu_dialog(void *trace_tree)
347 347
348 cpu_helper->allcpus = allset; 348 cpu_helper->allcpus = allset;
349 cpu_helper->cpu_mask = g_new0(guint64, (cpus >> 6) + 1); 349 cpu_helper->cpu_mask = g_new0(guint64, (cpus >> 6) + 1);
350 g_assert(cpu_helper->cpu_mask != NULL);
350 351
351 gtk_widget_show(check); 352 gtk_widget_show(check);
352 353
diff --git a/trace-view-store.c b/trace-view-store.c
index b65e6a3..3192b2b 100644
--- a/trace-view-store.c
+++ b/trace-view-store.c
@@ -177,6 +177,15 @@ trace_view_store_init (TraceViewStore *trace_view_store)
177 trace_view_store->num_rows = 0; 177 trace_view_store->num_rows = 0;
178 trace_view_store->rows = NULL; 178 trace_view_store->rows = NULL;
179 179
180 trace_view_store->spin = NULL;
181 trace_view_store->page = 1;
182 trace_view_store->pages = 1;
183 trace_view_store->rows_per_page = TRACE_VIEW_DEFAULT_MAX_ROWS;
184 trace_view_store->num_rows = 0;
185 trace_view_store->start_row = 0;
186 trace_view_store->visible_rows = 0;
187 trace_view_store->actual_rows = 0;
188
180 /* Set all columns visible */ 189 /* Set all columns visible */
181 trace_view_store->visible_column_mask = (1 << TRACE_VIEW_STORE_N_COLUMNS) - 1; 190 trace_view_store->visible_column_mask = (1 << TRACE_VIEW_STORE_N_COLUMNS) - 1;
182 191
@@ -195,11 +204,14 @@ trace_view_store_init (TraceViewStore *trace_view_store)
195static void 204static void
196trace_view_store_finalize (GObject *object) 205trace_view_store_finalize (GObject *object)
197{ 206{
198/* TraceViewStore *trace_view_store = TRACE_VIEW_STORE(object); */ 207 TraceViewStore *store = TRACE_VIEW_STORE(object);
199 208
200 /* free all records and free all memory used by the list */ 209 /* free all records and free all memory used by the list */
201#warning IMPLEMENT 210#warning IMPLEMENT
202 211
212 if (store->spin)
213 g_object_unref(store->spin);
214
203 /* must chain up - finalize parent */ 215 /* must chain up - finalize parent */
204 (* parent_class->finalize) (object); 216 (* parent_class->finalize) (object);
205} 217}
@@ -303,7 +315,7 @@ trace_view_store_get_iter (GtkTreeModel *tree_model,
303{ 315{
304 TraceViewStore *trace_view_store; 316 TraceViewStore *trace_view_store;
305 TraceViewRecord *record; 317 TraceViewRecord *record;
306 gint *indices, n, depth; 318 gint *indices, n, depth, pos;
307 319
308 g_assert(TRACE_VIEW_IS_LIST(tree_model)); 320 g_assert(TRACE_VIEW_IS_LIST(tree_model));
309 g_assert(path!=NULL); 321 g_assert(path!=NULL);
@@ -321,10 +333,13 @@ trace_view_store_get_iter (GtkTreeModel *tree_model,
321 if ( n >= trace_view_store->num_rows || n < 0 ) 333 if ( n >= trace_view_store->num_rows || n < 0 )
322 return FALSE; 334 return FALSE;
323 335
324 record = trace_view_store->rows[n]; 336 record = trace_view_store->rows[trace_view_store->start_row + n];
325 337
326 g_assert(record != NULL); 338 g_assert(record != NULL);
327 g_assert(record->pos == n); 339
340 pos = record->pos - trace_view_store->start_row;
341
342 g_assert(pos == n);
328 343
329 /* We simply store a pointer to our custom record in the iter */ 344 /* We simply store a pointer to our custom record in the iter */
330 iter->stamp = trace_view_store->stamp; 345 iter->stamp = trace_view_store->stamp;
@@ -388,7 +403,7 @@ trace_view_store_get_value (GtkTreeModel *tree_model,
388 const gchar *comm; 403 const gchar *comm;
389 gchar *str; 404 gchar *str;
390 guint64 secs, usecs; 405 guint64 secs, usecs;
391 gint val; 406 gint val, pos;
392 int cpu; 407 int cpu;
393 408
394 g_return_if_fail (TRACE_VIEW_IS_LIST (tree_model)); 409 g_return_if_fail (TRACE_VIEW_IS_LIST (tree_model));
@@ -405,7 +420,9 @@ trace_view_store_get_value (GtkTreeModel *tree_model,
405 420
406 g_return_if_fail ( record != NULL ); 421 g_return_if_fail ( record != NULL );
407 422
408 if(record->pos >= trace_view_store->num_rows) 423 pos = record->pos - trace_view_store->start_row;
424
425 if(pos >= trace_view_store->num_rows)
409 g_return_if_reached(); 426 g_return_if_reached();
410 427
411 column = get_visible_column(TRACE_VIEW_STORE(tree_model), column); 428 column = get_visible_column(TRACE_VIEW_STORE(tree_model), column);
@@ -433,6 +450,7 @@ trace_view_store_get_value (GtkTreeModel *tree_model,
433 case TRACE_VIEW_STORE_COL_INFO: 450 case TRACE_VIEW_STORE_COL_INFO:
434 451
435 data = tracecmd_read_at(trace_view_store->handle, record->offset, &cpu); 452 data = tracecmd_read_at(trace_view_store->handle, record->offset, &cpu);
453 g_assert(data != NULL);
436 if (cpu != record->cpu) { 454 if (cpu != record->cpu) {
437 free(data); 455 free(data);
438 return; 456 return;
@@ -490,6 +508,7 @@ trace_view_store_iter_next (GtkTreeModel *tree_model,
490{ 508{
491 TraceViewRecord *record, *nextrecord; 509 TraceViewRecord *record, *nextrecord;
492 TraceViewStore *trace_view_store; 510 TraceViewStore *trace_view_store;
511 gint pos;
493 512
494 g_return_val_if_fail (TRACE_VIEW_IS_LIST (tree_model), FALSE); 513 g_return_val_if_fail (TRACE_VIEW_IS_LIST (tree_model), FALSE);
495 514
@@ -500,8 +519,10 @@ trace_view_store_iter_next (GtkTreeModel *tree_model,
500 519
501 record = (TraceViewRecord *) iter->user_data; 520 record = (TraceViewRecord *) iter->user_data;
502 521
522 pos = record->pos - trace_view_store->start_row;
523
503 /* Is this the last record in the list? */ 524 /* Is this the last record in the list? */
504 if ((record->pos + 1) >= trace_view_store->num_rows) 525 if ((pos + 1) >= trace_view_store->num_rows)
505 return FALSE; 526 return FALSE;
506 527
507 nextrecord = trace_view_store->rows[(record->pos + 1)]; 528 nextrecord = trace_view_store->rows[(record->pos + 1)];
@@ -638,10 +659,10 @@ trace_view_store_iter_nth_child (GtkTreeModel *tree_model,
638 if( n >= trace_view_store->num_rows ) 659 if( n >= trace_view_store->num_rows )
639 return FALSE; 660 return FALSE;
640 661
641 record = trace_view_store->rows[n]; 662 record = trace_view_store->rows[trace_view_store->start_row + n];
642 663
643 g_assert( record != NULL ); 664 g_assert( record != NULL );
644 g_assert( record->pos == n ); 665 g_assert( record->pos - trace_view_store->start_row == n );
645 666
646 iter->stamp = trace_view_store->stamp; 667 iter->stamp = trace_view_store->stamp;
647 iter->user_data = record; 668 iter->user_data = record;
@@ -702,6 +723,15 @@ static void mask_set_cpus(TraceViewStore *store, gint cpus)
702 *(store->cpu_mask) = (1ULL << (cpus & ((1ULL << 6) - 1))) - 1; 723 *(store->cpu_mask) = (1ULL << (cpus & ((1ULL << 6) - 1))) - 1;
703} 724}
704 725
726static void update_page(TraceViewStore *store)
727{
728 if (!store->spin)
729 return;
730
731 gtk_spin_button_set_range(GTK_SPIN_BUTTON(store->spin),
732 1, store->pages);
733}
734
705/***************************************************************************** 735/*****************************************************************************
706 * 736 *
707 * merge_sort_rows_ts: Merge sort the data by time stamp. 737 * merge_sort_rows_ts: Merge sort the data by time stamp.
@@ -752,7 +782,27 @@ static void merge_sort_rows_ts(TraceViewStore *store)
752 } 782 }
753 } while (next >= 0); 783 } while (next >= 0);
754 784
755 store->num_rows = count; 785 store->visible_rows = count;
786 store->start_row = 0;
787 store->pages = (count / store->rows_per_page) + 1;
788
789 if (store->page > 1) {
790 if (count < store->page * store->rows_per_page)
791 store->page = store->pages;
792
793 /* still greater? */
794 if (store->page > 1) {
795 store->start_row =
796 (store->page - 1) * store->rows_per_page;
797 g_assert(store->start_row < count);
798 }
799 }
800
801 store->num_rows = count > (store->start_row + store->rows_per_page) ?
802 store->rows_per_page :
803 count - store->start_row;
804
805 update_page(store);
756 806
757 g_free(indexes); 807 g_free(indexes);
758} 808}
@@ -826,6 +876,8 @@ trace_view_store_new (struct tracecmd_input *handle)
826 rec = list; 876 rec = list;
827 877
828 trec = g_new(TraceViewRecord, count); 878 trec = g_new(TraceViewRecord, count);
879 g_assert(trec != NULL);
880
829 for (i = 0; i < count; i++) { 881 for (i = 0; i < count; i++) {
830 g_assert(rec != NULL); 882 g_assert(rec != NULL);
831 trec[i].cpu = cpu; 883 trec[i].cpu = cpu;
@@ -848,13 +900,29 @@ trace_view_store_new (struct tracecmd_input *handle)
848 total += count; 900 total += count;
849 } 901 }
850 902
851 newstore->rows = g_malloc(sizeof(*newstore->rows) * total); 903 newstore->actual_rows = total;
904 newstore->rows = g_malloc(sizeof(*newstore->rows) * total + 1);
852 905
853 merge_sort_rows_ts(newstore); 906 merge_sort_rows_ts(newstore);
854 907
855 return newstore; 908 return newstore;
856} 909}
857 910
911void trace_view_store_set_spin_button(TraceViewStore *store, GtkWidget *spin)
912{
913 g_return_if_fail (TRACE_VIEW_IS_LIST (store));
914 g_return_if_fail (GTK_IS_SPIN_BUTTON (spin));
915
916 store->spin = spin;
917
918 gtk_spin_button_set_increments(GTK_SPIN_BUTTON(store->spin),
919 1.0, 5.0);
920
921 update_page(store);
922
923 g_object_ref(spin);
924}
925
858/* --- helper functions --- */ 926/* --- helper functions --- */
859 927
860gboolean trace_view_store_cpu_isset(TraceViewStore *store, gint cpu) 928gboolean trace_view_store_cpu_isset(TraceViewStore *store, gint cpu)
@@ -907,6 +975,19 @@ void trace_view_store_clear_cpu(TraceViewStore *store, gint cpu)
907 merge_sort_rows_ts(store); 975 merge_sort_rows_ts(store);
908} 976}
909 977
978void trace_view_store_set_page(TraceViewStore *store, gint page)
979{
980 g_return_if_fail (TRACE_VIEW_IS_LIST (store));
981 g_return_if_fail (page >= 0 || page < store->pages);
982
983 store->page = page;
984 store->start_row = (page - 1) * store->rows_per_page;
985 g_assert(store->start_row < store->visible_rows);
986 store->num_rows = store->start_row + store->rows_per_page <
987 store->visible_rows ? store->rows_per_page :
988 store->visible_rows - store->start_row;
989}
990
910 991
911/***************************************************************************** 992/*****************************************************************************
912 * 993 *
diff --git a/trace-view-store.h b/trace-view-store.h
index 8440888..9dbbb5a 100644
--- a/trace-view-store.h
+++ b/trace-view-store.h
@@ -62,7 +62,10 @@ struct _TraceViewStore
62{ 62{
63 GObject parent; /* this MUST be the first member */ 63 GObject parent; /* this MUST be the first member */
64 64
65 guint num_rows; /* number of rows that we have */ 65 guint start_row; /* row to start at */
66 guint num_rows; /* number of rows that we have showing */
67 guint visible_rows; /* number of rows defined */
68 guint actual_rows; /* size of rows array */
66 TraceViewRecord **rows; /* a dynamically allocated array of pointers to 69 TraceViewRecord **rows; /* a dynamically allocated array of pointers to
67 * the TraceViewRecord structure for each row */ 70 * the TraceViewRecord structure for each row */
68 71
@@ -78,6 +81,11 @@ struct _TraceViewStore
78 TraceViewRecord **cpu_list; 81 TraceViewRecord **cpu_list;
79 gint *cpu_items; 82 gint *cpu_items;
80 83
84 gint page;
85 gint pages;
86 gint rows_per_page;
87 GtkWidget *spin;
88
81 /* filters */ 89 /* filters */
82 gint all_events; /* set 1 when all events are enabled */ 90 gint all_events; /* set 1 when all events are enabled */
83 /* else */ 91 /* else */
@@ -91,29 +99,15 @@ struct _TraceViewStore
91 gint stamp; /* Random integer to check whether an iter belongs to our model */ 99 gint stamp; /* Random integer to check whether an iter belongs to our model */
92}; 100};
93 101
94/* helper functions */
95
96static inline gint trace_view_store_get_cpus(TraceViewStore *store)
97{
98 return store->cpus;
99}
100
101static inline guint64 *trace_view_store_get_cpu_mask(TraceViewStore *store)
102{
103 return store->cpu_mask;
104}
105
106static inline gint trace_view_store_get_all_cpus(TraceViewStore *store)
107{
108 return store->all_cpus;
109}
110
111gboolean trace_view_store_cpu_isset(TraceViewStore *store, gint cpu); 102gboolean trace_view_store_cpu_isset(TraceViewStore *store, gint cpu);
112 103
113void trace_view_store_set_all_cpus(TraceViewStore *store); 104void trace_view_store_set_all_cpus(TraceViewStore *store);
114void trace_view_store_set_cpu(TraceViewStore *store, gint cpu); 105void trace_view_store_set_cpu(TraceViewStore *store, gint cpu);
115void trace_view_store_clear_cpu(TraceViewStore *store, gint cpu); 106void trace_view_store_clear_cpu(TraceViewStore *store, gint cpu);
116 107
108void trace_view_store_set_spin_button(TraceViewStore *store, GtkWidget *spin);
109
110void trace_view_store_set_page(TraceViewStore *store, gint page);
117 111
118/* TraceViewStoreClass: more boilerplate GObject stuff */ 112/* TraceViewStoreClass: more boilerplate GObject stuff */
119 113
@@ -127,10 +121,39 @@ GType trace_view_store_get_type (void);
127 121
128TraceViewStore *trace_view_store_new (struct tracecmd_input *handle); 122TraceViewStore *trace_view_store_new (struct tracecmd_input *handle);
129 123
124#define TRACE_VIEW_DEFAULT_MAX_ROWS 10000
125
130#if 0 126#if 0
131void trace_view_store_append_record (TraceViewStore *trace_view_store, 127void trace_view_store_append_record (TraceViewStore *trace_view_store,
132 const gchar *name, 128 const gchar *name,
133 guint year_born); 129 guint year_born);
134#endif 130#endif
135 131
132
133/* helper functions */
134
135static inline gint trace_view_store_get_cpus(TraceViewStore *store)
136{
137 g_return_val_if_fail (TRACE_VIEW_IS_LIST (store), -1);
138 return store->cpus;
139}
140
141static inline guint64 *trace_view_store_get_cpu_mask(TraceViewStore *store)
142{
143 g_return_val_if_fail (TRACE_VIEW_IS_LIST (store), NULL);
144 return store->cpu_mask;
145}
146
147static inline gint trace_view_store_get_all_cpus(TraceViewStore *store)
148{
149 g_return_val_if_fail (TRACE_VIEW_IS_LIST (store), -1);
150 return store->all_cpus;
151}
152
153static inline gint trace_view_store_get_page(TraceViewStore *store)
154{
155 g_return_val_if_fail (TRACE_VIEW_IS_LIST (store), -1);
156 return store->page;
157}
158
136#endif /* _trace_view_store_h_included_ */ 159#endif /* _trace_view_store_h_included_ */
diff --git a/trace-view.c b/trace-view.c
index ac71c7c..555f1aa 100644
--- a/trace-view.c
+++ b/trace-view.c
@@ -80,6 +80,44 @@ cpus_clicked (gpointer data)
80 trace_filter_cpu_dialog(trace_tree); 80 trace_filter_cpu_dialog(trace_tree);
81} 81}
82 82
83#if 0
84static GtkTreeModel *
85create_combo_box_model(void)
86{
87 GtkListStore *store;
88 GtkTreeIter iter;
89
90 store = gtk_list_store_new(1, G_TYPE_STRING);
91 gtk_list_store_append(store, &iter);
92 gtk_list_store_set(store, &iter, 0, "1", -1);
93
94 return GTK_TREE_MODEL(store);
95}
96#endif
97
98static void
99spin_changed(gpointer data, GtkWidget *spin)
100{
101 GtkTreeView *tree = data;
102 GtkTreeModel *model;
103 gint val, page;
104
105 val = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin));
106
107 model = gtk_tree_view_get_model(tree);
108 page = trace_view_store_get_page(TRACE_VIEW_STORE(model));
109 if (page == val)
110 return;
111
112 g_object_ref(model);
113 gtk_tree_view_set_model(tree, NULL);
114
115 trace_view_store_set_page(TRACE_VIEW_STORE(model), val);
116
117 gtk_tree_view_set_model(tree, model);
118 g_object_unref(model);
119}
120
83static GtkTreeModel * 121static GtkTreeModel *
84create_trace_view_model(struct tracecmd_input *handle) 122create_trace_view_model(struct tracecmd_input *handle)
85{ 123{
@@ -91,7 +129,8 @@ create_trace_view_model(struct tracecmd_input *handle)
91} 129}
92 130
93static void 131static void
94load_trace_view(GtkWidget *view, struct tracecmd_input *handle) 132load_trace_view(GtkWidget *view, struct tracecmd_input *handle,
133 GtkWidget *spin)
95{ 134{
96 GtkTreeViewColumn *col; 135 GtkTreeViewColumn *col;
97 GtkCellRenderer *renderer; 136 GtkCellRenderer *renderer;
@@ -155,6 +194,9 @@ load_trace_view(GtkWidget *view, struct tracecmd_input *handle)
155 194
156 model = create_trace_view_model(handle); 195 model = create_trace_view_model(handle);
157 196
197 trace_view_store_set_spin_button(TRACE_VIEW_STORE(model), spin);
198 g_object_unref(spin);
199
158 gtk_tree_view_set_model(GTK_TREE_VIEW(view), model); 200 gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
159 201
160 g_object_unref(model); /* destroy model automatically with view */ 202 g_object_unref(model); /* destroy model automatically with view */
@@ -171,6 +213,8 @@ void trace_view(int argc, char **argv)
171 GtkWidget *menu_item; 213 GtkWidget *menu_item;
172 GtkWidget *sub_item; 214 GtkWidget *sub_item;
173 GtkWidget *scrollwin; 215 GtkWidget *scrollwin;
216 GtkWidget *label;
217 GtkWidget *spin;
174 218
175 handle = read_trace_header(); 219 handle = read_trace_header();
176 if (!handle) 220 if (!handle)
@@ -279,6 +323,29 @@ void trace_view(int argc, char **argv)
279 /* --- End Filter Options --- */ 323 /* --- End Filter Options --- */
280 gtk_menu_item_set_submenu(GTK_MENU_ITEM (menu_item), menu); 324 gtk_menu_item_set_submenu(GTK_MENU_ITEM (menu_item), menu);
281 325
326
327 /* --- Paging Hbox --- */
328
329 hbox = gtk_hbox_new(FALSE, 0);
330 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
331 gtk_widget_show(hbox);
332
333 /* --- Page Spin Button --- */
334
335 label = gtk_label_new("Page");
336 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
337 gtk_widget_show(label);
338
339 spin = gtk_spin_button_new(NULL, 1.0, 0);
340 gtk_spin_button_set_range(GTK_SPIN_BUTTON(spin), 1, 1);
341 gtk_box_pack_start(GTK_BOX(hbox), spin, FALSE, FALSE, 0);
342 gtk_widget_show(spin);
343
344 g_signal_connect_swapped (G_OBJECT (spin), "value-changed",
345 G_CALLBACK (spin_changed),
346 (gpointer) trace_tree);
347
348
282 /* --- Top Level Hbox --- */ 349 /* --- Top Level Hbox --- */
283 350
284 hbox = gtk_hbox_new(FALSE, 0); 351 hbox = gtk_hbox_new(FALSE, 0);
@@ -295,7 +362,8 @@ void trace_view(int argc, char **argv)
295 362
296 /* --- Set up Trace Tree --- */ 363 /* --- Set up Trace Tree --- */
297 364
298 load_trace_view(trace_tree, handle); 365 load_trace_view(trace_tree, handle, spin);
366
299 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollwin), 367 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollwin),
300 trace_tree); 368 trace_tree);
301 gtk_widget_show(trace_tree); 369 gtk_widget_show(trace_tree);