libctf, hash: improve insertion of existing keys into dynhashes
Right now, if you insert a key/value pair into a dynhash, the old slot's key is freed and the new one always assigned. This seemed sane to me when I wrote it, but I got it wrong time and time again. It's much less confusing to free the key passed in: if a key-freeing function was passed, you are asserting that the dynhash owns the key in any case, so if you pass in a key it is always buggy to assume it sticks around. Freeing the old key means that you can't even safely look up a key from out of a dynhash and hold on to it, because some other matching key might force it to be freed at any time. In the new model, you can always get a key out of a dynhash with ctf_dynhash_lookup_kv and hang on to it until the kv-pair is actually deleted from the dynhash. In the old model the pointer to the key might be freed at any time if a matching key was inserted. libctf/ * ctf-hash.c (ctf_hashtab_insert): Free the key passed in if there is a key-freeing function and the key already exists.
This commit is contained in:
parent
809f6eb332
commit
5ceee3dba3
2 changed files with 7 additions and 2 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2020-07-22 Nick Alcock <nick.alcock@oracle.com>
|
||||||
|
|
||||||
|
* ctf-hash.c (ctf_hashtab_insert): Free the key passed in if
|
||||||
|
there is a key-freeing function and the key already exists.
|
||||||
|
|
||||||
2020-07-22 Nick Alcock <nick.alcock@oracle.com>
|
2020-07-22 Nick Alcock <nick.alcock@oracle.com>
|
||||||
|
|
||||||
* ctf-inlines.h: New file.
|
* ctf-inlines.h: New file.
|
||||||
|
|
|
@ -171,15 +171,15 @@ ctf_hashtab_insert (struct htab *htab, void *key, void *value,
|
||||||
*slot = malloc (sizeof (ctf_helem_t));
|
*slot = malloc (sizeof (ctf_helem_t));
|
||||||
if (!*slot)
|
if (!*slot)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
(*slot)->key = key;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (key_free)
|
if (key_free)
|
||||||
key_free ((*slot)->key);
|
key_free (key);
|
||||||
if (value_free)
|
if (value_free)
|
||||||
value_free ((*slot)->value);
|
value_free ((*slot)->value);
|
||||||
}
|
}
|
||||||
(*slot)->key = key;
|
|
||||||
(*slot)->value = value;
|
(*slot)->value = value;
|
||||||
return *slot;
|
return *slot;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue