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:
@@ -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();
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user