We already set the foreground and background color for every frame,

which means we're already doing a "do something to the last row in the
packet list" operation on every frame we add to the list, so adding a
call to "gtk_clist_set_row_data()" won't make matters worse.

In addition, we already set one column in a row on a "change time
format" operation, so finding the row for a frame by calling
"gtk_clist_find_row_from_data()" doesn't turn a constant-time operation
into a linear-time operation, it just cranks the proportionality
constant up - it was quadratic before, alas, and it's still quadratic.

Adding calls to "gtk_clist_find_row_from_data()" to the "Find Frame" and
"Go To Frame" code does add an extra linear operation there, but those
operations shouldn't be common - and "Go To Frame", going to the last
frame on an ~100,000-frame big capture file, was quick, at least on my
450 MHz Pentium II machine, so maybe it won't be too bad.

And "select_packet()" either has to search the frame table for the frame
with the specified row number, or has to call "gtk_clist_get_row_data()"
to do that - the first is linear in the position of the frame in the
frame table, and the latter is linear in its position in the CList, and
the latter is less than or equal to the former, so the only thing making
it worse would be a change in the proportionality constant.

So it probably won't hurt performance by much.

Furthermore, if we add the ability to sort the display on an arbitrary
column, or to delete frames from the display - both of which are in the
wish list - storing the row number of the frame in the "frame_data"
structure won't necessarily work, as the row number can change out from
under us.

Therefore, reinstate the old way of doing things, where we associate
with each row a pointer to the "frame_data" structure for the row, using
"gtk_clist_set_row_data()".

svn path=/trunk/; revision=1703
This commit is contained in:
Guy Harris 2000-03-08 06:48:01 +00:00
parent dc8fa8baf3
commit 050979d522
3 changed files with 47 additions and 58 deletions

93
file.c
View File

