forked from bartvdbraak/blender
minor api cleanup for ghash/edgehash
- use single inlined lookup function. - move comments into source. - pack iterator vars more efficiently.
This commit is contained in:
parent
fbb446dff6
commit
ee2d95f850
@ -42,61 +42,21 @@ enum {
|
||||
|
||||
EdgeHash *BLI_edgehash_new(void);
|
||||
void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP valfreefp);
|
||||
|
||||
/* Insert edge (v0,v1) into hash with given value, does
|
||||
* not check for duplicates.
|
||||
*/
|
||||
void BLI_edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val);
|
||||
|
||||
/* Return value for given edge (v0,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);
|
||||
|
||||
/* Return pointer to value for given edge (v0,v1),
|
||||
* or NULL if key does not exist in hash.
|
||||
*/
|
||||
void **BLI_edgehash_lookup_p(EdgeHash *eh, unsigned int v0, unsigned int v1);
|
||||
|
||||
/* Return boolean true/false if edge (v0,v1) in hash. */
|
||||
bool BLI_edgehash_haskey(EdgeHash *eh, unsigned int v0, unsigned int v1);
|
||||
|
||||
/* Return number of keys in hash. */
|
||||
int BLI_edgehash_size(EdgeHash *eh);
|
||||
|
||||
/* Remove all edges from hash. */
|
||||
void BLI_edgehash_clear(EdgeHash *eh, EdgeHashFreeFP valfreefp);
|
||||
|
||||
void BLI_edgehash_flag_set(EdgeHash *eh, unsigned short flag);
|
||||
void BLI_edgehash_flag_clear(EdgeHash *eh, unsigned short flag);
|
||||
|
||||
/***/
|
||||
|
||||
/**
|
||||
* Create a new EdgeHashIterator. The hash table must not be mutated
|
||||
* while the iterator is in use, and the iterator will step exactly
|
||||
* BLI_edgehash_size(gh) times before becoming done.
|
||||
*/
|
||||
EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh);
|
||||
|
||||
/* Free an EdgeHashIterator. */
|
||||
void BLI_edgehashIterator_free(EdgeHashIterator *ehi);
|
||||
|
||||
/* Retrieve the key from an iterator. */
|
||||
void BLI_edgehashIterator_getKey(EdgeHashIterator *ehi, unsigned int *v0_r, unsigned int *v1_r);
|
||||
|
||||
/* Retrieve the value from an iterator. */
|
||||
void *BLI_edgehashIterator_getValue(EdgeHashIterator *ehi);
|
||||
|
||||
/* Set the value for an iterator. */
|
||||
void BLI_edgehashIterator_setValue(EdgeHashIterator *ehi, void *val);
|
||||
|
||||
/* Steps the iterator to the next index. */
|
||||
void BLI_edgehashIterator_step(EdgeHashIterator *ehi);
|
||||
|
||||
/* Determine if an iterator is done. */
|
||||
bool BLI_edgehashIterator_isDone(EdgeHashIterator *ehi);
|
||||
|
||||
#endif
|
||||
|
@ -46,8 +46,8 @@ typedef struct GHash GHash;
|
||||
|
||||
typedef struct GHashIterator {
|
||||
GHash *gh;
|
||||
unsigned int curBucket;
|
||||
struct Entry *curEntry;
|
||||
unsigned int curBucket;
|
||||
} GHashIterator;
|
||||
|
||||
enum {
|
||||
@ -60,6 +60,7 @@ GHash *BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info);
|
||||
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
|
||||
void BLI_ghash_insert(GHash *gh, void *key, void *val);
|
||||
void *BLI_ghash_lookup(GHash *gh, const void *key);
|
||||
void **BLI_ghash_lookup_p(GHash *gh, const void *key);
|
||||
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_pop(GHash *gh, void *key, GHashKeyFreeFP keyfreefp);
|
||||
|
@ -23,12 +23,13 @@
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
* A general (pointer -> pointer) hash table ADT
|
||||
*/
|
||||
|
||||
/** \file blender/blenlib/intern/BLI_ghash.c
|
||||
* \ingroup bli
|
||||
*
|
||||
* A general (pointer -> pointer) hash table ADT
|
||||
*
|
||||
* \note edgehash.c is based on this, make sure they stay in sync.
|
||||
*/
|
||||
|
||||
@ -138,19 +139,31 @@ void BLI_ghash_insert(GHash *gh, void *key, void *val)
|
||||
}
|
||||
}
|
||||
|
||||
void *BLI_ghash_lookup(GHash *gh, const void *key)
|
||||
BLI_INLINE Entry *ghash_lookup_entry(GHash *gh, const void *key)
|
||||
{
|
||||
const unsigned int hash = gh->hashfp(key) % gh->nbuckets;
|
||||
Entry *e;
|
||||
|
||||
for (e = gh->buckets[hash]; e; e = e->next) {
|
||||
if (gh->cmpfp(key, e->key) == 0) {
|
||||
return e->val;
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *BLI_ghash_lookup(GHash *gh, const void *key)
|
||||
{
|
||||
Entry *e = ghash_lookup_entry(gh, key);
|
||||
return e ? e->val : NULL;
|
||||
}
|
||||
|
||||
void **BLI_ghash_lookup_p(GHash *gh, const void *key)
|
||||
{
|
||||
Entry *e = ghash_lookup_entry(gh, key);
|
||||
return e ? &e->val : NULL;
|
||||
}
|
||||
|
||||
bool BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
|
||||
{
|
||||
unsigned int hash = gh->hashfp(key) % gh->nbuckets;
|
||||
@ -179,33 +192,6 @@ bool BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFr
|
||||
return false;
|
||||
}
|
||||
|
||||
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (keyfreefp || valfreefp) {
|
||||
for (i = 0; i < gh->nbuckets; i++) {
|
||||
Entry *e;
|
||||
|
||||
for (e = gh->buckets[i]; e; ) {
|
||||
Entry *n = e->next;
|
||||
|
||||
if (keyfreefp) keyfreefp(e->key);
|
||||
if (valfreefp) valfreefp(e->val);
|
||||
|
||||
e = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gh->cursize = 0;
|
||||
gh->nentries = 0;
|
||||
gh->nbuckets = hashsizes[gh->cursize];
|
||||
|
||||
MEM_freeN(gh->buckets);
|
||||
gh->buckets = MEM_callocN(gh->nbuckets * sizeof(*gh->buckets), "buckets");
|
||||
}
|
||||
|
||||
/* same as above but return the value,
|
||||
* no free value argument since it will be returned */
|
||||
void *BLI_ghash_pop(GHash *gh, void *key, GHashKeyFreeFP keyfreefp)
|
||||
@ -238,14 +224,34 @@ void *BLI_ghash_pop(GHash *gh, void *key, GHashKeyFreeFP keyfreefp)
|
||||
|
||||
bool BLI_ghash_haskey(GHash *gh, const void *key)
|
||||
{
|
||||
unsigned int hash = gh->hashfp(key) % gh->nbuckets;
|
||||
Entry *e;
|
||||
return (ghash_lookup_entry(gh, key) != NULL);
|
||||
}
|
||||
|
||||
for (e = gh->buckets[hash]; e; e = e->next)
|
||||
if (gh->cmpfp(key, e->key) == 0)
|
||||
return true;
|
||||
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
return false;
|
||||
if (keyfreefp || valfreefp) {
|
||||
for (i = 0; i < gh->nbuckets; i++) {
|
||||
Entry *e;
|
||||
|
||||
for (e = gh->buckets[i]; e; ) {
|
||||
Entry *n = e->next;
|
||||
|
||||
if (keyfreefp) keyfreefp(e->key);
|
||||
if (valfreefp) valfreefp(e->val);
|
||||
|
||||
e = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gh->cursize = 0;
|
||||
gh->nentries = 0;
|
||||
gh->nbuckets = hashsizes[gh->cursize];
|
||||
|
||||
MEM_freeN(gh->buckets);
|
||||
gh->buckets = MEM_callocN(gh->nbuckets * sizeof(*gh->buckets), "buckets");
|
||||
}
|
||||
|
||||
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
|
||||
|
@ -18,12 +18,13 @@
|
||||
* Contributor(s): Daniel Dunbar, Joseph Eagar
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
* A general (pointer -> pointer) hash table ADT
|
||||
*/
|
||||
|
||||
/** \file blender/blenlib/intern/edgehash.c
|
||||
* \ingroup bli
|
||||
*
|
||||
* A general (pointer -> pointer) hash table ADT
|
||||
*
|
||||
* \note Based on 'BLI_ghash.c', make sure these stay in sync.
|
||||
*/
|
||||
|
||||
@ -66,12 +67,11 @@ static const unsigned int _ehash_hashsizes[] = {
|
||||
|
||||
/***/
|
||||
|
||||
typedef struct EdgeEntry EdgeEntry;
|
||||
struct EdgeEntry {
|
||||
EdgeEntry *next;
|
||||
typedef struct EdgeEntry {
|
||||
struct EdgeEntry *next;
|
||||
unsigned int v0, v1;
|
||||
void *val;
|
||||
};
|
||||
} EdgeEntry;
|
||||
|
||||
struct EdgeHash {
|
||||
EdgeEntry **buckets;
|
||||
@ -80,7 +80,9 @@ struct EdgeHash {
|
||||
unsigned short cursize, flag;
|
||||
};
|
||||
|
||||
/***/
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* EdgeHash API */
|
||||
|
||||
EdgeHash *BLI_edgehash_new(void)
|
||||
{
|
||||
@ -95,7 +97,10 @@ EdgeHash *BLI_edgehash_new(void)
|
||||
return eh;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Insert edge (\a v0, \a v1) into hash with given value, does
|
||||
* not check for duplicates.
|
||||
*/
|
||||
void BLI_edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val)
|
||||
{
|
||||
unsigned int hash;
|
||||
@ -138,7 +143,7 @@ void BLI_edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *v
|
||||
}
|
||||
}
|
||||
|
||||
void **BLI_edgehash_lookup_p(EdgeHash *eh, unsigned int v0, unsigned int v1)
|
||||
BLI_INLINE EdgeEntry *edgehash_lookup_entry(EdgeHash *eh, unsigned int v0, unsigned int v1)
|
||||
{
|
||||
unsigned int hash;
|
||||
EdgeEntry *e;
|
||||
@ -146,30 +151,55 @@ void **BLI_edgehash_lookup_p(EdgeHash *eh, unsigned int v0, unsigned int v1)
|
||||
EDGE_ORD(v0, v1); /* ensure v0 is smaller */
|
||||
|
||||
hash = EDGE_HASH(v0, v1) % eh->nbuckets;
|
||||
for (e = eh->buckets[hash]; e; e = e->next)
|
||||
if (v0 == e->v0 && v1 == e->v1)
|
||||
return &e->val;
|
||||
|
||||
for (e = eh->buckets[hash]; e; e = e->next) {
|
||||
if (v0 == e->v0 && v1 == e->v1) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return pointer to value for given edge (\a v0, \a v1),
|
||||
* or NULL if key does not exist in hash.
|
||||
*/
|
||||
void **BLI_edgehash_lookup_p(EdgeHash *eh, unsigned int v0, unsigned int v1)
|
||||
{
|
||||
EdgeEntry *e = edgehash_lookup_entry(eh, v0, v1);
|
||||
return e ? &e->val : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
void **value_p = BLI_edgehash_lookup_p(eh, v0, v1);
|
||||
|
||||
return value_p ? *value_p : NULL;
|
||||
EdgeEntry *e = edgehash_lookup_entry(eh, v0, v1);
|
||||
return e ? e->val : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return boolean true/false if edge (v0,v1) in hash.
|
||||
*/
|
||||
bool BLI_edgehash_haskey(EdgeHash *eh, unsigned int v0, unsigned int v1)
|
||||
{
|
||||
return BLI_edgehash_lookup_p(eh, v0, v1) != NULL;
|
||||
return (edgehash_lookup_entry(eh, v0, v1) != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return number of keys in hash.
|
||||
*/
|
||||
int BLI_edgehash_size(EdgeHash *eh)
|
||||
{
|
||||
return (int)eh->nentries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all edges from hash.
|
||||
*/
|
||||
void BLI_edgehash_clear(EdgeHash *eh, EdgeHashFreeFP valfreefp)
|
||||
{
|
||||
unsigned int i;
|
||||
@ -212,7 +242,9 @@ void BLI_edgehash_flag_clear(EdgeHash *eh, unsigned short flag)
|
||||
eh->flag &= (unsigned short)~flag;
|
||||
}
|
||||
|
||||
/***/
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* EdgeHash Iterator API */
|
||||
|
||||
struct EdgeHashIterator {
|
||||
EdgeHash *eh;
|
||||
@ -220,6 +252,12 @@ struct EdgeHashIterator {
|
||||
EdgeEntry *curEntry;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create a new EdgeHashIterator. The hash table must not be mutated
|
||||
* while the iterator is in use, and the iterator will step exactly
|
||||
* BLI_edgehash_size(gh) times before becoming done.
|
||||
*/
|
||||
EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh)
|
||||
{
|
||||
EdgeHashIterator *ehi = MEM_mallocN(sizeof(*ehi), "eh iter");
|
||||
@ -234,11 +272,18 @@ EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh)
|
||||
}
|
||||
return ehi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free an EdgeHashIterator.
|
||||
*/
|
||||
void BLI_edgehashIterator_free(EdgeHashIterator *ehi)
|
||||
{
|
||||
MEM_freeN(ehi);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the key from an iterator.
|
||||
*/
|
||||
void BLI_edgehashIterator_getKey(EdgeHashIterator *ehi, unsigned int *v0_r, unsigned int *v1_r)
|
||||
{
|
||||
if (ehi->curEntry) {
|
||||
@ -246,11 +291,18 @@ void BLI_edgehashIterator_getKey(EdgeHashIterator *ehi, unsigned int *v0_r, unsi
|
||||
*v1_r = ehi->curEntry->v1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the value from an iterator.
|
||||
*/
|
||||
void *BLI_edgehashIterator_getValue(EdgeHashIterator *ehi)
|
||||
{
|
||||
return ehi->curEntry ? ehi->curEntry->val : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for an iterator.
|
||||
*/
|
||||
void BLI_edgehashIterator_setValue(EdgeHashIterator *ehi, void *val)
|
||||
{
|
||||
if (ehi->curEntry) {
|
||||
@ -258,6 +310,9 @@ void BLI_edgehashIterator_setValue(EdgeHashIterator *ehi, void *val)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Steps the iterator to the next index.
|
||||
*/
|
||||
void BLI_edgehashIterator_step(EdgeHashIterator *ehi)
|
||||
{
|
||||
if (ehi->curEntry) {
|
||||
@ -272,6 +327,10 @@ void BLI_edgehashIterator_step(EdgeHashIterator *ehi)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if an iterator is done.
|
||||
*/
|
||||
bool BLI_edgehashIterator_isDone(EdgeHashIterator *ehi)
|
||||
{
|
||||
return (ehi->curEntry == NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user