38 #define GHASH_INTERNAL_API
48 #define GHASH_USE_MODULO_BUCKETS
57 5, 11, 17, 37, 67, 131, 257, 521, 1031,
58 2053, 4099, 8209, 16411, 32771, 65537, 131101, 262147, 524309,
59 1048583, 2097169, 4194319, 8388617, 16777259, 33554467, 67108879, 134217757, 268435459,
61 #define hashsizes BLI_ghash_hash_sizes
63 #ifdef GHASH_USE_MODULO_BUCKETS
64 # define GHASH_MAX_SIZE 27
67 # define GHASH_BUCKET_BIT_MIN 2
68 # define GHASH_BUCKET_BIT_MAX 28
79 #define GHASH_LIMIT_GROW(_nbkt) (((_nbkt)*3) / 4)
80 #define GHASH_LIMIT_SHRINK(_nbkt) (((_nbkt)*3) / 16)
97 #define GHASH_ENTRY_SIZE(_is_gset) ((_is_gset) ? sizeof(GSetEntry) : sizeof(GHashEntry))
107 #ifdef GHASH_USE_MODULO_BUCKETS
110 uint bucket_mask, bucket_bit, bucket_bit_min;
130 dst->
key = (keycopyfp) ? keycopyfp(src->
key) : src->
key;
132 if ((gh_dst->
flag & GHASH_FLAG_IS_GSET) == 0) {
133 if ((gh_src->
flag & GHASH_FLAG_IS_GSET) == 0) {
164 #ifdef GHASH_USE_MODULO_BUCKETS
167 return hash & gh->bucket_mask;
179 if (gh->
buckets[curr_bucket]) {
182 for (; curr_bucket < gh->
nbuckets; curr_bucket++) {
183 if (gh->
buckets[curr_bucket]) {
187 for (curr_bucket = 0; curr_bucket < gh->
nbuckets; curr_bucket++) {
188 if (gh->
buckets[curr_bucket]) {
210 #ifdef GHASH_USE_MODULO_BUCKETS
212 gh->bucket_mask = nbuckets - 1;
218 if (nbuckets > nbuckets_old) {
219 for (i = 0; i < nbuckets_old; i++) {
220 for (
Entry *
e = buckets_old[i], *e_next;
e;
e = e_next) {
224 e->next = buckets_new[bucket_index];
225 buckets_new[bucket_index] =
e;
230 for (i = 0; i < nbuckets_old; i++) {
231 #ifdef GHASH_USE_MODULO_BUCKETS
232 for (
Entry *
e = buckets_old[i], *e_next;
e;
e = e_next) {
236 e->next = buckets_new[bucket_index];
237 buckets_new[bucket_index] =
e;
246 for (
e = buckets_old[i];
e &&
e->next;
e =
e->next) {
250 e->next = buckets_new[bucket_index];
251 buckets_new[bucket_index] = buckets_old[i];
278 #ifdef GHASH_USE_MODULO_BUCKETS
284 while ((nentries > gh->
limit_grow) && (gh->bucket_bit < GHASH_BUCKET_BIT_MAX)) {
285 new_nbuckets = 1u << ++gh->bucket_bit;
291 #ifdef GHASH_USE_MODULO_BUCKETS
294 gh->bucket_bit_min = gh->bucket_bit;
309 const bool user_defined,
310 const bool force_shrink)
324 #ifdef GHASH_USE_MODULO_BUCKETS
325 while ((nentries < gh->limit_shrink) && (gh->
cursize > gh->
size_min)) {
330 while ((nentries < gh->limit_shrink) && (gh->bucket_bit > gh->bucket_bit_min)) {
331 new_nbuckets = 1u << --gh->bucket_bit;
337 #ifdef GHASH_USE_MODULO_BUCKETS
340 gh->bucket_bit_min = gh->bucket_bit;
360 #ifdef GHASH_USE_MODULO_BUCKETS
365 gh->bucket_bit = GHASH_BUCKET_BIT_MIN;
366 gh->bucket_bit_min = GHASH_BUCKET_BIT_MIN;
367 gh->
nbuckets = 1u << gh->bucket_bit;
389 for (
e = gh->
buckets[bucket_index];
e;
e =
e->next) {
407 const uint bucket_index)
435 const uint nentries_reserve,
478 const uint bucket_index,
483 e->next = gh->
buckets[bucket_index];
500 e->next = gh->
buckets[bucket_index];
576 const uint bucket_index)
592 e_prev->
next =
e->next;
595 gh->
buckets[bucket_index] =
e->next;
624 state->curr_bucket = curr_bucket;
638 for (i = 0; i < gh->
nbuckets; i++) {
669 for (i = 0; i < gh->
nbuckets; i++) {
710 const uint nentries_reserve)
712 return ghash_new(hashfp, cmpfp, info, nentries_reserve, 0);
787 void *key_prev =
e->
e.key;
817 return e ?
e->val : val_default;
834 return e ? &
e->val :
NULL;
856 const bool haskey = (
e !=
NULL);
878 const bool haskey = (
e !=
NULL);
969 *r_key = *r_val =
NULL;
983 const uint nentries_reserve)
985 if (keyfreefp || valfreefp) {
1011 if (keyfreefp || valfreefp) {
1120 const uint nentries_reserve)
1122 return (
GSet *)
ghash_new(hashfp, cmpfp, info, nentries_reserve, GHASH_FLAG_IS_GSET);
1140 return ((
GHash *)gs)->nentries;
1176 const bool haskey = (
e !=
NULL);
1283 return e ?
e->key :
NULL;
1296 void *key_ret =
e->key;
1333 double *r_prop_empty_buckets,
1334 double *r_prop_overloaded_buckets,
1335 int *r_biggest_bucket)
1347 if (r_prop_empty_buckets) {
1348 *r_prop_empty_buckets = 1.0;
1350 if (r_prop_overloaded_buckets) {
1351 *r_prop_overloaded_buckets = 0.0;
1353 if (r_biggest_bucket) {
1354 *r_biggest_bucket = 0;
1364 if (r_biggest_bucket) {
1365 *r_biggest_bucket = 0;
1373 for (i = 0; i < gh->
nbuckets; i++) {
1390 for (i = 0; i < gh->
nbuckets; i++) {
1396 if (r_biggest_bucket) {
1397 *r_biggest_bucket =
max_ii(*r_biggest_bucket, (
int)
count);
1399 if (r_prop_overloaded_buckets && (
count > overloaded_buckets_threshold)) {
1402 if (r_prop_empty_buckets && !
count) {
1407 if (r_prop_overloaded_buckets) {
1408 *r_prop_overloaded_buckets = (
double)sum_overloaded / (
double)gh->
nbuckets;
1410 if (r_prop_empty_buckets) {
1411 *r_prop_empty_buckets = (
double)sum_empty / (
double)gh->
nbuckets;
1420 double *r_prop_empty_buckets,
1421 double *r_prop_overloaded_buckets,
1422 int *r_biggest_bucket)
1427 r_prop_empty_buckets,
1428 r_prop_overloaded_buckets,
static Entry * ghash_pop(GHash *gh, GHashIterState *state)
bool BLI_ghash_haskey(GHash *gh, const void *key)
void * BLI_gset_pop_key(GSet *gs, const void *key)
bool BLI_ghash_pop(GHash *gh, GHashIterState *state, void **r_key, void **r_val)
double BLI_ghash_calc_quality_ex(GHash *gh, double *r_load, double *r_variance, double *r_prop_empty_buckets, double *r_prop_overloaded_buckets, int *r_biggest_bucket)
void * BLI_gset_replace_key(GSet *gs, void *key)
static void ghash_buckets_resize(GHash *gh, const uint nbuckets)
bool BLI_gset_ensure_p_ex(GSet *gs, const void *key, void ***r_key)
double BLI_ghash_calc_quality(GHash *gh)
bool BLI_gset_haskey(GSet *gs, const void *key)
bool BLI_ghash_reinsert(GHash *gh, void *key, void *val, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
void BLI_ghashIterator_step(GHashIterator *ghi)
bool BLI_ghash_ensure_p_ex(GHash *gh, const void *key, void ***r_key, void ***r_val)
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
BLI_INLINE void ghash_entry_copy(GHash *gh_dst, Entry *dst, GHash *gh_src, Entry *src, GHashKeyCopyFP keycopyfp, GHashValCopyFP valcopyfp)
uint BLI_gset_len(GSet *gs)
BLI_INLINE bool ghash_insert_safe_keyonly(GHash *gh, void *key, const bool override, GHashKeyFreeFP keyfreefp)
BLI_INLINE Entry * ghash_lookup_entry_ex(GHash *gh, const void *key, const uint bucket_index)
BLI_INLINE uint ghash_bucket_index(GHash *gh, const uint hash)
void BLI_ghashIterator_free(GHashIterator *ghi)
uint BLI_ghash_len(GHash *gh)
GSet * BLI_gset_new_ex(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info, const uint nentries_reserve)
static void ghash_buckets_contract(GHash *gh, const uint nentries, const bool user_defined, const bool force_shrink)
void BLI_ghash_clear_ex(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp, const uint nentries_reserve)
#define GHASH_ENTRY_SIZE(_is_gset)
void * BLI_ghash_popkey(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp)
struct GHashEntry GHashEntry
BLI_INLINE void ghash_insert(GHash *gh, void *key, void *val)
BLI_INLINE void ghash_buckets_reset(GHash *gh, const uint nentries)
double BLI_gset_calc_quality(GSet *gs)
GHash * BLI_ghash_copy(GHash *gh, GHashKeyCopyFP keycopyfp, GHashValCopyFP valcopyfp)
void BLI_ghash_reserve(GHash *gh, const uint nentries_reserve)
void BLI_gset_clear(GSet *gs, GSetKeyFreeFP keyfreefp)
void BLI_gset_flag_clear(GSet *gs, uint flag)
BLI_INLINE void ghash_insert_ex_keyonly(GHash *gh, void *key, const uint bucket_index)
void BLI_gset_clear_ex(GSet *gs, GSetKeyFreeFP keyfreefp, const uint nentries_reserve)
double BLI_gset_calc_quality_ex(GSet *gs, double *r_load, double *r_variance, double *r_prop_empty_buckets, double *r_prop_overloaded_buckets, int *r_biggest_bucket)
static GHash * ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info, const uint nentries_reserve, const uint flag)
BLI_STATIC_ASSERT(ARRAY_SIZE(hashsizes)==GHASH_MAX_SIZE, "Invalid 'hashsizes' size")
int BLI_gset_buckets_len(GSet *gs)
void BLI_gset_flag_set(GSet *gs, uint flag)
BLI_INLINE bool ghash_insert_safe(GHash *gh, void *key, void *val, const bool override, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
void BLI_ghash_flag_clear(GHash *gh, uint flag)
static Entry * ghash_remove_ex(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp, const uint bucket_index)
void BLI_gset_insert(GSet *gs, void *key)
BLI_INLINE uint ghash_keyhash(GHash *gh, const void *key)
#define GHASH_LIMIT_SHRINK(_nbkt)
int BLI_ghash_buckets_len(GHash *gh)
bool BLI_gset_reinsert(GSet *gs, void *key, GSetKeyFreeFP keyfreefp)
BLI_INLINE Entry * ghash_lookup_entry(GHash *gh, const void *key)
void ** BLI_ghash_lookup_p(GHash *gh, const void *key)
GHashIterator * BLI_ghashIterator_new(GHash *gh)
void * BLI_gset_lookup(GSet *gs, const void *key)
void * BLI_ghash_replace_key(GHash *gh, void *key)
BLI_INLINE uint ghash_find_next_bucket_index(GHash *gh, uint curr_bucket)
BLI_INLINE void ghash_insert_ex(GHash *gh, void *key, void *val, const uint bucket_index)
#define GHASH_LIMIT_GROW(_nbkt)
GSet * BLI_gset_copy(GSet *gs, GHashKeyCopyFP keycopyfp)
void BLI_ghash_flag_set(GHash *gh, uint flag)
void * BLI_ghash_lookup_default(GHash *gh, const void *key, void *val_default)
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
void * BLI_ghash_lookup(GHash *gh, const void *key)
const uint BLI_ghash_hash_sizes[]
GSet * BLI_gset_new(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info)
BLI_INLINE void ghash_insert_ex_keyonly_entry(GHash *gh, void *key, const uint bucket_index, Entry *e)
void BLI_ghash_insert(GHash *gh, void *key, void *val)
BLI_INLINE Entry * ghash_lookup_entry_prev_ex(GHash *gh, const void *key, Entry **r_e_prev, const uint bucket_index)
static GHash * ghash_copy(GHash *gh, GHashKeyCopyFP keycopyfp, GHashValCopyFP valcopyfp)
BLI_INLINE uint ghash_entryhash(GHash *gh, const Entry *e)
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val)
static void ghash_free_cb(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh)
GHash * BLI_ghash_new_ex(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info, const uint nentries_reserve)
bool BLI_gset_add(GSet *gs, void *key)
bool BLI_gset_pop(GSet *gs, GSetIterState *state, void **r_key)
GHash * BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info)
bool BLI_gset_remove(GSet *gs, const void *key, GSetKeyFreeFP keyfreefp)
static void ghash_buckets_expand(GHash *gh, const uint nentries, const bool user_defined)
@ GHASH_FLAG_ALLOW_SHRINK
bool(* GHashCmpFP)(const void *a, const void *b)
void *(* GHashKeyCopyFP)(const void *key)
GHashKeyFreeFP GSetKeyFreeFP
void *(* GHashValCopyFP)(const void *val)
unsigned int(* GHashHashFP)(const void *key)
void(* GHashKeyFreeFP)(void *key)
void(* GHashValFreeFP)(void *val)
MINLINE int max_ii(int a, int b)
void void BLI_mempool_clear_ex(BLI_mempool *pool, const int totelem_reserve) ATTR_NONNULL(1)
void BLI_mempool_free(BLI_mempool *pool, void *addr) ATTR_NONNULL(1
BLI_mempool * BLI_mempool_create(unsigned int esize, unsigned int totelem, unsigned int pchunk, unsigned int flag) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_mempool_alloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_mempool_destroy(BLI_mempool *pool) ATTR_NONNULL(1)
int BLI_mempool_len(BLI_mempool *pool) ATTR_NONNULL(1)
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
typedef double(DMatrix)[4][4]
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
static T sum(const btAlignedObjectArray< T > &items)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
unsigned __int64 uint64_t
struct BLI_mempool * entrypool