aboutsummaryrefslogtreecommitdiffstats
path: root/epan/conversation.c
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2012-04-19 13:59:14 +0000
committerAnders Broman <anders.broman@ericsson.com>2012-04-19 13:59:14 +0000
commit9a4a387e12b4e5d4aabcc241ff869dfb29748d79 (patch)
tree2fe6c5e03d893ff46c66af2dafccd928dcd5c99c /epan/conversation.c
parent990d1ad71e2a28231f93a622cb93fe5e38a9bf84 (diff)
From Cristian Constantin:
while caching the last element from the conversation hash chain lists speeds-up the operation when the hash/chain lists are actually built, it does NOT help a lot when a certain random conversation which is in the hash table is looked-up. I did some profiling and tracing and I saw that a lot of cpu time is spent in the function conversation_lookup_hashtable() when wireshark is asked to show the "Flow Graph", "TCP Conversations", "Voip Calls". I used two types of captures with over 500k packets: - tcp packets having the _same_ src ip addr, src tcp port, dst ip addr, dst tcp port - (mostly) sip packets containing sdp payloads which advertise the _same_ ip addr, udp port for media these types of captures lead to _huge_ chain lists behind the same hash bucket (to which the conversation is actually mapped) the solution would be to cache the last found conversation into the head of the chain list and to use it whenever it is possible; most of the time the look-up will be in O(1) instead of O(n) (n - number of elements in the list). https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7149 svn path=/trunk/; revision=42141
Diffstat (limited to 'epan/conversation.c')
-rw-r--r--epan/conversation.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/epan/conversation.c b/epan/conversation.c
index 55e8cd8917..f1a13f771a 100644
--- a/epan/conversation.c
+++ b/epan/conversation.c
@@ -640,6 +640,7 @@ conversation_new(const guint32 setup_frame, const address *addr1, const address
new_key->port2 = port2;
conversation = se_alloc(sizeof(conversation_t));
+ memset(conversation, 0, sizeof(conversation_t));
conversation->index = new_index;
conversation->setup_frame = setup_frame;
@@ -729,6 +730,7 @@ conversation_lookup_hashtable(GHashTable *hashtable, const guint32 frame_num, co
{
conversation_t* conversation=NULL;
conversation_t* match=NULL;
+ conversation_t* chain_head=NULL;
conversation_key key;
guint found=0;
@@ -742,7 +744,7 @@ conversation_lookup_hashtable(GHashTable *hashtable, const guint32 frame_num, co
key.port1 = port1;
key.port2 = port2;
- match = g_hash_table_lookup(hashtable, &key);
+ chain_head = (match = g_hash_table_lookup(hashtable, &key));
if (match && (match->setup_frame > frame_num))
match = NULL;
@@ -750,10 +752,13 @@ conversation_lookup_hashtable(GHashTable *hashtable, const guint32 frame_num, co
if (match) {
if((match->last)&&(match->last->setup_frame<=frame_num))
return match->last;
+ if((match->latest_found)&&(match->latest_found->setup_frame<=frame_num))
+ return match->latest_found;
for (conversation = match->next; conversation; conversation = conversation->next) {
if ((conversation->setup_frame <= frame_num)
&& (conversation->setup_frame > match->setup_frame)) {
match = conversation;
+ chain_head->latest_found = conversation;
found=1;
} else if(conversation->setup_frame>frame_num)
/* we are past the frame_num */