From bcdf4cf28bb5517137c074801b949fc641141e6c Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Sun, 22 May 2011 10:50:16 -0400 Subject: [PATCH] Enum: fix single-value hash table lookup Signed-off-by: Mathieu Desnoyers --- include/babeltrace/types.h | 2 +- types/enum.c | 192 +++++++++++++++++++------------------ 2 files changed, 99 insertions(+), 95 deletions(-) diff --git a/include/babeltrace/types.h b/include/babeltrace/types.h index cd31a9ef..4534d0f1 100644 --- a/include/babeltrace/types.h +++ b/include/babeltrace/types.h @@ -407,7 +407,7 @@ GArray *enum_uint_to_quark_set(const struct declaration_enum *enum_declaration, * Caller must release the GArray with g_array_unref(). */ GArray *enum_int_to_quark_set(const struct declaration_enum *enum_declaration, - uint64_t v); + int64_t v); /* * Returns a GArray of struct enum_range or NULL. diff --git a/types/enum.c b/types/enum.c index 1c71f9e6..6fcbe683 100644 --- a/types/enum.c +++ b/types/enum.c @@ -35,6 +35,72 @@ void enum_range_set_free(void *ptr) g_array_unref(ptr); } +#if (__WORDSIZE == 32) +static inline +gpointer get_uint_v(uint64_t *v) +{ + return v; +} + +static inline +gpointer get_int_v(int64_t *v) +{ + return v; +} + +static +guint enum_val_hash(gconstpointer key) +{ + int64_t ukey = *(const int64_t *)key; + + return (guint)ukey ^ (guint)(ukey >> 32); +} + +static +gboolean enum_val_equal(gconstpointer a, gconstpointer b) +{ + int64_t ua = *(const int64_t *)a; + int64_t ub = *(const int64_t *)b; + + return ua == ub; +} + +static +void enum_val_free(void *ptr) +{ + g_free(ptr); +} +#else /* __WORDSIZE != 32 */ +static inline +gpointer get_uint_v(uint64_t *v) +{ + return (gpointer) *v; +} + +static inline +gpointer get_int_v(int64_t *v) +{ + return (gpointer) *v; +} + +static +guint enum_val_hash(gconstpointer key) +{ + return g_direct_hash(key); +} + +static +gboolean enum_val_equal(gconstpointer a, gconstpointer b) +{ + return g_direct_equal(a, b); +} + +static +void enum_val_free(void *ptr) +{ +} +#endif /* __WORDSIZE != 32 */ + /* * Returns a GArray or NULL. * Caller must release the GArray with g_array_unref(). @@ -46,7 +112,8 @@ GArray *enum_uint_to_quark_set(const struct declaration_enum *enum_declaration, GArray *qs, *ranges = NULL; /* Single values lookup */ - qs = g_hash_table_lookup(enum_declaration->table.value_to_quark_set, &v); + qs = g_hash_table_lookup(enum_declaration->table.value_to_quark_set, + get_uint_v(&v)); /* Range lookup */ cds_list_for_each_entry(iter, &enum_declaration->table.range_to_quark, node) { @@ -66,11 +133,15 @@ GArray *enum_uint_to_quark_set(const struct declaration_enum *enum_declaration, sizeof(struct enum_range) * qs_len); g_array_index(ranges, struct enum_range, qs_len) = iter->range; } else { - g_array_set_size(ranges, ranges->len + 1); - g_array_index(ranges, struct enum_range, ranges->len) = iter->range; + size_t qs_len = ranges->len; + + g_array_set_size(ranges, qs_len + 1); + g_array_index(ranges, struct enum_range, qs_len) = iter->range; } } if (!ranges) { + if (!qs) + return NULL; ranges = qs; g_array_ref(ranges); } @@ -82,13 +153,14 @@ GArray *enum_uint_to_quark_set(const struct declaration_enum *enum_declaration, * Caller must release the GArray with g_array_unref(). */ GArray *enum_int_to_quark_set(const struct declaration_enum *enum_declaration, - uint64_t v) + int64_t v) { struct enum_range_to_quark *iter; GArray *qs, *ranges = NULL; /* Single values lookup */ - qs = g_hash_table_lookup(enum_declaration->table.value_to_quark_set, &v); + qs = g_hash_table_lookup(enum_declaration->table.value_to_quark_set, + get_int_v(&v)); /* Range lookup */ cds_list_for_each_entry(iter, &enum_declaration->table.range_to_quark, node) { @@ -108,62 +180,21 @@ GArray *enum_int_to_quark_set(const struct declaration_enum *enum_declaration, sizeof(struct enum_range) * qs_len); g_array_index(ranges, struct enum_range, qs_len) = iter->range; } else { - g_array_set_size(ranges, ranges->len + 1); - g_array_index(ranges, struct enum_range, ranges->len) = iter->range; + size_t qs_len = ranges->len; + + g_array_set_size(ranges, qs_len + 1); + g_array_index(ranges, struct enum_range, qs_len) = iter->range; } } if (!ranges) { + if (!qs) + return NULL; ranges = qs; g_array_ref(ranges); } return ranges; } -#if (__WORDSIZE == 32) -static -guint enum_val_hash(gconstpointer key) -{ - int64_t ukey = *(const int64_t *)key; - - return (guint)ukey ^ (guint)(ukey >> 32); -} - -static -gboolean enum_val_equal(gconstpointer a, gconstpointer b) -{ - int64_t ua = *(const int64_t *)a; - int64_t ub = *(const int64_t *)b; - - return ua == ub; -} - -static -void enum_val_free(void *ptr) -{ - g_free(ptr); -} - -static -void enum_signed_insert_value_to_quark_set(struct declaration_enum *enum_declaration, - int64_t v, GQuark q) -{ - int64_t *valuep; - GArray *array; - - array = g_hash_table_lookup(enum_declaration->table.value_to_quark_set, &v); - if (!array) { - array = g_array_sized_new(FALSE, TRUE, sizeof(GQuark), 1); - g_array_set_size(array, 1); - g_array_index(array, GQuark, array->len - 1) = q; - valuep = g_new(int64_t, 1); - *valuep = v; - g_hash_table_insert(enum_declaration->table.value_to_quark_set, valuep, array); - } else { - g_array_set_size(array, array->len + 1); - g_array_index(array, GQuark, array->len - 1) = q; - } -} - static void enum_unsigned_insert_value_to_quark_set(struct declaration_enum *enum_declaration, uint64_t v, GQuark q) @@ -171,77 +202,50 @@ void enum_unsigned_insert_value_to_quark_set(struct declaration_enum *enum_decla uint64_t *valuep; GArray *array; - array = g_hash_table_lookup(enum_declaration->table.value_to_quark_set, &v); + array = g_hash_table_lookup(enum_declaration->table.value_to_quark_set, + get_uint_v(&v)); if (!array) { array = g_array_sized_new(FALSE, TRUE, sizeof(GQuark), 1); g_array_set_size(array, 1); g_array_index(array, GQuark, array->len - 1) = q; +#if (__WORDSIZE == 32) valuep = g_new(uint64_t, 1); *valuep = v; +#else /* __WORDSIZE != 32 */ + valuep = get_uint_v(&v); +#endif /* __WORDSIZE != 32 */ g_hash_table_insert(enum_declaration->table.value_to_quark_set, valuep, array); } else { g_array_set_size(array, array->len + 1); g_array_index(array, GQuark, array->len - 1) = q; } } -#else /* __WORDSIZE != 32 */ -static -guint enum_val_hash(gconstpointer key) -{ - return g_direct_hash(key); -} - -static -gboolean enum_val_equal(gconstpointer a, gconstpointer b) -{ - return g_direct_equal(a, b); -} - -static -void enum_val_free(void *ptr) -{ -} static void enum_signed_insert_value_to_quark_set(struct declaration_enum *enum_declaration, int64_t v, GQuark q) { + int64_t *valuep; GArray *array; array = g_hash_table_lookup(enum_declaration->table.value_to_quark_set, - (gconstpointer) v); - if (!array) { - array = g_array_sized_new(FALSE, TRUE, sizeof(GQuark), 1); - g_array_set_size(array, 1); - g_array_index(array, GQuark, array->len - 1) = q; - g_hash_table_insert(enum_declaration->table.value_to_quark_set, - (gpointer) v, array); - } else { - g_array_set_size(array, array->len + 1); - g_array_index(array, GQuark, array->len - 1) = q; - } -} - -static -void enum_unsigned_insert_value_to_quark_set(struct declaration_enum *enum_declaration, - uint64_t v, GQuark q) -{ - GArray *array; - - array = g_hash_table_lookup(enum_declaration->table.value_to_quark_set, - (gconstpointer) v); + get_int_v(&v)); if (!array) { array = g_array_sized_new(FALSE, TRUE, sizeof(GQuark), 1); g_array_set_size(array, 1); g_array_index(array, GQuark, array->len - 1) = q; - g_hash_table_insert(enum_declaration->table.value_to_quark_set, - (gpointer) v, array); +#if (__WORDSIZE == 32) + valuep = g_new(int64_t, 1); + *valuep = v; +#else /* __WORDSIZE != 32 */ + valuep = get_int_v(&v); +#endif /* __WORDSIZE != 32 */ + g_hash_table_insert(enum_declaration->table.value_to_quark_set, valuep, array); } else { g_array_set_size(array, array->len + 1); g_array_index(array, GQuark, array->len - 1) = q; } } -#endif /* __WORDSIZE != 32 */ GArray *enum_quark_to_range_set(const struct declaration_enum *enum_declaration, GQuark q) -- 2.34.1