[Bf-blender-cvs] [a7241d0] master: GHash: add typed hash functions (were all (void *))

Campbell Barton noreply at git.blender.org
Tue Apr 15 06:23:46 CEST 2014


Commit: a7241d09cdd204a63e10a6e53c575f36639a3102
Author: Campbell Barton
Date:   Tue Apr 15 14:17:54 2014 +1000
https://developer.blender.org/rBa7241d09cdd204a63e10a6e53c575f36639a3102

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.

===================================================================

M	source/blender/blenkernel/intern/node.c
M	source/blender/blenkernel/intern/treehash.c
M	source/blender/blenlib/BLI_ghash.h
M	source/blender/blenlib/intern/BLI_ghash.c
M	source/blender/bmesh/tools/bmesh_beautify.c
M	source/blender/editors/interface/interface_regions.c
M	source/blender/editors/sculpt_paint/sculpt_uv.c
M	source/blender/editors/uvedit/uvedit_smart_stitch.c

===================================================================

diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 47ef030..a99d130 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 d1e9da7..eda78d6 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 61a75eb..1e51bd9 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 e308836..33a3ba3 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 b602e07..b19a7d0 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 b98bf0f..f34fc3c 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 c064612..d47840d 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 630b601..86aece5 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)




More information about the Bf-blender-cvs mailing list