Blender  V2.93
BLI_ghash_utils.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
27 #include <string.h>
28 
29 #include "MEM_guardedalloc.h"
30 
31 #include "BLI_ghash.h" /* own include */
32 #include "BLI_hash_mm2a.h"
33 #include "BLI_utildefines.h"
34 
35 /* keep last */
36 #include "BLI_strict_flags.h"
37 
38 /* -------------------------------------------------------------------- */
42 #if 0
43 /* works but slower */
44 uint BLI_ghashutil_ptrhash(const void *key)
45 {
46  return (uint)(intptr_t)key;
47 }
48 #else
49 /* Based Python3.7's pointer hashing function. */
50 uint BLI_ghashutil_ptrhash(const void *key)
51 {
52  size_t y = (size_t)key;
53  /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid
54  * excessive hash collisions for dicts and sets */
55 
56  /* Note: Unlike Python 'sizeof(uint)' is used instead of 'sizeof(void *)',
57  * Otherwise casting to 'uint' ignores the upper bits on 64bit platforms. */
58  return (uint)(y >> 4) | ((uint)y << (sizeof(uint[8]) - 4));
59 }
60 #endif
61 bool BLI_ghashutil_ptrcmp(const void *a, const void *b)
62 {
63  return (a != b);
64 }
65 
67 {
68  uint hash;
69  hash = key[0];
70  hash *= 37;
71  hash += key[1];
72  hash *= 37;
73  hash += key[2];
74  hash *= 37;
75  hash += key[3];
76  return hash;
77 }
78 
80 {
81  return BLI_hash_mm2((const unsigned char *)key, sizeof(int[4]) /* sizeof(key) */, 0);
82 }
83 
84 bool BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b)
85 {
86  return (memcmp(a, b, sizeof(uint[4])) != 0);
87 }
88 
90 {
91  key += ~(key << 16);
92  key ^= (key >> 5);
93  key += (key << 3);
94  key ^= (key >> 13);
95  key += ~(key << 9);
96  key ^= (key >> 17);
97 
98  return key;
99 }
100 
102 {
103  uintptr_t key = (uintptr_t)ptr;
104 
105  key += ~(key << 16);
106  key ^= (key >> 5);
107  key += (key << 3);
108  key ^= (key >> 13);
109  key += ~(key << 9);
110  key ^= (key >> 17);
111 
112  return (uint)(key & 0xffffffff);
113 }
114 
116 {
117  uintptr_t key = (uintptr_t)ptr;
118 
119  return BLI_hash_mm2((const unsigned char *)&key, sizeof(key), 0);
120 }
121 
123 {
124  return POINTER_AS_UINT(ptr);
125 }
126 
127 bool BLI_ghashutil_intcmp(const void *a, const void *b)
128 {
129  return (a != b);
130 }
131 
132 size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b)
133 {
134  return hash_a ^ (hash_b + 0x9e3779b9 + (hash_a << 6) + (hash_a >> 2));
135 }
136 
146 uint BLI_ghashutil_strhash_n(const char *key, size_t n)
147 {
148  const signed char *p;
149  uint h = 5381;
150 
151  for (p = (const signed char *)key; n-- && *p != '\0'; p++) {
152  h = (uint)((h << 5) + h) + (uint)*p;
153  }
154 
155  return h;
156 }
158 {
159  const signed char *p;
160  uint h = 5381;
161 
162  for (p = ptr; *p != '\0'; p++) {
163  h = (uint)((h << 5) + h) + (uint)*p;
164  }
165 
166  return h;
167 }
169 {
170  const unsigned char *key = ptr;
171 
172  return BLI_hash_mm2(key, strlen((const char *)key) + 1, 0);
173 }
174 bool BLI_ghashutil_strcmp(const void *a, const void *b)
175 {
176  return (a == b) ? false : !STREQ(a, b);
177 }
178 
179 GHashPair *BLI_ghashutil_pairalloc(const void *first, const void *second)
180 {
181  GHashPair *pair = MEM_mallocN(sizeof(GHashPair), "GHashPair");
182  pair->first = first;
183  pair->second = second;
184  return pair;
185 }
186 
188 {
189  const GHashPair *pair = ptr;
191  return hash ^ BLI_ghashutil_ptrhash(pair->second);
192 }
193 
194 bool BLI_ghashutil_paircmp(const void *a, const void *b)
195 {
196  const GHashPair *A = a;
197  const GHashPair *B = b;
198 
199  return ((A->first != B->first) || (A->second != B->second));
200 }
201 
203 {
204  MEM_freeN(ptr);
205 }
206 
209 /* -------------------------------------------------------------------- */
213 GHash *BLI_ghash_ptr_new_ex(const char *info, const uint nentries_reserve)
214 {
215  return BLI_ghash_new_ex(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, info, nentries_reserve);
216 }
217 GHash *BLI_ghash_ptr_new(const char *info)
218 {
219  return BLI_ghash_ptr_new_ex(info, 0);
220 }
221 
222 GHash *BLI_ghash_str_new_ex(const char *info, const uint nentries_reserve)
223 {
224  return BLI_ghash_new_ex(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, info, nentries_reserve);
225 }
226 GHash *BLI_ghash_str_new(const char *info)
227 {
228  return BLI_ghash_str_new_ex(info, 0);
229 }
230 
231 GHash *BLI_ghash_int_new_ex(const char *info, const uint nentries_reserve)
232 {
233  return BLI_ghash_new_ex(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, info, nentries_reserve);
234 }
235 GHash *BLI_ghash_int_new(const char *info)
236 {
237  return BLI_ghash_int_new_ex(info, 0);
238 }
239 
240 GHash *BLI_ghash_pair_new_ex(const char *info, const uint nentries_reserve)
241 {
242  return BLI_ghash_new_ex(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, info, nentries_reserve);
243 }
244 GHash *BLI_ghash_pair_new(const char *info)
245 {
246  return BLI_ghash_pair_new_ex(info, 0);
247 }
248 
251 /* -------------------------------------------------------------------- */
255 GSet *BLI_gset_ptr_new_ex(const char *info, const uint nentries_reserve)
256 {
257  return BLI_gset_new_ex(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, info, nentries_reserve);
258 }
259 GSet *BLI_gset_ptr_new(const char *info)
260 {
261  return BLI_gset_ptr_new_ex(info, 0);
262 }
263 
264 GSet *BLI_gset_str_new_ex(const char *info, const uint nentries_reserve)
265 {
266  return BLI_gset_new_ex(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, info, nentries_reserve);
267 }
268 GSet *BLI_gset_str_new(const char *info)
269 {
270  return BLI_gset_str_new_ex(info, 0);
271 }
272 
273 GSet *BLI_gset_pair_new_ex(const char *info, const uint nentries_reserve)
274 {
275  return BLI_gset_new_ex(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, info, nentries_reserve);
276 }
277 GSet *BLI_gset_pair_new(const char *info)
278 {
279  return BLI_gset_pair_new_ex(info, 0);
280 }
281 
282 GSet *BLI_gset_int_new_ex(const char *info, const uint nentries_reserve)
283 {
284  return BLI_gset_new_ex(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, info, nentries_reserve);
285 }
286 GSet *BLI_gset_int_new(const char *info)
287 {
288  return BLI_gset_int_new_ex(info, 0);
289 }
290 
struct GSet GSet
Definition: BLI_ghash.h:189
GHash * BLI_ghash_new_ex(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:707
GSet * BLI_gset_new_ex(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:1117
GSet * BLI_gset_str_new(const char *info)
GSet * BLI_gset_int_new_ex(const char *info, const uint nentries_reserve)
bool BLI_ghashutil_strcmp(const void *a, const void *b)
uint BLI_ghashutil_strhash_p(const void *ptr)
uint BLI_ghashutil_inthash_p(const void *ptr)
size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b)
uint BLI_ghashutil_uinthash_v4(const uint key[4])
GSet * BLI_gset_ptr_new_ex(const char *info, const uint nentries_reserve)
GHash * BLI_ghash_pair_new_ex(const char *info, const uint nentries_reserve)
GHashPair * BLI_ghashutil_pairalloc(const void *first, const void *second)
GSet * BLI_gset_ptr_new(const char *info)
uint BLI_ghashutil_inthash_p_simple(const void *ptr)
GHash * BLI_ghash_str_new_ex(const char *info, const uint nentries_reserve)
GHash * BLI_ghash_ptr_new_ex(const char *info, const uint nentries_reserve)
GHash * BLI_ghash_ptr_new(const char *info)
uint BLI_ghashutil_strhash_p_murmur(const void *ptr)
void BLI_ghashutil_pairfree(void *ptr)
uint BLI_ghashutil_pairhash(const void *ptr)
GSet * BLI_gset_str_new_ex(const char *info, const uint nentries_reserve)
GSet * BLI_gset_pair_new_ex(const char *info, const uint nentries_reserve)
uint BLI_ghashutil_ptrhash(const void *key)
bool BLI_ghashutil_intcmp(const void *a, const void *b)
bool BLI_ghashutil_ptrcmp(const void *a, const void *b)
uint BLI_ghashutil_inthash_p_murmur(const void *ptr)
GSet * BLI_gset_pair_new(const char *info)
GSet * BLI_gset_int_new(const char *info)
GHash * BLI_ghash_int_new_ex(const char *info, const uint nentries_reserve)
uint BLI_ghashutil_uinthash(uint key)
bool BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b)
bool BLI_ghashutil_paircmp(const void *a, const void *b)
GHash * BLI_ghash_int_new(const char *info)
uint BLI_ghashutil_uinthash_v4_murmur(const uint key[4])
uint BLI_ghashutil_strhash_n(const char *key, size_t n)
GHash * BLI_ghash_str_new(const char *info)
GHash * BLI_ghash_pair_new(const char *info)
uint32_t BLI_hash_mm2(const unsigned char *data, size_t len, uint32_t seed)
Definition: hash_mm2a.c:114
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
unsigned int uint
Definition: BLI_sys_types.h:83
#define POINTER_AS_UINT(i)
#define STREQ(a, b)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
Read Guarded memory(de)allocation.
#define A
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
#define B
static unsigned a[3]
Definition: RandGen.cpp:92
#define hash
Definition: noise.c:169
_W64 unsigned int uintptr_t
Definition: stdint.h:122
_W64 int intptr_t
Definition: stdint.h:121
const void * second
Definition: BLI_ghash.h:382
const void * first
Definition: BLI_ghash.h:381
PointerRNA * ptr
Definition: wm_files.c:3157