GHash: Add BLI_ghash_ensure_p_ex to copy the key

Needed in cases where the memory from each key is owned by the GHash.
This commit is contained in:
Campbell Barton 2015-05-11 09:27:05 +10:00
parent d55868c3b2
commit 9e2e85a367
2 changed files with 25 additions and 2 deletions

@ -44,8 +44,8 @@ typedef unsigned int (*GHashHashFP) (const void *key);
typedef bool (*GHashCmpFP) (const void *a, const void *b);
typedef void (*GHashKeyFreeFP) (void *key);
typedef void (*GHashValFreeFP) (void *val);
typedef void *(*GHashKeyCopyFP) (void *key);
typedef void *(*GHashValCopyFP) (void *val);
typedef void *(*GHashKeyCopyFP) (const void *key);
typedef void *(*GHashValCopyFP) (const void *val);
typedef struct GHash GHash;
@ -80,6 +80,7 @@ void *BLI_ghash_lookup(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT;
void *BLI_ghash_lookup_default(GHash *gh, const void *key, void *val_default) ATTR_WARN_UNUSED_RESULT;
void **BLI_ghash_lookup_p(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT;
bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val) ATTR_WARN_UNUSED_RESULT;
bool BLI_ghash_ensure_p_ex(GHash *gh, const void *key, void ***r_val, GHashKeyCopyFP keycopyfp) ATTR_WARN_UNUSED_RESULT;
bool BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
void BLI_ghash_clear_ex(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp,

@ -766,6 +766,28 @@ bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val)
return haskey;
}
/**
* A version of #BLI_ghash_ensure_p copies the key on insertion.
*/
bool BLI_ghash_ensure_p_ex(
GHash *gh, const void *key, void ***r_val,
GHashKeyCopyFP keycopyfp)
{
const unsigned int hash = ghash_keyhash(gh, key);
const unsigned int bucket_index = ghash_bucket_index(gh, hash);
GHashEntry *e = (GHashEntry *)ghash_lookup_entry_ex(gh, key, bucket_index);
const bool haskey = (e != NULL);
if (!haskey) {
/* keycopyfp(key) is the only difference to BLI_ghash_ensure_p */
e = BLI_mempool_alloc(gh->entrypool);
ghash_insert_ex_keyonly_entry(gh, keycopyfp(key), bucket_index, (Entry *)e);
}
*r_val = &e->val;
return haskey;
}
/**
* Remove \a key from \a gh, or return false if the key wasn't found.
*