diff options
author | Campbell Barton <ideasman42@gmail.com> | 2014-04-15 08:17:54 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2014-04-15 08:22:36 +0400 |
commit | a7241d09cdd204a63e10a6e53c575f36639a3102 (patch) | |
tree | a436fbac1010ece84d9d15c617d5be3728469133 /source | |
parent | ea610e655cd8b8f9fb97f0a9a4fc5fd46418bd9e (diff) |
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.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/treehash.c | 4 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_ghash.h | 20 | ||||
-rw-r--r-- | source/blender/blenlib/intern/BLI_ghash.c | 31 | ||||
-rw-r--r-- | source/blender/bmesh/tools/bmesh_beautify.c | 10 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_regions.c | 9 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_uv.c | 4 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_smart_stitch.c | 4 |
8 files changed, 64 insertions, 24 deletions
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 47ef03093b1..a99d1303b85 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -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(); diff --git a/source/blender/blenkernel/intern/treehash.c b/source/blender/blenkernel/intern/treehash.c index d1e9da72208..eda78d6c72e 100644 --- a/source/blender/blenkernel/intern/treehash.c +++ b/source/blender/blenkernel/intern/treehash.c @@ -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; } diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h index 61a75ebb7e8..1e51bd9afea 100644 --- a/source/blender/blenlib/BLI_ghash.h +++ b/source/blender/blenlib/BLI_ghash.h @@ -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; diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index e30883611a8..33a3ba30e4b 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -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) diff --git a/source/blender/bmesh/tools/bmesh_beautify.c b/source/blender/bmesh/tools/bmesh_beautify.c index b602e0742d0..b19a7d0e9b6 100644 --- a/source/blender/bmesh/tools/bmesh_beautify.c +++ b/source/blender/bmesh/tools/bmesh_beautify.c @@ -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) diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index b98bf0f1514..f34fc3c9135 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -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; } diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c index c064612a551..d47840d1504 100644 --- a/source/blender/editors/sculpt_paint/sculpt_uv.c +++ b/source/blender/editors/sculpt_paint/sculpt_uv.c @@ -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) diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 630b601b69d..86aece5d882 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -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) |