GHash: ensure function, avoids multiple lookups
This commit is contained in:
parent
3639a70eae
commit
dd129125b6
|
@ -79,6 +79,7 @@ bool BLI_ghash_reinsert(GHash *gh, void *key, void *val, GHashKeyFreeFP keyfre
|
|||
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_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,
|
||||
|
|
|
@ -444,6 +444,22 @@ BLI_INLINE void ghash_insert_ex(
|
|||
ghash_buckets_expand(gh, ++gh->nentries, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert function that takes a pre-allocated entry.
|
||||
*/
|
||||
BLI_INLINE void ghash_insert_ex_keyonly_entry(
|
||||
GHash *gh, void *key, const unsigned int bucket_index,
|
||||
Entry *e)
|
||||
{
|
||||
BLI_assert((gh->flag & GHASH_FLAG_ALLOW_DUPES) || (BLI_ghash_haskey(gh, key) == 0));
|
||||
|
||||
e->next = gh->buckets[bucket_index];
|
||||
e->key = key;
|
||||
gh->buckets[bucket_index] = e;
|
||||
|
||||
ghash_buckets_expand(gh, ++gh->nentries, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert function that doesn't set the value (use for GSet)
|
||||
*/
|
||||
|
@ -720,6 +736,36 @@ void **BLI_ghash_lookup_p(GHash *gh, const void *key)
|
|||
return e ? &e->val : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure \a key is exists in \a gh.
|
||||
*
|
||||
* This handles the common situation where the caller needs ensure a key is added to \a gh,
|
||||
* constructing a new value in the case the key isn't found.
|
||||
* Otherwise use the existing value.
|
||||
*
|
||||
* Such situations typically incur multiple lookups, however this function
|
||||
* avoids them by ensuring the key is added,
|
||||
* returning a pointer to the value so it can be used or initialized by the caller.
|
||||
*
|
||||
* \returns true when the value didn't need to be added.
|
||||
* (when false, the caller _must_ initialize the value).
|
||||
*/
|
||||
bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val)
|
||||
{
|
||||
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) {
|
||||
e = BLI_mempool_alloc(gh->entrypool);
|
||||
ghash_insert_ex_keyonly_entry(gh, 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.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue