auth-chain: optimize tracking of user data for NMAuthChain
- instead of allocating memory separately for the @tag (key) and ChainData (data), store the tag also inside ChainData. - instead of adding two separate key and value items to GHashTable, use g_hash_table_add(), which is optimized for this case.
This commit is contained in:
@@ -85,18 +85,26 @@ auth_call_free (AuthCall *call)
|
|||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
|
/* must be the first field. */
|
||||||
|
const char *tag;
|
||||||
|
|
||||||
gpointer data;
|
gpointer data;
|
||||||
GDestroyNotify destroy;
|
GDestroyNotify destroy;
|
||||||
|
char tag_data[];
|
||||||
} ChainData;
|
} ChainData;
|
||||||
|
|
||||||
static ChainData *
|
static ChainData *
|
||||||
chain_data_new (gpointer data, GDestroyNotify destroy)
|
chain_data_new (const char *tag, gpointer data, GDestroyNotify destroy)
|
||||||
{
|
{
|
||||||
ChainData *tmp;
|
ChainData *tmp;
|
||||||
|
gsize l = strlen (tag);
|
||||||
|
|
||||||
tmp = g_slice_new (ChainData);
|
tmp = g_malloc (sizeof (ChainData) + l + 1);
|
||||||
|
tmp->tag = &tmp->tag_data[0];
|
||||||
tmp->data = data;
|
tmp->data = data;
|
||||||
tmp->destroy = destroy;
|
tmp->destroy = destroy;
|
||||||
|
memcpy (&tmp->tag_data[0], tag, l + 1);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +115,7 @@ chain_data_free (gpointer data)
|
|||||||
|
|
||||||
if (tmp->destroy)
|
if (tmp->destroy)
|
||||||
tmp->destroy (tmp->data);
|
tmp->destroy (tmp->data);
|
||||||
g_slice_free (ChainData, tmp);
|
g_free (tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
@@ -115,7 +123,7 @@ _get_data (NMAuthChain *self, const char *tag)
|
|||||||
{
|
{
|
||||||
ChainData *tmp;
|
ChainData *tmp;
|
||||||
|
|
||||||
tmp = g_hash_table_lookup (self->data, tag);
|
tmp = g_hash_table_lookup (self->data, &tag);
|
||||||
return tmp ? tmp->data : NULL;
|
return tmp ? tmp->data : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,19 +152,19 @@ nm_auth_chain_steal_data (NMAuthChain *self, const char *tag)
|
|||||||
{
|
{
|
||||||
ChainData *tmp;
|
ChainData *tmp;
|
||||||
gpointer value = NULL;
|
gpointer value = NULL;
|
||||||
void *orig_key;
|
|
||||||
|
|
||||||
g_return_val_if_fail (self, NULL);
|
g_return_val_if_fail (self, NULL);
|
||||||
g_return_val_if_fail (tag, NULL);
|
g_return_val_if_fail (tag, NULL);
|
||||||
|
|
||||||
if (g_hash_table_lookup_extended (self->data, tag, &orig_key, (gpointer)&tmp)) {
|
tmp = g_hash_table_lookup (self->data, &tag);
|
||||||
g_hash_table_steal (self->data, tag);
|
if (!tmp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
value = tmp->data;
|
value = tmp->data;
|
||||||
|
|
||||||
/* Make sure the destroy handler isn't called when freeing */
|
/* Make sure the destroy handler isn't called when freeing */
|
||||||
tmp->destroy = NULL;
|
tmp->destroy = NULL;
|
||||||
chain_data_free (tmp);
|
g_hash_table_remove (self->data, tmp);
|
||||||
g_free (orig_key);
|
|
||||||
}
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,11 +178,10 @@ nm_auth_chain_set_data (NMAuthChain *self,
|
|||||||
g_return_if_fail (tag);
|
g_return_if_fail (tag);
|
||||||
|
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
g_hash_table_remove (self->data, tag);
|
g_hash_table_remove (self->data, &tag);
|
||||||
else {
|
else {
|
||||||
g_hash_table_insert (self->data,
|
g_hash_table_add (self->data,
|
||||||
g_strdup (tag),
|
chain_data_new (tag, data, data_destroy));
|
||||||
chain_data_new (data, data_destroy));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,7 +386,7 @@ nm_auth_chain_new_subject (NMAuthSubject *subject,
|
|||||||
self = g_slice_new0 (NMAuthChain);
|
self = g_slice_new0 (NMAuthChain);
|
||||||
c_list_init (&self->auth_call_lst_head);
|
c_list_init (&self->auth_call_lst_head);
|
||||||
self->refcount = 1;
|
self->refcount = 1;
|
||||||
self->data = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, chain_data_free);
|
self->data = g_hash_table_new_full (nm_pstr_hash, nm_pstr_equal, NULL, chain_data_free);
|
||||||
self->done_func = done_func;
|
self->done_func = done_func;
|
||||||
self->user_data = user_data;
|
self->user_data = user_data;
|
||||||
self->context = context ? g_object_ref (context) : NULL;
|
self->context = context ? g_object_ref (context) : NULL;
|
||||||
|
Reference in New Issue
Block a user