Wireshark-dev: [Wireshark-dev] RFC: sorted value_string + bsearch
From: Jakub Zawadzki <darkjames@xxxxxxxxxxxxxxxx>
Date: Mon, 12 Apr 2010 02:28:22 +0200
Hi, In wireshark there are some large value_string arrays. Some developers keep them sorted, some don't :) Dissectors in which value_string are sorted could be a little faster thanks to binary search. In attachment patch to introduce new 'fast' functions for value_string. Can this patch be commited? I don't know if I will have time to rewrite dissectors. Some time later it should be also possible to get rid of (hated) value_string NULL terminator. I'm also attaching sample dns_types rewrite. Cheers.
diff --git epan/value_string.c epan/value_string.c index 0e43750..8edd94a 100644 --- epan/value_string.c +++ epan/value_string.c @@ -49,6 +49,19 @@ val_to_str(const guint32 val, const value_string *vs, const char *fmt) { return ep_strdup_printf(fmt, val); } +const gchar* +val_to_str_fast(const guint32 val, const value_string_fast *vs, const char *fmt) { + const gchar *ret; + + g_assert(fmt != NULL); + + ret = match_strval_fast(val, vs); + if (ret != NULL) + return ret; + + return ep_strdup_printf(fmt, val); +} + /* Tries to match val against each element in the value_string array vs. Returns the associated string ptr on a match. Returns 'unknown_str', on failure. */ @@ -65,6 +78,19 @@ val_to_str_const(const guint32 val, const value_string *vs, const char *unknown_ return unknown_str; } +const gchar* +val_to_str_fast_const(const guint32 val, const value_string_fast *vs, const char *unknown_str) { + const gchar *ret; + + g_assert(unknown_str != NULL); + + ret = match_strval_fast(val, vs); + if (ret != NULL) + return ret; + + return unknown_str; +} + /* Tries to match val against each element in the value_string array vs. Returns the associated string ptr, and sets "*idx" to the index in that table, on a match, and returns NULL, and sets "*idx" to -1, @@ -94,6 +120,27 @@ match_strval(const guint32 val, const value_string *vs) { return match_strval_idx(val, vs, &ignore_me); } +const gchar* +match_strval_fast(const guint32 val, const value_string_fast *vs) { + guint low, idx, max; + guint32 item; + if(vs) { + /* XXX, bsearch() */ + for (low = 0, max = vs->length; low < max; ) { + idx = (low + max) / 2; + item = vs->vals[idx].value; + + if (val < item) + max = idx; + else if (val > item) + low = idx + 1; + else + return vs->vals[idx].strptr; + } + } + return NULL; +} + /* Tries to match val against each element in the value_string array vs. Returns the associated string ptr on a match. Formats val with fmt, and returns the resulting string, on failure. */ diff --git epan/value_string.h epan/value_string.h index 7fcbb30..cd3c031 100644 --- epan/value_string.h +++ epan/value_string.h @@ -34,6 +34,14 @@ typedef struct _value_string { const gchar *strptr; } value_string; +typedef struct { + guint length; + const value_string *vals; +} value_string_fast; + +#define VALUE_STRING_FAST(x) \ + value_string_fast x##_fast = { array_length(x)-1, x } + /* Struct for the str_to_str, match_strstr_idx, and match_strstr functions */ typedef struct _string_string { @@ -59,16 +67,19 @@ extern const gchar* match_strval_idx(const guint32 val, const value_string *vs, /* Like match_strval_idx(), but doesn't return the index. */ extern const gchar* match_strval(const guint32 val, const value_string *vs); +extern const gchar* match_strval_fast(const guint32 val, const value_string_fast *vs); /* Tries to match val against each element in the value_string array vs. Returns the associated string ptr on a match. Formats val with fmt, and returns the resulting string, on failure. */ extern const gchar* val_to_str(const guint32 val, const value_string *vs, const char *fmt); +extern const gchar* val_to_str_fast(const guint32 val, const value_string_fast *vs, const char *fmt); /* Tries to match val against each element in the value_string array vs. Returns the associated string ptr on a match. Returns 'unknown_str', on failure. */ extern const gchar* val_to_str_const(const guint32 val, const value_string *vs, const char *unknown_str); +extern const gchar* val_to_str_fast_const(const guint32 val, const value_string_fast *vs, const char *unknown_str); /* Tries to match val against each element in the value_string array vs. Returns the associated string ptr, and sets "*idx" to the index in
diff --git epan/dissectors/packet-dns.c epan/dissectors/packet-dns.c index 3a702f5..57e58fc 100644 --- epan/dissectors/packet-dns.c +++ epan/dissectors/packet-dns.c @@ -499,9 +503,6 @@ static const value_string dns_types[] = { { T_TKEY, "TKEY"}, { T_TSIG, "TSIG"}, - { T_WINS, "WINS"}, - { T_WINS_R, "WINS-R"}, - { 251, "IXFR"}, { 252, "AXFR"}, { 253, "MAILB"}, @@ -510,13 +511,18 @@ static const value_string dns_types[] = { { T_DLV, "DLV" }, /* Domain Lookaside Validation DNS Resource Record (RFC 4431) */ + + { T_WINS, "WINS"}, + { T_WINS_R, "WINS-R"}, {0, NULL} }; +static const VALUE_STRING_FAST(dns_types); /* dns_types_fast */ + static const char * dns_type_name (guint type) { - return val_to_str(type, dns_types, "Unknown (%u)"); + return val_to_str_fast(type, &dns_types_fast, "Unknown (%u)"); } static char *
- Follow-Ups:
- Prev by Date: Re: [Wireshark-dev] Adding tap to dissector causes build errors in tap.h?
- Next by Date: Re: [Wireshark-dev] Adding tap to dissector causes build errors in tap.h?
- Previous by thread: [Wireshark-dev] buildbot failure in Wireshark 1.0 on Windows-XP-x86
- Next by thread: Re: [Wireshark-dev] RFC: sorted value_string + bsearch
- Index(es):