GHash: add typed hash functions (were all (void *))

- BLI_ghashutil_strhash_n takes string length, to avoid terminating the string before hashing.
- BLI_ghashutil_inthash/uinthash take ints, to avoid casting to (void *)

This also showed up incorrect use of inthash, which was using a pointer.
This commit is contained in:
2014-04-15 14:17:54 +10:00
parent ea610e655c
commit a7241d09cd
8 changed files with 64 additions and 24 deletions

View File

@@ -3591,9 +3591,9 @@ static void registerTextureNodes(void)
void init_nodesystem(void)
{
nodetreetypes_hash = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "nodetreetypes_hash gh");
nodetypes_hash = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "nodetypes_hash gh");
nodesockettypes_hash = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "nodesockettypes_hash gh");
nodetreetypes_hash = BLI_ghash_str_new("nodetreetypes_hash gh");
nodetypes_hash = BLI_ghash_str_new("nodetypes_hash gh");
nodesockettypes_hash = BLI_ghash_str_new("nodesockettypes_hash gh");
register_undefined_types();

View File

@@ -78,8 +78,8 @@ static unsigned int tse_hash(const void *ptr)
const TreeStoreElem *tse = ptr;
unsigned int hash;
BLI_assert(tse->type || !tse->nr);
hash = BLI_ghashutil_inthash(SET_INT_IN_POINTER((tse->nr << 16) + tse->type));
hash ^= BLI_ghashutil_inthash(tse->id);
hash = BLI_ghashutil_inthash((tse->nr << 16) + tse->type);
hash ^= BLI_ghashutil_ptrhash(tse->id);
return hash;
}

View File

@@ -112,17 +112,31 @@ BLI_INLINE bool BLI_ghashIterator_done(GHashIterator *ghi) { return !ghi
BLI_ghashIterator_done(&gh_iter_) == false; \
BLI_ghashIterator_step(&gh_iter_), i_++)
/* *** */
/** \name Callbacks for GHash
*
* \note '_p' suffix denotes void pointer arg,
* so we can have functions that take correctly typed args too.
* \{ */
unsigned int BLI_ghashutil_ptrhash(const void *key);
int BLI_ghashutil_ptrcmp(const void *a, const void *b);
unsigned int BLI_ghashutil_strhash(const void *key);
unsigned int BLI_ghashutil_strhash_n(const char *key, size_t n);
#define BLI_ghashutil_strhash(key) ( \
CHECK_TYPE_INLINE(key, char *), \
BLI_ghashutil_strhash_p(key))
unsigned int BLI_ghashutil_strhash_p(const void *key);
int BLI_ghashutil_strcmp(const void *a, const void *b);
unsigned int BLI_ghashutil_inthash(const void *ptr);
#define BLI_ghashutil_inthash(key) ( \
CHECK_TYPE_INLINE(key, int), \
BLI_ghashutil_uinthash((unsigned int)key))
unsigned int BLI_ghashutil_uinthash(unsigned int key);
unsigned int BLI_ghashutil_inthash_p(const void *ptr);
int BLI_ghashutil_intcmp(const void *a, const void *b);
/** \} */
GHash *BLI_ghash_ptr_new_ex(const char *info,
const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
GHash *BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;

View File

@@ -679,7 +679,19 @@ int BLI_ghashutil_ptrcmp(const void *a, const void *b)
return (a < b) ? -1 : 1;
}
unsigned int BLI_ghashutil_inthash(const void *ptr)
unsigned int BLI_ghashutil_uinthash(unsigned int key)
{
key += ~(key << 16);
key ^= (key >> 5);
key += (key << 3);
key ^= (key >> 13);
key += ~(key << 9);
key ^= (key >> 17);
return key;
}
unsigned int BLI_ghashutil_inthash_p(const void *ptr)
{
uintptr_t key = (uintptr_t)ptr;
@@ -710,7 +722,18 @@ int BLI_ghashutil_intcmp(const void *a, const void *b)
*
* note: this is the same hash method that glib 2.34.0 uses.
*/
unsigned int BLI_ghashutil_strhash(const void *ptr)
unsigned int BLI_ghashutil_strhash_n(const char *key, size_t n)
{
const signed char *p;
unsigned int h = 5381;
for (p = (const signed char *)key; n-- && *p != '\0'; p++) {
h = (h << 5) + h + (unsigned int)*p;
}
return h;
}
unsigned int BLI_ghashutil_strhash_p(const void *ptr)
{
const signed char *p;
unsigned int h = 5381;
@@ -777,7 +800,7 @@ GHash *BLI_ghash_ptr_new(const char *info)
GHash *BLI_ghash_str_new_ex(const char *info,
const unsigned int nentries_reserve)
{
return BLI_ghash_new_ex(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, info,
return BLI_ghash_new_ex(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, info,
nentries_reserve);
}
GHash *BLI_ghash_str_new(const char *info)
@@ -788,7 +811,7 @@ GHash *BLI_ghash_str_new(const char *info)
GHash *BLI_ghash_int_new_ex(const char *info,
const unsigned int nentries_reserve)
{
return BLI_ghash_new_ex(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, info,
return BLI_ghash_new_ex(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, info,
nentries_reserve);
}
GHash *BLI_ghash_int_new(const char *info)

View File

@@ -62,11 +62,11 @@ typedef struct EdRotState {
static unsigned int erot_gsetutil_hash(const void *ptr)
{
const EdRotState *e_state = (const EdRotState *)ptr;
unsigned int
hash = BLI_ghashutil_inthash(SET_INT_IN_POINTER(e_state->v1));
hash ^= BLI_ghashutil_inthash(SET_INT_IN_POINTER(e_state->v2));
hash ^= BLI_ghashutil_inthash(SET_INT_IN_POINTER(e_state->f1));
hash ^= BLI_ghashutil_inthash(SET_INT_IN_POINTER(e_state->f2));
unsigned int hash;
hash = BLI_ghashutil_inthash(e_state->v1);
hash ^= BLI_ghashutil_inthash(e_state->v2);
hash ^= BLI_ghashutil_inthash(e_state->f1);
hash ^= BLI_ghashutil_inthash(e_state->f2);
return hash;
}
static int erot_gsetutil_cmp(const void *a, const void *b)

View File

@@ -2091,9 +2091,12 @@ static unsigned int ui_popup_string_hash(const char *str)
int hash;
char *delimit = strchr(str, UI_SEP_CHAR);
if (delimit) *delimit = '\0';
hash = BLI_ghashutil_strhash(str);
if (delimit) *delimit = UI_SEP_CHAR;
if (delimit) {
hash = BLI_ghashutil_strhash_n(str, delimit - str);
}
else {
hash = BLI_ghashutil_strhash(str);
}
return hash;
}

View File

@@ -560,8 +560,8 @@ static int uv_element_offset_from_face_get(UvElementMap *map, BMFace *efa, BMLoo
static unsigned int uv_edge_hash(const void *key)
{
UvEdge *edge = (UvEdge *)key;
return (BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv2)) +
BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv1)));
return (BLI_ghashutil_uinthash(edge->uv2) +
BLI_ghashutil_uinthash(edge->uv1));
}
static int uv_edge_compare(const void *a, const void *b)

View File

@@ -1358,8 +1358,8 @@ static unsigned int uv_edge_hash(const void *key)
{
UvEdge *edge = (UvEdge *)key;
return
BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv2)) +
BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv1));
BLI_ghashutil_uinthash(edge->uv2) +
BLI_ghashutil_uinthash(edge->uv1);
}
static int uv_edge_compare(const void *a, const void *b)