/** * Remove \a key (v0, v1) from \a eh, returning the value or NULL if the key wasn't found. * * \param v0, v1: The key to remove. * \return the value of \a key int \a eh or NULL. */ void *BLI_edgehash_popkey(EdgeHash *eh, uint v0, uint v1) { EDGE_ORD(v0, v1); const uint bucket_index = edgehash_bucket_index(eh, v0, v1); EdgeEntry *e = edgehash_remove_ex(eh, v0, v1, NULL, bucket_index); IS_EDGEHASH_ASSERT(eh); if (e) { void *val = e->val; BLI_mempool_free(eh->epool, e); return val; } else { return NULL; } }
/** * Assign a new value to a key that may already be in edgehash. */ bool BLI_edgehash_reinsert(EdgeHash *eh, uint v0, uint v1, void *val) { IS_EDGEHASH_ASSERT(eh); EDGE_ORD(v0, v1); const uint bucket_index = edgehash_bucket_index(eh, v0, v1); EdgeEntry *e = edgehash_lookup_entry_ex(eh, v0, v1, bucket_index); if (e) { e->val = val; return false; } else { edgehash_insert_ex(eh, v0, v1, val, bucket_index); return true; } }
/** * Assign a new value to a key that may already be in edgehash. */ bool BLI_edgehash_reinsert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val) { unsigned int hash; EdgeEntry *e; IS_EDGEHASH_ASSERT(eh); EDGE_ORD(v0, v1); /* ensure v0 is smaller */ hash = edgehash_keyhash(eh, v0, v1); e = edgehash_lookup_entry_ex(eh, v0, v1, hash); if (e) { e->val = val; return false; } else { edgehash_insert_ex(eh, v0, v1, val, hash); return true; } }
/** * Internal insert function. * Takes a hash argument to avoid calling #edgehash_keyhash multiple times. */ BLI_INLINE void edgehash_insert_ex(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val, unsigned int hash) { EdgeEntry *e = BLI_mempool_alloc(eh->epool); BLI_assert((eh->flag & EDGEHASH_FLAG_ALLOW_DUPES) || (BLI_edgehash_haskey(eh, v0, v1) == 0)); IS_EDGEHASH_ASSERT(eh); /* this helps to track down errors with bad edge data */ BLI_assert(v0 < v1); BLI_assert(v0 != v1); e->next = eh->buckets[hash]; e->v0 = v0; e->v1 = v1; e->val = val; eh->buckets[hash] = e; if (UNLIKELY(edgehash_test_expand_buckets(++eh->nentries, eh->nbuckets))) { edgehash_resize_buckets(eh, _ehash_hashsizes[++eh->cursize]); } }
/** * A version of #BLI_edgehash_lookup which accepts a fallback argument. */ void *BLI_edgehash_lookup_default(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val_default) { EdgeEntry *e = edgehash_lookup_entry(eh, v0, v1); IS_EDGEHASH_ASSERT(eh); return e ? e->val : val_default; }
/** * Return value for given edge (\a v0, \a v1), or NULL if * if key does not exist in hash. (If need exists * to differentiate between key-value being NULL and * lack of key then see BLI_edgehash_lookup_p(). */ void *BLI_edgehash_lookup(EdgeHash *eh, unsigned int v0, unsigned int v1) { EdgeEntry *e = edgehash_lookup_entry(eh, v0, v1); IS_EDGEHASH_ASSERT(eh); return e ? e->val : NULL; }