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:
Thomas Haller
2018-04-05 09:43:45 +02:00
parent 2cda3770a3
commit d0330bfa73

View File

@@ -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)
value = tmp->data; return NULL;
/* Make sure the destroy handler isn't called when freeing */
tmp->destroy = NULL; value = tmp->data;
chain_data_free (tmp);
g_free (orig_key); /* Make sure the destroy handler isn't called when freeing */
} tmp->destroy = NULL;
g_hash_table_remove (self->data, tmp);
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;