@ -1,7 +1,7 @@
/* file.c
* File I/O routines
*
* $Id: file.c,v 1.168 2000/02/29 06:24:15 guy Exp $
* $Id: file.c,v 1.169 2000/03/08 06:47:50 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -423,9 +423,12 @@ continue_tail_cap_file(capture_file *cf, int to_read)
wtap_loop(cf->wth, to_read, wtap_dispatch_cb, (u_char *) cf, &err);
gtk_clist_thaw(GTK_CLIST(packet_list));
/* XXX - this cheats and looks inside the packet list to find the final
row number. */
if (auto_scroll_live && cf->plist_end != NULL)
gtk_clist_moveto(GTK_CLIST(packet_list),
cf->plist_end->row, -1, 1.0, 1.0);
GTK_CLIST(packet_list)->rows - 1, -1, 1.0, 1.0);
return err;
}
@ -440,8 +443,10 @@ finish_tail_cap_file(capture_file *cf)
thaw_clist(cf);
if (auto_scroll_live && cf->plist_end != NULL)
/* XXX - this cheats and looks inside the packet list to find the final
row number. */
gtk_clist_moveto(GTK_CLIST(packet_list),
cf->plist_end->row, -1, 1.0, 1.0);
GTK_CLIST(packet_list)->rows - 1, -1, 1.0, 1.0);
/* Set the file encapsulation type now; we don't know what it is until
we've looked at all the packets, as we don't know until then whether
@ -557,32 +562,6 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf, const u_char *buf
}
if (fdata->passed_dfilter) {
/* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
the first entry is added to it by "real_insert_row()", that row
is selected (see "real_insert_row()", in "gtk/gtkclist.c", in both
our version and the vanilla GTK+ version).
This means that a "select-row" signal is emitted; this causes
"packet_list_select_cb()" to be called, which causes "select_packet()"
to be called.
"select_packet()" searches the list of frames for a frame with the
row number passed into it; however, as "gtk_clist_append()", which
called "real_insert_row()", hasn't yet returned, we don't know what
the row number is, so we can't correctly set "fd->row" for that frame
yet.
This means that we won't find the frame for that row.
We can't assume that there's only one frame in the frame list,
either, as we may be filtering the display.
Therefore, we set "fdata->row" to 0, under the assumption that
the row number passed to "select_packet()" will be 0 (as we're
adding the first row to the list; it gets set to the proper
value later. */
fdata->row = 0;
/* If we don't have the time stamp of the previous displayed packet,
it's because this is the first displayed packet. Save the time
stamp of this packet as the time stamp of the previous displayed
@ -611,7 +590,7 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf, const u_char *buf
fill_in_columns(fdata);
row = gtk_clist_append(GTK_CLIST(packet_list), fdata->cinfo->col_data);
fdata->row = row;
gtk_clist_set_row_data(GTK_CLIST(packet_list), row, fdata);
if (filter_list != NULL && (args.colorf != NULL)) {
gtk_clist_set_background(GTK_CLIST(packet_list), row,
@ -634,8 +613,7 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf, const u_char *buf
we can arrange that it's on the screen when we're done. */
if (cf->current_frame == fdata)
cf->current_row = row;
} else
fdata->row = -1; /* not in the display */
}
fdata->cinfo = NULL;
}
@ -1051,6 +1029,7 @@ void
change_time_formats(capture_file *cf)
{
frame_data *fd;
int row;
int i;
GtkStyle *pl_style;
@ -1063,8 +1042,11 @@ change_time_formats(capture_file *cf)
any columns that show the time in the "command-line-specified"
format and, if so, update that row. */
for (fd = cf->plist; fd != NULL; fd = fd->next) {
if (fd->row != -1) {
/* This packet is in the summary list, on row "fd->row". */
/* Find what row this packet is in. */
row = gtk_clist_find_row_from_data(GTK_CLIST(packet_list), fd);
if (row != -1) {
/* This packet is in the summary list, on row "row". */
/* XXX - there really should be a way of checking "cf->cinfo" for this;
the answer isn't going to change from packet to packet, so we should
@ -1080,7 +1062,7 @@ change_time_formats(capture_file *cf)
"command-line-specified" format; update it. */
cf->cinfo.col_data[i][0] = '\0';
col_set_cls_time(fd, i);
gtk_clist_set_text(GTK_CLIST(packet_list), fd->row, i,
gtk_clist_set_text(GTK_CLIST(packet_list), row, i,
cf->cinfo.col_data[i]);
}
}
@ -1127,6 +1109,7 @@ find_packet(capture_file *cf, dfilter *sfcode)
guint32 progbar_nextstep;
int count;
proto_tree *protocol_tree;
int row;
start_fd = cf->current_frame;
if (start_fd != NULL) {
@ -1206,9 +1189,13 @@ find_packet(capture_file *cf, dfilter *sfcode)
}
if (new_fd != NULL) {
/* We found a frame. Make it visible, and select it. */
if (!gtk_clist_row_is_visible(GTK_CLIST(packet_list), new_fd->row))
gtk_clist_moveto(GTK_CLIST(packet_list), new_fd->row, -1, 0.0, 0.0);
/* We found a frame. Find what row it's in. */
row = gtk_clist_find_row_from_data(GTK_CLIST(packet_list), new_fd);
g_assert(row != -1);
/* Make it visible, and select it. */
if (!gtk_clist_row_is_visible(GTK_CLIST(packet_list), row))
gtk_clist_moveto(GTK_CLIST(packet_list), row, -1, 0.0, 0.0);
/* XXX - why is there no "gtk_clist_set_focus_row()", so that we
can make the row for the frame we found the focus row?
@ -1218,8 +1205,8 @@ find_packet(capture_file *cf, dfilter *sfcode)
http://www.gnome.org/mailing-lists/archives/gtk-list/2000-January/0038.shtml
*/
GTK_CLIST(packet_list)->focus_row = new_fd->row;
gtk_clist_select_row(GTK_CLIST(packet_list), new_fd->row, -1);
GTK_CLIST(packet_list)->focus_row = row;
gtk_clist_select_row(GTK_CLIST(packet_list), row, -1);
return TRUE; /* success */
} else
return FALSE; /* failure */
@ -1229,6 +1216,7 @@ goto_result_t
goto_frame(capture_file *cf, guint fnumber)
{
frame_data *fd;
int row;
for (fd = cf->plist; fd != NULL && fd->num < fnumber; fd = fd->next)
;
@ -1239,13 +1227,17 @@ goto_frame(capture_file *cf, guint fnumber)
return FRAME_NOT_DISPLAYED; /* the frame with that number isn't displayed */
/* We found that frame, and it's currently being displayed.
Make it visible, and select it. */
if (!gtk_clist_row_is_visible(GTK_CLIST(packet_list), fd->row))
gtk_clist_moveto(GTK_CLIST(packet_list), fd->row, -1, 0.0, 0.0);
Find what row it's in. */
row = gtk_clist_find_row_from_data(GTK_CLIST(packet_list), fd);
g_assert(row != -1);
/* Make it visible, and select it. */
if (!gtk_clist_row_is_visible(GTK_CLIST(packet_list), row))
gtk_clist_moveto(GTK_CLIST(packet_list), row, -1, 0.0, 0.0);
/* See above complaint about the lack of "gtk_clist_set_focus_row()". */
GTK_CLIST(packet_list)->focus_row = fd->row;
gtk_clist_select_row(GTK_CLIST(packet_list), fd->row, -1);
GTK_CLIST(packet_list)->focus_row = row;
gtk_clist_select_row(GTK_CLIST(packet_list), row, -1);
return FOUND_FRAME;
}
@ -1254,16 +1246,9 @@ void
select_packet(capture_file *cf, int row)
{
frame_data *fd;
int i;
/* Search through the list of frames to see which one is in
this row. */
for (fd = cf->plist, i = 0; fd != NULL; fd = fd->next, i++) {
if (fd->row == row)
break;
}
g_assert(fd != NULL);
/* Get the frame data struct pointer for this frame */
fd = (frame_data *) gtk_clist_get_row_data(GTK_CLIST(packet_list), row);
/* Record that this frame is the current frame, and that it's selected. */
cf->current_frame = fd;

View File

@ -3,7 +3,7 @@
*
* Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
*
* $Id: packet_win.c,v 1.3 2000/03/02 07:05:57 guy Exp $
* $Id: packet_win.c,v 1.4 2000/03/08 06:48:01 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -98,6 +98,7 @@ void new_window_cb(GtkWidget *w){
#define NewWinTitleLen 1000
int row;
gint tv_size = 95, bv_size = 75;
int i;
char Title[ NewWinTitleLen] = "";
@ -105,10 +106,14 @@ void new_window_cb(GtkWidget *w){
/* build title of window by getting */
/* data from the packet_list GtkCList */
/* Find what row this packet is in. */
row = gtk_clist_find_row_from_data(GTK_CLIST(packet_list),
cf.current_frame);
g_assert(row != -1);
for( i = 0; i < cf.cinfo.num_cols; ++i){
if ( gtk_clist_get_text(GTK_CLIST( packet_list),
cf.current_frame->row, i, &TextPtr)){
row, i, &TextPtr)){
if (( strlen( Title) + strlen( TextPtr))
< ( NewWinTitleLen - 1)){

View File

@ -1,7 +1,7 @@
/* packet.h
* Definitions for packet disassembly structures and routines
*
* $Id: packet.h,v 1.173 2000/02/18 13:41:26 oabad Exp $
* $Id: packet.h,v 1.174 2000/03/08 06:47:51 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -134,7 +134,6 @@ typedef struct _frame_data {
guint32 del_usecs; /* Delta microseconds */
long file_off; /* File offset */
column_info *cinfo; /* Column formatting information */
gint row; /* Row number for this packet in the display */
int lnk_t; /* Per-packet encapsulation/data-link type */
gboolean passed_dfilter; /* TRUE = display, FALSE = no display */
char_enc encoding; /* Character encoding (ASCII, EBCDIC...) */