58 void *
operator new(
size_t size, cc_memalloc * memhandler) {
60 cc_memalloc_allocate(memhandler);
61 entry->memhandler = memhandler;
64 void operator delete(
void * ptr) {
66 cc_memalloc_deallocate(entry->memhandler, ptr);
68 void operator delete(
void * ptr, cc_memalloc * memhandler) {
70 cc_memalloc_deallocate(entry->memhandler, ptr);
76 cc_memalloc * memhandler;
84 typedef uintptr_t SbHashFunc(
const Key & key);
85 typedef void SbHashApplyFunc(
const Key & key,
const Type & obj,
void * closure);
88 SbHash(
unsigned int sizearg = 256,
float loadfactorarg = 0.0f)
90 this->commonConstructor(sizearg, loadfactorarg);
95 this->commonConstructor(from.size, from.loadfactor);
96 this->operator=(from);
102 from.apply(SbHash::copy_data,
this);
109 cc_memalloc_destruct(this->memhandler);
110 delete [] this->buckets;
116 for ( i = 0; i < this->size; i++ ) {
117 while ( this->buckets[i] ) {
119 this->buckets[i] = entry->next;
127 SbBool put(
const Key & key,
const Type & obj)
129 unsigned int i = this->getIndex(key);
132 if ( entry->key == key ) {
146 entry->next = this->buckets[i];
147 this->buckets[i] = entry;
149 if ( this->elements++ >= this->threshold ) { this->resize(this->size * 2); }
153 SbBool get(
const Key & key, Type & obj)
const
156 unsigned int i = this->getIndex(key);
157 entry = this->buckets[i];
159 if ( entry->key == key ) {
168 SbBool remove(
const Key & key)
170 unsigned int i = this->getIndex(key);
174 if ( entry->key == key ) {
177 this->buckets[i] = next;
191 void apply(SbHashApplyFunc * func,
void * closure)
const
195 for ( i = 0; i < this->size; i++ ) {
196 elem = this->buckets[i];
198 func(elem->key, elem->obj, closure);
206 this->apply(SbHash::add_to_list, &l);
209 unsigned int getNumElements(
void)
const {
return this->elements; }
211 void setHashFunc(SbHashFunc * func) { this->hashfunc = func; }
214 static uintptr_t default_hash_func(
const Key & key) {
215 return (uintptr_t) key;
218 unsigned int getIndex(
const Key & key)
const {
219 unsigned int idx = this->hashfunc(key);
221 return idx & (this->size - 1);
224 void resize(
unsigned int newsize) {
226 if (this->size >= newsize)
return;
229 unsigned int oldsize = this->size;
232 this->size = newsize;
234 this->threshold = (
unsigned int) (newsize * this->loadfactor);
240 for ( i = 0; i < oldsize; i++ ) {
243 this->put(entry->key, entry->obj);
249 delete [] oldbuckets;
253 void commonConstructor(
unsigned int sizearg,
float loadfactorarg)
255 if ( loadfactorarg <= 0.0f ) { loadfactorarg = 0.75f; }
257 while ( s < sizearg ) { s <<= 1; }
261 this->threshold = (
unsigned int) (s * loadfactorarg);
262 this->loadfactor = loadfactorarg;
265 this->hashfunc = default_hash_func;
268 void getStats(
int & buckets_used,
int & buckets,
int & elements,
float & chain_length_avg,
int & chain_length_max)
271 buckets_used = 0, chain_length_max = 0;
272 for ( i = 0; i < this->size; i++ ) {
273 if ( this->buckets[i] ) {
274 unsigned int chain_l = 0;
281 if ( chain_l > chain_length_max ) { chain_length_max = chain_l; }
284 buckets = this->size;
285 elements = this->elements;
286 chain_length_avg = (float) this->elements / buckets_used;
289 static void copy_data(
const Key & key,
const Type & obj,
void * closure)
292 thisp->put(key, obj);
295 static void add_to_list(
const Key & key,
const Type & obj,
void * closure)
303 unsigned int elements;
304 unsigned int threshold;
307 SbHashFunc * hashfunc;
308 cc_memalloc * memhandler;