1 /* frame_data_sequence.c
2 * Implements a sequence of frame_data structures
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include <epan/packet.h>
29 #include "frame_data_sequence.h"
32 * We store the frame_data structures in a radix tree, with 1024
33 * elements per level. The leaf nodes are arrays of 1024 frame_data
34 * structures; the nodes above them are arrays of 1024 pointers to
35 * the nodes below them. The capture_file structure has a pointer
38 * As frame numbers are 32 bits, and as 1024 is 2^10, that gives us
39 * up to 4 levels of tree.
41 #define LOG2_NODES_PER_LEVEL 10
42 #define NODES_PER_LEVEL (1<<LOG2_NODES_PER_LEVEL)
44 struct _frame_data_sequence {
45 guint32 count; /* Total number of frames */
46 void *ptree_root; /* Pointer to the root node */
50 * For a given frame number, calculate the indices into a level 3
51 * node, a level 2 node, a level 1 node, and a leaf node.
53 #define LEVEL_3_INDEX(framenum) \
54 ((framenum) >> (3*LOG2_NODES_PER_LEVEL))
55 #define LEVEL_2_INDEX(framenum) \
56 (((framenum) >> (2*LOG2_NODES_PER_LEVEL)) & (NODES_PER_LEVEL - 1))
57 #define LEVEL_1_INDEX(framenum) \
58 (((framenum) >> (1*LOG2_NODES_PER_LEVEL)) & (NODES_PER_LEVEL - 1))
59 #define LEAF_INDEX(framenum) \
60 (((framenum) >> (0*LOG2_NODES_PER_LEVEL)) & (NODES_PER_LEVEL - 1))
63 new_frame_data_sequence(void)
65 frame_data_sequence *fds;
67 fds = (frame_data_sequence *)g_malloc(sizeof *fds);
69 fds->ptree_root = NULL;
74 * Add a new frame_data structure to a frame_data_sequence.
77 frame_data_sequence_add(frame_data_sequence *fds, frame_data *fdata)
82 frame_data ****level3;
86 * The current value of fds->count is the index value for the new frame,
87 * because the index value for a frame is the frame number - 1, and
88 * if we currently have fds->count frames, the the frame number of
89 * the last frame in the collection is fds->count, so its index value
92 if (fds->count == 0) {
93 /* The tree is empty; allocate the first leaf node, which will be
95 leaf = (frame_data *)g_malloc((sizeof *leaf)*NODES_PER_LEVEL);
97 fds->ptree_root = leaf;
98 } else if (fds->count < NODES_PER_LEVEL) {
99 /* It's a 1-level tree, and is going to stay that way for now. */
100 leaf = (frame_data *)fds->ptree_root;
101 node = &leaf[fds->count];
102 } else if (fds->count == NODES_PER_LEVEL) {
103 /* It's a 1-level tree that will turn into a 2-level tree. */
104 level1 = (frame_data **)g_malloc0((sizeof *level1)*NODES_PER_LEVEL);
105 level1[0] = (frame_data *)fds->ptree_root;
106 leaf = (frame_data *)g_malloc((sizeof *leaf)*NODES_PER_LEVEL);
109 fds->ptree_root = level1;
110 } else if (fds->count < NODES_PER_LEVEL*NODES_PER_LEVEL) {
111 /* It's a 2-level tree, and is going to stay that way for now. */
112 level1 = (frame_data **)fds->ptree_root;
113 leaf = level1[fds->count >> LOG2_NODES_PER_LEVEL];
115 leaf = (frame_data *)g_malloc((sizeof *leaf)*NODES_PER_LEVEL);
116 level1[fds->count >> LOG2_NODES_PER_LEVEL] = leaf;
118 node = &leaf[LEAF_INDEX(fds->count)];
119 } else if (fds->count == NODES_PER_LEVEL*NODES_PER_LEVEL) {
120 /* It's a 2-level tree that will turn into a 3-level tree */
121 level2 = (frame_data ***)g_malloc0((sizeof *level2)*NODES_PER_LEVEL);
122 level2[0] = (frame_data **)fds->ptree_root;
123 level1 = (frame_data **)g_malloc0((sizeof *level1)*NODES_PER_LEVEL);
125 leaf = (frame_data *)g_malloc((sizeof *leaf)*NODES_PER_LEVEL);
128 fds->ptree_root = level2;
129 } else if (fds->count < NODES_PER_LEVEL*NODES_PER_LEVEL*NODES_PER_LEVEL) {
130 /* It's a 3-level tree, and is going to stay that way for now. */
131 level2 = (frame_data ***)fds->ptree_root;
132 level1 = level2[fds->count >> (LOG2_NODES_PER_LEVEL+LOG2_NODES_PER_LEVEL)];
133 if (level1 == NULL) {
134 level1 = (frame_data **)g_malloc0((sizeof *level1)*NODES_PER_LEVEL);
135 level2[fds->count >> (LOG2_NODES_PER_LEVEL+LOG2_NODES_PER_LEVEL)] = level1;
137 leaf = level1[LEVEL_1_INDEX(fds->count)];
139 leaf = (frame_data *)g_malloc((sizeof *leaf)*NODES_PER_LEVEL);
140 level1[LEVEL_1_INDEX(fds->count)] = leaf;
142 node = &leaf[LEAF_INDEX(fds->count)];
143 } else if (fds->count == NODES_PER_LEVEL*NODES_PER_LEVEL*NODES_PER_LEVEL) {
144 /* It's a 3-level tree that will turn into a 4-level tree */
145 level3 = (frame_data ****)g_malloc0((sizeof *level3)*NODES_PER_LEVEL);
146 level3[0] = (frame_data ***)fds->ptree_root;
147 level2 = (frame_data ***)g_malloc0((sizeof *level2)*NODES_PER_LEVEL);
149 level1 = (frame_data **)g_malloc0((sizeof *level1)*NODES_PER_LEVEL);
151 leaf = (frame_data *)g_malloc((sizeof *leaf)*NODES_PER_LEVEL);
154 fds->ptree_root = level3;
156 /* fds->count is 2^32-1 at most, and NODES_PER_LEVEL^4
157 2^(LOG2_NODES_PER_LEVEL*4), and LOG2_NODES_PER_LEVEL is 10,
158 so fds->count is always less < NODES_PER_LEVEL^4.
160 XXX - we should fail if fds->count is 2^31-1, or should
161 make the frame numbers 64-bit and just let users run
162 themselves out of address space or swap space. :-) */
163 /* It's a 4-level tree, and is going to stay that way forever. */
164 level3 = (frame_data ****)fds->ptree_root;
165 level2 = level3[LEVEL_3_INDEX(fds->count)];
166 if (level2 == NULL) {
167 level2 = (frame_data ***)g_malloc0((sizeof *level2)*NODES_PER_LEVEL);
168 level3[LEVEL_3_INDEX(fds->count)] = level2;
170 level1 = level2[LEVEL_2_INDEX(fds->count)];
171 if (level1 == NULL) {
172 level1 = (frame_data **)g_malloc0((sizeof *level1)*NODES_PER_LEVEL);
173 level2[LEVEL_2_INDEX(fds->count)] = level1;
175 leaf = level1[LEVEL_1_INDEX(fds->count)];
177 leaf = (frame_data *)g_malloc((sizeof *leaf)*NODES_PER_LEVEL);
178 level1[LEVEL_1_INDEX(fds->count)] = leaf;
180 node = &leaf[LEAF_INDEX(fds->count)];
188 * Find the frame_data for the specified frame number.
191 frame_data_sequence_find(frame_data_sequence *fds, guint32 num)
195 frame_data ***level2;
196 frame_data ****level3;
199 /* There is no frame number 0 */
203 /* Convert it into an index number. */
205 if (num >= fds->count) {
206 /* There aren't that many frames. */
210 if (fds->count <= NODES_PER_LEVEL) {
211 /* It's a 1-level tree. */
212 leaf = (frame_data *)fds->ptree_root;
215 if (fds->count <= NODES_PER_LEVEL*NODES_PER_LEVEL) {
216 /* It's a 2-level tree. */
217 level1 = (frame_data **)fds->ptree_root;
218 leaf = level1[num >> LOG2_NODES_PER_LEVEL];
219 return &leaf[LEAF_INDEX(num)];
221 if (fds->count <= NODES_PER_LEVEL*NODES_PER_LEVEL*NODES_PER_LEVEL) {
222 /* It's a 3-level tree. */
223 level2 = (frame_data ***)fds->ptree_root;
224 level1 = level2[num >> (LOG2_NODES_PER_LEVEL+LOG2_NODES_PER_LEVEL)];
225 leaf = level1[(num >> LOG2_NODES_PER_LEVEL) & (NODES_PER_LEVEL - 1)];
226 return &leaf[LEAF_INDEX(num)];
228 /* fds->count is 2^32-1 at most, and NODES_PER_LEVEL^4
229 2^(LOG2_NODES_PER_LEVEL*4), and LOG2_NODES_PER_LEVEL is 10,
230 so fds->count is always less < NODES_PER_LEVEL^4. */
231 /* It's a 4-level tree, and is going to stay that way forever. */
232 level3 = (frame_data ****)fds->ptree_root;
233 level2 = level3[num >> (LOG2_NODES_PER_LEVEL+LOG2_NODES_PER_LEVEL+LOG2_NODES_PER_LEVEL)];
234 level1 = level2[(num >> (LOG2_NODES_PER_LEVEL+LOG2_NODES_PER_LEVEL)) & (NODES_PER_LEVEL - 1)];
235 leaf = level1[(num >> LOG2_NODES_PER_LEVEL) & (NODES_PER_LEVEL - 1)];
236 return &leaf[LEAF_INDEX(num)];
239 /* recursively frees a frame_data radix level */
241 free_frame_data_array(void *array, guint count, guint level, gboolean last)
243 guint i, level_count;
246 /* if we are the last in our given parent's row, we may not have
247 * exactly a full row, so do the bit twiddling to figure out exactly
248 * how many fields we have */
249 level_count = (count >> ((level - 1) * LOG2_NODES_PER_LEVEL)) &
250 (NODES_PER_LEVEL - 1);
251 /* the above calculation rounds down, so make sure we count correctly
252 * if count is not an even multiple of NODES_PER_LEVEL */
253 if (count & ((1 << ((level - 1) * LOG2_NODES_PER_LEVEL)) - 1)) {
258 /* if we're not the last in our parent, then we're guaranteed to have
260 level_count = NODES_PER_LEVEL;
265 /* recurse on every sub-array, passing on our own 'last' value
266 * specially to our last child */
267 frame_data **real_array = (frame_data **) array;
269 for (i=0; i < level_count-1; i++) {
270 free_frame_data_array(real_array[i], count, level-1, FALSE);
273 free_frame_data_array(real_array[level_count-1], count, level-1, last);
275 else if (level == 1) {
276 /* bottom level, so just clean up all the frame data */
277 frame_data *real_array = (frame_data *) array;
279 for (i=0; i < level_count; i++) {
280 frame_data_destroy(&real_array[i]);
284 /* free the array itself */
289 * Free a frame_data_sequence and all the frame_data structures in it.
292 free_frame_data_sequence(frame_data_sequence *fds)
296 /* calculate how many levels we have */
297 if (fds->count == 0) {
298 /* The tree is empty; there are no levels. */
300 } else if (fds->count <= NODES_PER_LEVEL) {
301 /* It's a 1-level tree. */
303 } else if (fds->count <= NODES_PER_LEVEL*NODES_PER_LEVEL) {
304 /* It's a 2-level tree. */
306 } else if (fds->count <= NODES_PER_LEVEL*NODES_PER_LEVEL*NODES_PER_LEVEL) {
307 /* It's a 3-level tree. */
310 /* fds->count is 2^32-1 at most, and NODES_PER_LEVEL^4
311 2^(LOG2_NODES_PER_LEVEL*4), and LOG2_NODES_PER_LEVEL is 10,
312 so fds->count is always less < NODES_PER_LEVEL^4. */
313 /* It's a 4-level tree. */
317 /* call the recursive free function */
319 free_frame_data_array(fds->ptree_root, fds->count, levels, TRUE);
322 /* free the header struct */
327 find_and_mark_frame_depended_upon(gpointer data, gpointer user_data)
329 frame_data *dependent_fd;
330 guint32 dependent_frame = GPOINTER_TO_UINT(data);
331 frame_data_sequence *frames = (frame_data_sequence *)user_data;
333 if (dependent_frame && frames) {
334 dependent_fd = frame_data_sequence_find(frames, dependent_frame);
335 dependent_fd->flags.dependent_of_displayed = 1;
340 * Editor modelines - http://www.wireshark.org/tools/modelines.html
345 * indent-tabs-mode: nil
348 * vi: set shiftwidth=2 tabstop=8 expandtab:
349 * :indentSize=2:tabSize=8:noTabs=true: