Make the packet count an unsigned value, as frame numbers are unsigned.
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 25 Apr 2011 05:33:07 +0000 (05:33 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 25 Apr 2011 05:33:07 +0000 (05:33 +0000)
Make the loops that scan through all the packets do so by frame number,
to abstract away the "next" and "previous" pointers in the frame_data
structure.  Add a routine to cfile.c to map frame numbers to frame_data
structures, and put in some special case handling so scanning forward or
backward through the packets is O(N) rather than O(N^2).

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@36846 f5534014-38df-0310-8fa8-9805f1628bb7

cfile.c
cfile.h
file.c
gtk/new_packet_list.c
summary.c

diff --git a/cfile.c b/cfile.c
index 89ab953d40bf1b5abff1926fc20184e5ff4b4e20..d993e7ab84b249ce313a99f444582392d1522024 100644 (file)
--- a/cfile.c
+++ b/cfile.c
@@ -37,19 +37,21 @@ void
 cap_file_init(capture_file *cf)
 {
   /* Initialize the capture file struct */
-  cf->plist_start   = NULL;
-  cf->plist_end     = NULL;
-  cf->wth           = NULL;
-  cf->filename      = NULL;
-  cf->source        = NULL;
-  cf->user_saved    = FALSE;
-  cf->is_tempfile   = FALSE;
-  cf->rfcode        = NULL;
-  cf->dfilter       = NULL;
-  cf->has_snap      = FALSE;
-  cf->snap          = WTAP_MAX_PACKET_SIZE;
-  cf->count         = 0;
-  cf->redissecting  = FALSE;
+  cf->plist_start    = NULL;
+  cf->plist_end      = NULL;
+  cf->wth            = NULL;
+  cf->filename       = NULL;
+  cf->source         = NULL;
+  cf->user_saved     = FALSE;
+  cf->is_tempfile    = FALSE;
+  cf->rfcode         = NULL;
+  cf->dfilter        = NULL;
+  cf->has_snap       = FALSE;
+  cf->snap           = WTAP_MAX_PACKET_SIZE;
+  cf->count          = 0;
+  cf->last_found_num = 0;
+  cf->last_found_fd  = NULL;
+  cf->redissecting   = FALSE;
 }
 
 void
@@ -64,3 +66,71 @@ cap_file_add_fdata(capture_file *cf, frame_data *fdata)
   cf->plist_end = fdata;
 }
 
