24#define GHASH_INTERNAL_API
33#define GHASH_USE_MODULO_BUCKETS
39 5, 11, 17, 37, 67, 131, 257, 521, 1031,
40 2053, 4099, 8209, 16411, 32771, 65537, 131101, 262147, 524309,
41 1048583, 2097169, 4194319, 8388617, 16777259, 33554467, 67108879, 134217757, 268435459,
44#ifdef GHASH_USE_MODULO_BUCKETS
45# define GHASH_MAX_SIZE 27
48# define GHASH_BUCKET_BIT_MIN 2
49# define GHASH_BUCKET_BIT_MAX 28
60#define GHASH_LIMIT_GROW(_nbkt) (((_nbkt) * 3) / 4)
61#define GHASH_LIMIT_SHRINK(_nbkt) (((_nbkt) * 3) / 16)
78#define GHASH_ENTRY_SIZE(_is_gset) ((_is_gset) ? sizeof(GSetEntry) : sizeof(GHashEntry))
88#ifdef GHASH_USE_MODULO_BUCKETS
91 uint bucket_mask, bucket_bit, bucket_bit_min;
111 dst->
key = (keycopyfp) ? keycopyfp(src->
key) : src->
key;
113 if ((gh_dst->
flag & GHASH_FLAG_IS_GSET) == 0) {
114 if ((gh_src->
flag & GHASH_FLAG_IS_GSET) == 0) {
145#ifdef GHASH_USE_MODULO_BUCKETS
148 return hash & gh->bucket_mask;
160 if (gh->
buckets[curr_bucket]) {
163 for (; curr_bucket < gh->
nbuckets; curr_bucket++) {
164 if (gh->
buckets[curr_bucket]) {
168 for (curr_bucket = 0; curr_bucket < gh->
nbuckets; curr_bucket++) {
169 if (gh->
buckets[curr_bucket]) {
191#ifdef GHASH_USE_MODULO_BUCKETS
193 gh->bucket_mask = nbuckets - 1;
199 if (nbuckets > nbuckets_old) {
200 for (i = 0; i < nbuckets_old; i++) {
201 for (
Entry *
e = buckets_old[i], *e_next;
e;
e = e_next) {
205 e->next = buckets_new[bucket_index];
206 buckets_new[bucket_index] =
e;
211 for (i = 0; i < nbuckets_old; i++) {
212#ifdef GHASH_USE_MODULO_BUCKETS
213 for (
Entry *
e = buckets_old[i], *e_next;
e;
e = e_next) {
217 e->next = buckets_new[bucket_index];
218 buckets_new[bucket_index] =
e;
227 for (
e = buckets_old[i];
e &&
e->next;
e =
e->next) {
231 e->next = buckets_new[bucket_index];
232 buckets_new[bucket_index] = buckets_old[i];
259#ifdef GHASH_USE_MODULO_BUCKETS
265 while ((nentries > gh->
limit_grow) && (gh->bucket_bit < GHASH_BUCKET_BIT_MAX)) {
266 new_nbuckets = 1u << ++gh->bucket_bit;
272#ifdef GHASH_USE_MODULO_BUCKETS
275 gh->bucket_bit_min = gh->bucket_bit;
290 const bool user_defined,
291 const bool force_shrink)
305#ifdef GHASH_USE_MODULO_BUCKETS
306 while ((nentries < gh->limit_shrink) && (gh->
cursize > gh->
size_min)) {
311 while ((nentries < gh->limit_shrink) && (gh->bucket_bit > gh->bucket_bit_min)) {
312 new_nbuckets = 1u << --gh->bucket_bit;
318#ifdef GHASH_USE_MODULO_BUCKETS
321 gh->bucket_bit_min = gh->bucket_bit;
341#ifdef GHASH_USE_MODULO_BUCKETS
346 gh->bucket_bit = GHASH_BUCKET_BIT_MIN;
347 gh->bucket_bit_min = GHASH_BUCKET_BIT_MIN;
348 gh->
nbuckets = 1u << gh->bucket_bit;
370 for (
e = gh->
buckets[bucket_index];
e;
e =
e->next) {
388 const uint bucket_index)
416 const uint nentries_reserve,
459 const uint bucket_index,
464 e->next = gh->
buckets[bucket_index];
481 e->next = gh->
buckets[bucket_index];
557 const uint bucket_index)
573 e_prev->
next =
e->next;
576 gh->
buckets[bucket_index] =
e->next;
605 state->curr_bucket = curr_bucket;
619 for (i = 0; i < gh->
nbuckets; i++) {
650 for (i = 0; i < gh->
nbuckets; i++) {
681 const uint nentries_reserve)
683 return ghash_new(hashfp, cmpfp, info, nentries_reserve, 0);
724 void *key_prev =
e->
e.key;
742 return e ?
e->val : val_default;
749 return e ? &
e->val :
NULL;
757 const bool haskey = (
e !=
NULL);
773 const bool haskey = (
e !=
NULL);
838 *r_key = *r_val =
NULL;
845 const uint nentries_reserve)
847 if (keyfreefp || valfreefp) {
863 if (keyfreefp || valfreefp) {
939 const uint nentries_reserve)
941 return (
GSet *)
ghash_new(hashfp, cmpfp, info, nentries_reserve, GHASH_FLAG_IS_GSET);
956 return ((
GHash *)gs)->nentries;
976 const bool haskey = (
e !=
NULL);
1046 ((
GHash *)gs)->flag &= ~flag;
1061 return e ?
e->key :
NULL;
1070 void *key_ret =
e->key;
1095 double *r_prop_empty_buckets,
1096 double *r_prop_overloaded_buckets,
1097 int *r_biggest_bucket)
1109 if (r_prop_empty_buckets) {
1110 *r_prop_empty_buckets = 1.0;
1112 if (r_prop_overloaded_buckets) {
1113 *r_prop_overloaded_buckets = 0.0;
1115 if (r_biggest_bucket) {
1116 *r_biggest_bucket = 0;
1126 if (r_biggest_bucket) {
1127 *r_biggest_bucket = 0;
1135 for (i = 0; i < gh->
nbuckets; i++) {
1152 for (i = 0; i < gh->
nbuckets; i++) {
1158 if (r_biggest_bucket) {
1159 *r_biggest_bucket =
max_ii(*r_biggest_bucket, (
int)
count);
1161 if (r_prop_overloaded_buckets && (
count > overloaded_buckets_threshold)) {
1164 if (r_prop_empty_buckets && !
count) {
1169 if (r_prop_overloaded_buckets) {
1170 *r_prop_overloaded_buckets = (
double)sum_overloaded / (
double)gh->
nbuckets;
1172 if (r_prop_empty_buckets) {
1173 *r_prop_empty_buckets = (
double)sum_empty / (
double)gh->
nbuckets;
1182 double *r_prop_empty_buckets,
1183 double *r_prop_overloaded_buckets,
1184 int *r_biggest_bucket)
1189 r_prop_empty_buckets,
1190 r_prop_overloaded_buckets,
#define BLI_assert_unreachable()
#define BLI_STATIC_ASSERT(a, msg)
BLI_INLINE void ghash_entry_copy(GHash *gh_dst, Entry *dst, const GHash *gh_src, const Entry *src, GHashKeyCopyFP keycopyfp, GHashValCopyFP valcopyfp)
BLI_INLINE Entry * ghash_lookup_entry_prev_ex(GHash *gh, const void *key, Entry **r_e_prev, const uint bucket_index)
GHashIterator * BLI_ghashIterator_new(GHash *gh)
BLI_INLINE Entry * ghash_lookup_entry(const GHash *gh, const void *key)
bool BLI_ghash_pop(GHash *gh, GHashIterState *state, void **r_key, void **r_val)
static Entry * ghash_pop(GHash *gh, GHashIterState *state)
static void ghash_buckets_resize(GHash *gh, const uint nbuckets)
bool BLI_gset_ensure_p_ex(GSet *gs, const void *key, void ***r_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 bool ghash_insert_safe_keyonly(GHash *gh, void *key, const bool override, GHashKeyFreeFP keyfreefp)
void BLI_ghashIterator_free(GHashIterator *ghi)
uint BLI_gset_len(const GSet *gs)
double BLI_gset_calc_quality(const GSet *gs)
static void ghash_buckets_contract(GHash *gh, const uint nentries, const bool user_defined, const bool force_shrink)
void * BLI_gset_replace_key(GSet *gs, void *key)
void BLI_ghash_clear_ex(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp, const uint nentries_reserve)
#define GHASH_ENTRY_SIZE(_is_gset)
int BLI_ghash_buckets_len(const GHash *gh)
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)
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_ghash_popkey(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp)
void BLI_gset_clear_ex(GSet *gs, GSetKeyFreeFP keyfreefp, const uint nentries_reserve)
double BLI_ghash_calc_quality_ex(const GHash *gh, double *r_load, double *r_variance, double *r_prop_empty_buckets, double *r_prop_overloaded_buckets, int *r_biggest_bucket)
BLI_INLINE Entry * ghash_lookup_entry_ex(const GHash *gh, const void *key, const uint bucket_index)
BLI_INLINE uint ghash_find_next_bucket_index(const GHash *gh, uint curr_bucket)
void * BLI_gset_pop_key(GSet *gs, const void *key)
GHash * BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info)
void BLI_gset_flag_set(GSet *gs, uint flag)
GHash * BLI_ghash_copy(const GHash *gh, GHashKeyCopyFP keycopyfp, GHashValCopyFP valcopyfp)
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)
bool BLI_gset_haskey(const GSet *gs, const void *key)
void BLI_gset_insert(GSet *gs, void *key)
BLI_INLINE uint ghash_keyhash(const GHash *gh, const void *key)
static GHash * ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info, const uint nentries_reserve, const uint flag)
double BLI_ghash_calc_quality(const GHash *gh)
#define GHASH_LIMIT_SHRINK(_nbkt)
bool BLI_ghash_haskey(const GHash *gh, const void *key)
static const uint hashsizes[]
bool BLI_gset_reinsert(GSet *gs, void *key, GSetKeyFreeFP keyfreefp)
GSet * BLI_gset_new_ex(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info, const uint nentries_reserve)
uint BLI_ghash_len(const GHash *gh)
BLI_INLINE uint ghash_bucket_index(const GHash *gh, const uint hash)
int BLI_gset_buckets_len(const GSet *gs)
void * BLI_ghash_lookup(const GHash *gh, const void *key)
void * BLI_gset_lookup(const GSet *gs, const void *key)
GSet * BLI_gset_new(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info)
BLI_INLINE void ghash_insert_ex(GHash *gh, void *key, void *val, const uint bucket_index)
void ** BLI_ghash_lookup_p(GHash *gh, const void *key)
#define GHASH_LIMIT_GROW(_nbkt)
void BLI_ghash_flag_set(GHash *gh, uint flag)
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
double BLI_gset_calc_quality_ex(const GSet *gs, double *r_load, double *r_variance, double *r_prop_empty_buckets, double *r_prop_overloaded_buckets, int *r_biggest_bucket)
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 uint ghash_entryhash(const 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)
GSet * BLI_gset_copy(const GSet *gs, GHashKeyCopyFP keycopyfp)
static GHash * ghash_copy(const GHash *gh, GHashKeyCopyFP keycopyfp, GHashValCopyFP valcopyfp)
void * BLI_ghash_lookup_default(const GHash *gh, const void *key, void *val_default)
bool BLI_gset_add(GSet *gs, void *key)
void * BLI_ghash_replace_key(GHash *gh, void *key)
bool BLI_gset_pop(GSet *gs, GSetIterState *state, void **r_key)
GHash * BLI_ghash_new_ex(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info, const uint nentries_reserve)
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)
bool(* GHashCmpFP)(const void *a, const void *b)
void *(* GHashValCopyFP)(const void *val)
void *(* GHashKeyCopyFP)(const void *key)
GHashKeyFreeFP GSetKeyFreeFP
unsigned int(* GHashHashFP)(const void *key)
void(* GHashKeyFreeFP)(void *key)
void(* GHashValFreeFP)(void *val)
@ GHASH_FLAG_ALLOW_SHRINK
MINLINE int max_ii(int a, int b)
void * BLI_mempool_alloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1)
void void BLI_mempool_clear_ex(BLI_mempool *pool, int elem_num_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 elem_num, unsigned int pchunk, unsigned int flag) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
int BLI_mempool_len(const BLI_mempool *pool) ATTR_NONNULL(1)
void BLI_mempool_destroy(BLI_mempool *pool) ATTR_NONNULL(1)
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_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
unsigned __int64 uint64_t