Merge branch 'th/main-sources-dict-as-set' into 'main'

gmain: optimize "context->sources" hash table to use as set

See merge request GNOME/glib!3664
This commit is contained in:
Philip Withnall 2023-11-06 15:05:43 +00:00
commit c17090275c
3 changed files with 72 additions and 9 deletions

View File

@ -2552,6 +2552,50 @@ g_int_hash (gconstpointer v)
return *(const gint*) v;
}
/**
* g_uint_equal:
* @v1: (not nullable): a pointer to a #guint key
* @v2: (not nullable): a pointer to a #guint key to compare with @v1
*
* Compares the two #guint values being pointed to and returns
* %TRUE if they are equal.
* It can be passed to g_hash_table_new() as the @key_equal_func
* parameter, when using non-%NULL pointers to integers as keys in a
* #GHashTable.
*
* Note that this function acts on pointers to #guint, not on #guint
* directly: if your hash table's keys are of the form
* `GUINT_TO_POINTER (n)`, use g_direct_equal() instead.
*
* Returns: %TRUE if the two keys match.
*/
gboolean
g_uint_equal (gconstpointer v1,
gconstpointer v2)
{
return *((const guint *) v1) == *((const guint *) v2);
}
/**
* g_uint_hash:
* @v: (not nullable): a pointer to a #guint key
*
* Converts a pointer to a #guint to a hash value.
* It can be passed to g_hash_table_new() as the @hash_func parameter,
* when using non-%NULL pointers to integer values as keys in a #GHashTable.
*
* Note that this function acts on pointers to #guint, not on #guint
* directly: if your hash table's keys are of the form
* `GUINT_TO_POINTER (n)`, use g_direct_hash() instead.
*
* Returns: a hash value corresponding to the key.
*/
guint
g_uint_hash (gconstpointer v)
{
return *(const guint *) v;
}
/**
* g_int64_equal:
* @v1: (not nullable): a pointer to a #gint64 key

View File

@ -63,6 +63,18 @@ void __lsan_ignore_object (const void *p) __attribute__ ((weak));
#endif
/**
* G_CONTAINER_OF:
* @ptr: a pointer to a member @field of type @type.
* @type: the type of the container in which @field is embedded.
* @field: the name of the field in @type.
*
* Casts away constness of @ptr.
*
* Returns: a pointer to the container, so that "&(@container)->field == (@ptr)" holds.
*/
#define G_CONTAINER_OF(ptr, type, field) ((type *) G_STRUCT_MEMBER_P (ptr, -G_STRUCT_OFFSET (type, field)))
/*
* g_leak_sanitizer_is_supported:
*
@ -303,4 +315,7 @@ GLibPrivateVTable *glib__private__ (void);
# define GLIB_DEFAULT_LOCALE ""
#endif
gboolean g_uint_equal (gconstpointer v1, gconstpointer v2);
guint g_uint_hash (gconstpointer v);
#endif /* __GLIB_PRIVATE_H__ */

View File

@ -637,7 +637,7 @@ g_main_context_new_with_flags (GMainContextFlags flags)
g_mutex_init (&context->mutex);
g_cond_init (&context->cond);
context->sources = g_hash_table_new (NULL, NULL);
context->sources = g_hash_table_new (g_uint_hash, g_uint_equal);
context->owner = NULL;
context->flags = flags;
context->waiters = NULL;
@ -1166,13 +1166,13 @@ g_source_attach_unlocked (GSource *source,
*/
do
id = context->next_id++;
while (id == 0 || g_hash_table_contains (context->sources, GUINT_TO_POINTER (id)));
while (id == 0 || g_hash_table_contains (context->sources, &id));
source->context = context;
source->source_id = id;
g_source_ref (source);
g_hash_table_insert (context->sources, GUINT_TO_POINTER (id), source);
g_hash_table_add (context->sources, &source->source_id);
source_add_to_context (source, context);
@ -2239,7 +2239,7 @@ g_source_unref_internal (GSource *source,
g_warning (G_STRLOC ": ref_count == 0, but source was still attached to a context!");
source_remove_from_context (source, context);
g_hash_table_remove (context->sources, GUINT_TO_POINTER (source->source_id));
g_hash_table_remove (context->sources, &source->source_id);
}
if (source->source_funcs->finalize)
@ -2348,7 +2348,8 @@ GSource *
g_main_context_find_source_by_id (GMainContext *context,
guint source_id)
{
GSource *source;
GSource *source = NULL;
gconstpointer ptr;
g_return_val_if_fail (source_id > 0, NULL);
@ -2356,12 +2357,15 @@ g_main_context_find_source_by_id (GMainContext *context,
context = g_main_context_default ();
LOCK_CONTEXT (context);
source = g_hash_table_lookup (context->sources, GUINT_TO_POINTER (source_id));
ptr = g_hash_table_lookup (context->sources, &source_id);
if (ptr)
{
source = G_CONTAINER_OF (ptr, GSource, source_id);
if (SOURCE_DESTROYED (source))
source = NULL;
}
UNLOCK_CONTEXT (context);
if (source && SOURCE_DESTROYED (source))
source = NULL;
return source;
}