+/*
+ * Find the frame_data for the specified frame number.
+ * Do some caching to make this work reasonably fast for
+ * forward and backward sequential passes through the packets.
+ */
+frame_data *
+cap_file_find_fdata(capture_file *cf, guint32 num)
+{
+  frame_data *fdata;
+
+  if (num == 0) {
+    /* There is no frame number 0 */
+    return NULL;
+  }
+
+  /*
+   * Did we remember a frame number from a sequential pass through
+   * the frames?
+   */
+  if (cf->last_found_num != 0) {
+    /*
+     * Yes.  Is this that frame?
+     */
+    if (num == cf->last_found_num) {
+      /* Yes - return it. */
+      return cf->last_found_fd;
+    }
+
+    /*
+     * No.  Is it the frame just after that frame?
+     */
+    if (num == cf->last_found_num + 1) {
+      /*
+       * Yes - if there is such a frame, remember it and return it.
+       */
+      fdata = cf->last_found_fd->next;
+      if (fdata != NULL) {
+        cf->last_found_num = num;
+        cf->last_found_fd = fdata;
+      }
+      return fdata;    /* could be null, if there is no such frame */
+    }
+
+    /*
+     * No.  Is it the frame just before that frame?
+     */
+    if (num == cf->last_found_num - 1) {
+      /*
+       * Yes - if there is such a frame, remember it and return it.
+       */
+      fdata = cf->last_found_fd->prev;
+      if (fdata != NULL) {
+        cf->last_found_num = num;
+        cf->last_found_fd = fdata;
+      }
+      return fdata;    /* could be null, if there is no such frame */
+    }
+  }
+
+  for (fdata = cf->plist_start; fdata != NULL && fdata->num < num;
+       fdata = fdata->next)
+    ;
+  if (fdata != NULL) {
+    cf->last_found_num = num;
+    cf->last_found_fd = fdata;
+  }
+  return fdata;
+}
diff --git a/cfile.h b/cfile.h
index a54fddc0a0da2f4645b1bfa22bd2a2a5011d1b53..06bdc4e12093688e3effdb8532479b046176306a 100644 (file)
--- a/cfile.h
+++ b/cfile.h
@@ -55,11 +55,11 @@ typedef struct _capture_file {
   gint64       f_datalen;       /* Size of capture file data (uncompressed) */
   guint16      cd_t;            /* File type of capture file */
   int          lnk_t;           /* Link-layer type with which to save capture */
-  int          count;           /* Total number of frames */
-  int          displayed_count; /* Number of displayed frames */
-  int          marked_count;    /* Number of marked frames */
-  int          ignored_count;   /* Number of ignored frames */
-  int          ref_time_count;  /* Number of time referenced frames */
+  guint32      count;           /* Total number of frames */
+  guint32      displayed_count; /* Number of displayed frames */
+  guint32      marked_count;    /* Number of marked frames */
+  guint32      ignored_count;   /* Number of ignored frames */
+  guint32      ref_time_count;  /* Number of time referenced frames */
   gboolean     drops_known;     /* TRUE if we know how many packets were dropped */
   guint32      drops;           /* Dropped packets */
   nstime_t     elapsed_time;    /* Elapsed time */
@@ -96,6 +96,9 @@ typedef struct _capture_file {
   frame_data  *plist_end;       /* Last packet in list */
   frame_data  *first_displayed; /* First frame displayed */
   frame_data  *last_displayed;  /* Last frame displayed */
+  /* The next two are used to speed up frame number -> frame data searches */
+  guint32      last_found_num;  /* Frame number we last found */
+  frame_data  *last_found_fd;   /* The corresponding frame_data */
   column_info  cinfo;           /* Column formatting information */
   frame_data  *current_frame;   /* Frame data for current frame */
   gint         current_row;     /* Row number for current frame */
@@ -107,4 +110,11 @@ void cap_file_init(capture_file *cf);
 
 void cap_file_add_fdata(capture_file *cf, frame_data *fdata);
 
+/*
+ * Find the frame_data for the specified frame number.
+ * Do some caching to make this work reasonably fast for
+ * forward and backward sequential passes through the packets.
+ */
+extern frame_data *cap_file_find_fdata(capture_file *cf, guint32 num);
+
 #endif /* cfile.h */
diff --git a/file.c b/file.c
index 50c499e126d6e50d6827becfeba70cd22b844ef5..a1697e7a9464752cf59f14d3d253f1a052f7efd7 100644 (file)
--- a/file.c
+++ b/file.c
@@ -1636,7 +1636,8 @@ static void
 rescan_packets(capture_file *cf, const char *action, const char *action_item,
         gboolean refilter, gboolean redissect)
 {
-    /* Rescan packets new packet list */
+  /* Rescan packets new packet list */
+  guint32     framenum;
   frame_data *fdata;
   progdlg_t  *progbar = NULL;
   gboolean    stop_flag;
@@ -1742,7 +1743,9 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
 
   selected_frame_seen = FALSE;
 
-  for (fdata = cf->plist_start; fdata != NULL; fdata = fdata->next) {
+  for (framenum = 1; framenum <= cf->count; framenum++) {
+    fdata = cap_file_find_fdata(cf, framenum);
+
     /* Create the progress bar if necessary.
        We check on every iteration of the loop, so that it takes no
        longer than the standard time to create it (otherwise, for a
@@ -1855,7 +1858,8 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
        even though the user requested that the scan stop, and that
        would leave the user stuck with an Wireshark grinding on
        until it finishes.  Should we just stick them with that? */
-    for (; fdata != NULL; fdata = fdata->next) {
+    for (; framenum <= cf->count; framenum++) {
+      fdata = cap_file_find_fdata(cf, framenum);
       fdata->flags.visited = 0;
       frame_data_cleanup(fdata);
     }
@@ -1948,13 +1952,16 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
 static void
 ref_time_packets(capture_file *cf)
 {
+  guint32 framenum;
   frame_data *fdata;
 
   nstime_set_unset(&first_ts);
   nstime_set_unset(&prev_dis_ts);
   cum_bytes = 0;
 
-  for (fdata = cf->plist_start; fdata != NULL; fdata = fdata->next) {
+  for (framenum = 1; framenum <= cf->count; framenum++) {
+    fdata = cap_file_find_fdata(cf, framenum);
+
     /* just add some value here until we know if it is being displayed or not */
     fdata->cum_bytes = cum_bytes + fdata->pkt_len;
 
@@ -2031,6 +2038,7 @@ process_specified_packets(capture_file *cf, packet_range_t *range,
                          union wtap_pseudo_header *, const guint8 *, void *),
     void *callback_args)
 {
+  guint32 framenum;
   frame_data *fdata;
   union wtap_pseudo_header pseudo_header;
   guint8      pd[WTAP_MAX_PACKET_SIZE+1];
@@ -2061,9 +2069,11 @@ process_specified_packets(capture_file *cf, packet_range_t *range,
 
   packet_range_process_init(range);
 
-  /* Iterate through the list of packets, printing the packets that
+  /* Iterate through all the packets, printing the packets that
      were selected by the current display filter.  */
-  for (fdata = cf->plist_start; fdata != NULL; fdata = fdata->next) {
+  for (framenum = 1; framenum <= cf->count; framenum++) {
+    fdata = cap_file_find_fdata(cf, framenum);
+
     /* Create the progress bar if necessary.
        We check on every iteration of the loop, so that it takes no
        longer than the standard time to create it (otherwise, for a
@@ -3217,6 +3227,7 @@ find_packet(capture_file *cf,
             void *criterion, search_direction dir)
 {
   frame_data  *start_fd;
+  guint32      framenum;
   frame_data  *fdata;
   frame_data  *new_fd = NULL;
   progdlg_t   *progbar = NULL;
@@ -3237,7 +3248,7 @@ find_packet(capture_file *cf,
        picked, calling a routine to run the filter on the packet, see if
        it matches, and stop if so.  */
     count = 0;
-    fdata = start_fd;
+    framenum = start_fd->num;
 
     /* Update the progress bar when it gets to this value. */
     progbar_nextstep = 0;
@@ -3293,8 +3304,7 @@ find_packet(capture_file *cf,
       /* Go past the current frame. */
       if (dir == SD_BACKWARD) {
         /* Go on to the previous frame. */
-        fdata = fdata->prev;
-        if (fdata == NULL) {
+        if (framenum == 1) {
           /*
            * XXX - other apps have a bit more of a detailed message
            * for this, and instead of offering "OK" and "Cancel",
@@ -3306,30 +3316,32 @@ find_packet(capture_file *cf,
           if (prefs.gui_find_wrap)
           {
               statusbar_push_temporary_msg("Search reached the beginning. Continuing at end.");
-              fdata = cf->plist_end;    /* wrap around */
+              framenum = cf->count;     /* wrap around */
           }
           else
           {
               statusbar_push_temporary_msg("Search reached the beginning.");
-              fdata = start_fd;        /* stay on previous packet */
+              framenum = start_fd->num; /* stay on previous packet */
           }
-        }
+        } else
+          framenum--;
       } else {
         /* Go on to the next frame. */
-        fdata = fdata->next;
-        if (fdata == NULL) {
+        if (framenum == cf->count) {
           if (prefs.gui_find_wrap)
           {
               statusbar_push_temporary_msg("Search reached the end. Continuing at beginning.");
-              fdata = cf->plist_start;    /* wrap around */
+              framenum = 1;             /* wrap around */
           }
           else
           {
               statusbar_push_temporary_msg("Search reached the end.");
-              fdata = start_fd;     /* stay on previous packet */
+              framenum = start_fd->num; /* stay on previous packet */
           }
-        }
+        } else
+          framenum++;
       }
+      fdata = cap_file_find_fdata(cf, framenum);
 
       count++;
 
@@ -3388,8 +3400,7 @@ cf_goto_frame(capture_file *cf, guint fnumber)
 {
   frame_data *fdata;
 
-  for (fdata = cf->plist_start; fdata != NULL && fdata->num < fnumber; fdata = fdata->next)
-    ;
+  fdata = cap_file_find_fdata(cf, fnumber);
 
   if (fdata == NULL) {
     /* we didn't find a packet with that packet number */
index a43c84c356dde5bacbf5bf49f64de0a32d460173..74c08f5d4b6e45aa123145d8084f27cb7aad5c4e 100644 (file)
@@ -1492,8 +1492,10 @@ static void
 mark_all_displayed_frames(gboolean set)
 {
        /* XXX: we might need a progressbar here */
+       guint32 framenum;
        frame_data *fdata;
-       for (fdata = cfile.plist_start; fdata != NULL; fdata = fdata->next) {
+       for (framenum = 1; framenum <= cfile.count; framenum++) {
+               fdata = cap_file_find_fdata(&cfile, framenum);
                if( fdata->flags.passed_dfilter )
                        set_frame_mark(set, fdata);
        }
@@ -1517,8 +1519,10 @@ static void
 toggle_mark_all_displayed_frames()
 {
        /* XXX: we might need a progressbar here */
+       guint32 framenum;
        frame_data *fdata;
-       for (fdata = cfile.plist_start; fdata != NULL; fdata = fdata->next) {
+       for (framenum = 1; framenum <= cfile.count; framenum++) {
+               fdata = cap_file_find_fdata(&cfile, framenum);
                if( fdata->flags.passed_dfilter )
                        set_frame_mark(!fdata->flags.marked, fdata);
        }
@@ -1562,12 +1566,14 @@ new_packet_list_ignore_frame_cb(GtkWidget *w _U_, gpointer data _U_)
 static void
 ignore_all_displayed_frames(gboolean set)
 {
+       guint32 framenum;
        frame_data *fdata;
 
        /* XXX: we might need a progressbar here */
-       for (fdata = cfile.plist_start; fdata != NULL; fdata = fdata->next) {
+       for (framenum = 1; framenum <= cfile.count; framenum++) {
+               fdata = cap_file_find_fdata(&cfile, framenum);
                if( fdata->flags.passed_dfilter )
-               set_frame_ignore(set, fdata);
+                       set_frame_ignore(set, fdata);
        }
        redissect_packets();
 }
@@ -1590,12 +1596,14 @@ new_packet_list_ignore_all_displayed_frames_cb(GtkWidget *w _U_, gpointer data _
 }
 
 static void
-unignore_all_frames()
+unignore_all_frames(void)
 {
+       guint32 framenum;
        frame_data *fdata;
 
        /* XXX: we might need a progressbar here */
-       for (fdata = cfile.plist_start; fdata != NULL && cfile.ignored_count > 0; fdata = fdata->next) {
+       for (framenum = 1; framenum <= cfile.count; framenum++) {
+               fdata = cap_file_find_fdata(&cfile, framenum);
                set_frame_ignore(FALSE, fdata);
        }
        redissect_packets();
@@ -1612,8 +1620,10 @@ static void
 untime_reference_all_frames()
 {
        /* XXX: we might need a progressbar here */
+       guint32 framenum;
        frame_data *fdata;
-       for (fdata = cfile.plist_start; fdata != NULL && cfile.ref_time_count > 0; fdata = fdata->next) {
+       for (framenum = 1; framenum <= cfile.count && cfile.ref_time_count > 0; framenum++) {
+               fdata = cap_file_find_fdata(&cfile, framenum);
                if (fdata->flags.ref_time == 1) {
                        set_frame_reftime(FALSE, fdata, cfile.current_row);
                }
index 82831b78d4ac6ac662ab40de187a1b49c12fe579..cda290289acf82159f6e1898c5f22f7f3eacfc1a 100644 (file)
--- a/summary.c
+++ b/summary.c
@@ -92,7 +92,7 @@ summary_fill_in(capture_file *cf, summary_tally *st)
 {
 
   frame_data    *first_frame, *cur_frame;
-  int          i;
+  guint32        i;
   frame_data    *cur_glist;
 
   st->start_time = 0;